Coverage Report - pt.digitalis.dif.codegen.util.ClassEnhancerImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
ClassEnhancerImpl
0%
0/366
0%
0/204
9,667
 
 1  0
 /**
 2  
  * - Digitalis Internal Framework v2.0 - (C) 2007, Digitalis Informatica. Distribuicao e Gestao de Informatica, Lda.
 3  
  * Estrada de Paco de Arcos num.9 - Piso -1 2780-666 Paco de Arcos Telefone: (351) 21 4408990 Fax: (351) 21 4408999
 4  
  * http://www.digitalis.pt
 5  
  */
 6  
 package pt.digitalis.dif.codegen.util;
 7  
 
 8  
 import java.util.ArrayList;
 9  
 import java.util.Arrays;
 10  
 import java.util.Collection;
 11  
 import java.util.List;
 12  
 import java.util.Map;
 13  
 
 14  
 import pt.digitalis.dif.codegen.CGAncillaries;
 15  
 import pt.digitalis.dif.controller.ExceptionHandlers;
 16  
 import pt.digitalis.dif.controller.security.managers.IAuthorizationManager;
 17  
 import pt.digitalis.dif.controller.security.managers.IIdentityManager;
 18  
 import pt.digitalis.dif.controller.security.objects.IDIFGroup;
 19  
 import pt.digitalis.dif.controller.security.objects.IDIFUser;
 20  
 import pt.digitalis.dif.dem.DEMAnnotationLogic;
 21  
 import pt.digitalis.dif.dem.Entity;
 22  
 import pt.digitalis.dif.dem.annotations.AnnotationMemberTags;
 23  
 import pt.digitalis.dif.dem.annotations.AnnotationTags;
 24  
 import pt.digitalis.dif.dem.annotations.Registrable;
 25  
 import pt.digitalis.dif.dem.annotations.parameter.BindParameterIDs;
 26  
 import pt.digitalis.dif.dem.annotations.parameter.FormConfigurable;
 27  
 import pt.digitalis.dif.dem.annotations.parameter.Parameter;
 28  
 import pt.digitalis.dif.dem.annotations.parameter.Persist;
 29  
 import pt.digitalis.dif.dem.annotations.parameter.Rule;
 30  
 import pt.digitalis.dif.dem.annotations.parameter.Rules;
 31  
 import pt.digitalis.dif.dem.annotations.security.AccessControl;
 32  
 import pt.digitalis.dif.dem.annotations.security.Group;
 33  
 import pt.digitalis.dif.dem.annotations.security.Groups;
 34  
 import pt.digitalis.dif.dem.annotations.security.User;
 35  
 import pt.digitalis.dif.dem.annotations.security.Users;
 36  
 import pt.digitalis.dif.dem.annotations.stage.ExceptionHandler;
 37  
 import pt.digitalis.dif.dem.managers.IParameterManager;
 38  
 import pt.digitalis.dif.dem.managers.IRegistrationManager;
 39  
 import pt.digitalis.dif.dem.managers.impl.UsageIssuesManagerImpl;
 40  
 import pt.digitalis.dif.dem.objects.issues.IssueScope;
 41  
 import pt.digitalis.dif.dem.objects.issues.IssueType;
 42  
 import pt.digitalis.dif.dem.objects.issues.UsageIssue;
 43  
 import pt.digitalis.dif.dem.objects.parameters.IParameter;
 44  
 import pt.digitalis.dif.dem.objects.parameters.ParameterList;
 45  
 import pt.digitalis.dif.dem.objects.parameters.ParameterScope;
 46  
 import pt.digitalis.dif.dem.objects.parameters.constraints.impl.ParameterConstraintRegexImpl;
 47  
 import pt.digitalis.dif.dem.objects.parameters.rules.IParameterRule;
 48  
 import pt.digitalis.dif.dem.objects.parameters.rules.ParameterRuleAction;
 49  
 import pt.digitalis.dif.exception.InternalFrameworkException;
 50  
 import pt.digitalis.dif.exception.codegen.DIFCodeGenerationException;
 51  
 import pt.digitalis.dif.exception.objects.ParameterException;
 52  
 import pt.digitalis.dif.exception.security.AuthorizationManagerException;
 53  
 import pt.digitalis.dif.exception.security.IdentityManagerException;
 54  
 import pt.digitalis.dif.ioc.DIFIoCRegistry;
 55  
 import pt.digitalis.dif.utils.logging.DIFLogger;
 56  
 import pt.digitalis.utils.bytecode.exceptions.CodeGenerationException;
 57  
 import pt.digitalis.utils.bytecode.holders.AnnotationHolder;
 58  
 import pt.digitalis.utils.bytecode.holders.AnnotationMemberValueHolder;
 59  
 import pt.digitalis.utils.bytecode.holders.AttributeHolder;
 60  
 import pt.digitalis.utils.bytecode.holders.ClassHolder;
 61  
 import pt.digitalis.utils.bytecode.holders.MethodHolder;
 62  
 import pt.digitalis.utils.inspection.exception.ResourceNotFoundException;
 63  
 
 64  
 import com.google.inject.Inject;
 65  
 
 66  
 /**
 67  
  * An implementation of the IClassEnhancer that uses Bytecode Utils to enhance the classes.
 68  
  * 
 69  
  * @author Rodrigo Gon�alves <a href="mailto:rgoncalves@digitalis.pt">rgoncalves@digitalis.pt</a>
 70  
  * @author Pedro Viegas <a href="mailto:pviegas@digitalis.pt">pviegas@digitalis.pt</a>
 71  
  * @created Jul 5, 2007
 72  
  */
 73  
 /**
 74  
  * @author Pedro Viegas <a href="mailto:pviegas@digitalis.pt">pviegas@digitalis.pt</a><br/>
 75  
  * @created 17 de Mar de 2011
 76  
  */
 77  
 /**
 78  
  * @author Pedro Viegas <a href="mailto:pviegas@digitalis.pt">pviegas@digitalis.pt</a><br/>
 79  
  * @created 17 de Mar de 2011
 80  
  */
 81  
 public class ClassEnhancerImpl implements IClassEnhancer {
 82  
 
 83  
     /** Default password for new users */
 84  
     private static final String DEFAULT_PASSWORD = "@bcd1234";
 85  
 
 86  
     /** Map of all annotations and their corresponding Logic objects */
 87  0
     private Map<String, DEMAnnotationLogic> annotationLogicMap = null;
 88  
 
 89  
     /** The authorization manager */
 90  
     private final IAuthorizationManager authorizationManager;
 91  
 
 92  
     /** The identity manager */
 93  
     private final IIdentityManager identityManager;
 94  
 
 95  
     /** The parameter manager */
 96  
     private final IParameterManager parameterManager;
 97  
 
 98  
     /** The registration manager */
 99  
     private final IRegistrationManager registrationManager;
 100  
 
 101  
     /**
 102  
      * Constructor.
 103  
      * 
 104  
      * @param registrationManager
 105  
      *            the registration manager instance
 106  
      * @param parameterManager
 107  
      *            the parameter manager instance
 108  
      * @param identityManager
 109  
      *            the identity manager instance
 110  
      * @param authorizationManager
 111  
      *            the authorization manager instance
 112  
      * @throws CodeGenerationException
 113  
      *             if the needed resources for class enhancement could not be properly initialized
 114  
      */
 115  
     @Inject
 116  0
     public ClassEnhancerImpl(IRegistrationManager registrationManager, IParameterManager parameterManager,
 117  
             IIdentityManager identityManager, IAuthorizationManager authorizationManager)
 118  
             throws CodeGenerationException
 119  
     {
 120  
 
 121  0
         this.registrationManager = registrationManager;
 122  0
         this.parameterManager = parameterManager;
 123  0
         this.identityManager = identityManager;
 124  0
         this.authorizationManager = authorizationManager;
 125  
 
 126  
         try
 127  
         {
 128  0
             annotationLogicMap = DEMLoaderHelper.getAnnotationLogicMap();
 129  
 
 130  
         }
 131  0
         catch (Exception exception)
 132  
         {
 133  0
             throw new CodeGenerationException("Could not properly initialize resources ", exception);
 134  
         }
 135  0
     }
 136  
 
 137  
     /**
 138  
      * Enhances the methods of a given class.
 139  
      * 
 140  
      * @param classEnhancementContext
 141  
      *            the class enhancement context
 142  
      * @throws ResourceNotFoundException
 143  
      *             if class can not be loaded
 144  
      * @throws CodeGenerationException
 145  
      *             if class can not be enhanced
 146  
      * @throws DIFCodeGenerationException
 147  
      */
 148  
     private void enhaceMethods(ClassEnhancementContext classEnhancementContext) throws ResourceNotFoundException,
 149  
             CodeGenerationException, DIFCodeGenerationException
 150  
     {
 151  
 
 152  0
         ClassHolder clazz = classEnhancementContext.getOriginalClassObject();
 153  
 
 154  0
         for (MethodHolder method: clazz.getAllMethods().values())
 155  
         {
 156  
 
 157  0
             Collection<AnnotationHolder> annotations = method.getAnnotations().values();
 158  
 
 159  
             // If there are annotations to process (method can have no
 160  
             // annotations!)
 161  0
             if (annotations != null && annotations.size() > 0)
 162  
             {
 163  
 
 164  0
                 for (AnnotationHolder annotation: annotations)
 165  
                 {
 166  
 
 167  
                     // ...get it's associated object...
 168  0
                     DEMAnnotationLogic annotationLogic = annotationLogicMap.get(annotation.getName());
 169  
                     // ...if the object exists...
 170  0
                     if (annotationLogic != null)
 171  
                     {
 172  
                         // if annotation usage is correct process it!
 173  0
                         annotationLogic.validateUsage(method);
 174  0
                         processAnnotation(classEnhancementContext, method, annotation, annotationLogic);
 175  
                     }
 176  
                     else
 177  0
                         DIFLogger.getLogger().debug(
 178  0
                                 "Annotation @" + annotation.getName()
 179  0
                                         + " has no AnnotationLogicClass defined. Skipping...");
 180  
                 }
 181  
             }
 182  
         }
 183  0
     }
 184  
 
 185  
     /**
 186  
      * Reads and iterates over the class annotations, processing them according to their target scope.
 187  
      * 
 188  
      * @see pt.digitalis.dif.codegen.util.IClassEnhancer#enhance(ClassHolder)
 189  
      */
 190  
     public ClassHolder enhance(ClassHolder clazz) throws ResourceNotFoundException, CodeGenerationException,
 191  
             DIFCodeGenerationException
 192  
     {
 193  
 
 194  0
         ClassEnhancementContext classEnhancementContext = new ClassEnhancementContext(clazz);
 195  
 
 196  0
         enhanceClass(classEnhancementContext);
 197  0
         enhanceAttributes(classEnhancementContext);
 198  0
         enhaceMethods(classEnhancementContext);
 199  
 
 200  0
         postProcessActions(classEnhancementContext);
 201  
 
 202  
         // Commit changes
 203  0
         classEnhancementContext.commitEnhancements();
 204  
 
 205  0
         return classEnhancementContext.getEntityClass();
 206  
     }
 207  
 
 208  
     /**
 209  
      * Enhances the attributes of a given class.
 210  
      * 
 211  
      * @param classEnhancementContext
 212  
      *            the class enhancement context
 213  
      * @throws ResourceNotFoundException
 214  
      *             if class can not be loaded
 215  
      * @throws CodeGenerationException
 216  
      *             if class can not be enhanced
 217  
      * @throws DIFCodeGenerationException
 218  
      */
 219  
     private void enhanceAttributes(ClassEnhancementContext classEnhancementContext) throws ResourceNotFoundException,
 220  
             CodeGenerationException, DIFCodeGenerationException
 221  
     {
 222  
 
 223  0
         ClassHolder clazz = classEnhancementContext.getOriginalClassObject();
 224  
 
 225  
         // For each attribute...
 226  0
         for (AttributeHolder attribute: clazz.getAttributes().values())
 227  
         {
 228  
             // For each annotation...
 229  0
             for (AnnotationHolder annotation: attribute.getAnnotations().values())
 230  
             {
 231  
                 // ...get it's associated object...
 232  0
                 DEMAnnotationLogic annotationLogic = annotationLogicMap.get(annotation.getName());
 233  
                 // ...if the object exists...
 234  0
                 if (annotationLogic != null)
 235  
                 {
 236  
                     // if annotation usage is correct process it!
 237  0
                     annotationLogic.validateUsage(attribute);
 238  0
                     processAnnotation(classEnhancementContext, attribute, annotation, annotationLogic);
 239  
                 }
 240  
                 else
 241  0
                     DIFLogger.getLogger()
 242  0
                             .debug("Annotation @" + annotation.getName()
 243  0
                                     + " has no AnnotationLogicClass defined. Skipping...");
 244  
             }
 245  
         }
 246  0
     }
 247  
 
 248  
     /**
 249  
      * Enhances a given class. Analyzes class annotations and implements the needed interfaces and methods according.
 250  
      * 
 251  
      * @param classEnhancementContext
 252  
      *            the class enhancement context
 253  
      * @throws ResourceNotFoundException
 254  
      *             if class can not be loaded
 255  
      * @throws CodeGenerationException
 256  
      *             if class can not be enhanced
 257  
      * @throws DIFCodeGenerationException
 258  
      */
 259  
     private void enhanceClass(ClassEnhancementContext classEnhancementContext) throws ResourceNotFoundException,
 260  
             CodeGenerationException, DIFCodeGenerationException
 261  
     {
 262  
 
 263  0
         ClassHolder clazz = classEnhancementContext.getOriginalClassObject();
 264  
 
 265  0
         for (AnnotationHolder annotation: clazz.getAnnotations().values())
 266  
         {
 267  0
             DEMAnnotationLogic annotationLogic = annotationLogicMap.get(annotation.getName());
 268  
 
 269  
             // ...if the object exists...
 270  0
             if (annotationLogic != null)
 271  
             {
 272  
                 // if annotation usage is correct process it!
 273  0
                 annotationLogic.validateUsage(clazz);
 274  0
                 processAnnotation(classEnhancementContext, annotation, annotationLogic);
 275  
             }
 276  
             else
 277  0
                 DIFLogger.getLogger().debug(
 278  0
                         "Annotation @" + annotation.getName() + " has no AnnotationLogicClass defined. Skipping...");
 279  
         }
 280  0
     }
 281  
 
 282  
     /**
 283  
      * Infers a given {@link Rule} annotation to a {@link IParameterRule} object
 284  
      * 
 285  
      * @param parameterID
 286  
      *            the id of the associated stage parameter
 287  
      * @param ruleAnnotation
 288  
      *            the rule annotation
 289  
      * @return the converted {@link IParameterRule}
 290  
      * @throws ResourceNotFoundException
 291  
      */
 292  
     private IParameterRule<?> getRule(String parameterID, AnnotationHolder ruleAnnotation)
 293  
             throws ResourceNotFoundException
 294  
     {
 295  
 
 296  0
         IParameterRule<?> paramRule = null;
 297  
 
 298  0
         if (ruleAnnotation != null)
 299  
         {
 300  0
             String ruleID = null;
 301  0
             String ruleParameters = null;
 302  0
             ParameterRuleAction ruleAction = ParameterRuleAction.HIDE;
 303  
 
 304  0
             Map<String, AnnotationMemberValueHolder> ruleValues = ruleAnnotation.getMembers();
 305  
 
 306  
             AnnotationMemberValueHolder temp;
 307  
 
 308  
             // Override default from the declared parameters in @Persist
 309  0
             temp = ruleValues.get(AnnotationMemberTags.RULE_ID);
 310  
 
 311  0
             if (temp != null)
 312  
             {
 313  0
                 ruleID = temp.toString();
 314  
 
 315  0
                 temp = ruleValues.get(AnnotationMemberTags.RULE_PARAMETER_LIST);
 316  
 
 317  0
                 if (temp != null)
 318  
                 {
 319  0
                     ruleParameters = temp.toString();
 320  
 
 321  0
                     temp = ruleValues.get(AnnotationMemberTags.RULE_ACTION);
 322  
 
 323  0
                     if (temp != null && temp.enumValuetoString() != null)
 324  0
                         ruleAction = ParameterRuleAction.valueOf(temp.enumValuetoString());
 325  
 
 326  0
                     String value = ruleValues.get(AnnotationMemberTags.RULE_VALUE).toString();
 327  0
                     String first = ruleValues.get(AnnotationMemberTags.RULE_FIRST).toString();
 328  0
                     String last = ruleValues.get(AnnotationMemberTags.RULE_LAST).toString();
 329  
 
 330  0
                     if (AnnotationTags.NONE.equals(value))
 331  0
                         value = null;
 332  
 
 333  0
                     if (AnnotationTags.NONE.equals(first))
 334  0
                         first = null;
 335  
 
 336  0
                     if (AnnotationTags.NONE.equals(last))
 337  0
                         last = null;
 338  
 
 339  0
                     paramRule = DIFIoCRegistry.getRegistry().getImplementation(IParameterRule.class, ruleID);
 340  
 
 341  0
                     if (paramRule != null)
 342  0
                         paramRule.init(parameterID, ruleParameters, ruleAction, value, first, last);
 343  
                 }
 344  
             }
 345  
         }
 346  
 
 347  0
         return paramRule;
 348  
     }
 349  
 
 350  
     /**
 351  
      * Post processing actions. Will analize the current DEm entity, with their processed annotations and perform
 352  
      * context analisys and code generation
 353  
      * 
 354  
      * @param classEnhancementContext
 355  
      * @throws ResourceNotFoundException
 356  
      */
 357  
     private void postProcessActions(ClassEnhancementContext classEnhancementContext) throws ResourceNotFoundException
 358  
     {
 359  
 
 360  0
         String entityID = EntityUtils.getEntityID(classEnhancementContext.getOriginalClassObject());
 361  0
         Entity entityType = EntityUtils.getEntityType(classEnhancementContext.getOriginalClassObject());
 362  
 
 363  0
         if (entityType != Entity.VALIDATOR)
 364  
         {
 365  0
             ParameterList parameters = parameterManager.getParameters(entityType, entityID);
 366  
 
 367  
             // Parse all current entity parameters and each of their optional rules. for each set the dependent
 368  
             // parameter ReferencedInAnotherRule parameter
 369  0
             if (parameters != null)
 370  0
                 for (IParameter<?> parameter: parameters.getParameters().values())
 371  0
                     for (IParameterRule<?> rule: parameter.getRules())
 372  0
                         for (String dependentParameterId: rule.getParameters())
 373  
                         {
 374  
 
 375  0
                             IParameter<?> param = parameters.getParameter(dependentParameterId.trim());
 376  
 
 377  0
                             if (param == null)
 378  
                             {
 379  0
                                 UsageIssue issue = new UsageIssue();
 380  0
                                 issue.setIssueScope(IssueScope.LOADTIME);
 381  0
                                 issue.setIssueType(IssueType.ERROR);
 382  0
                                 issue.setIssueDescription("The parameter " + dependentParameterId.trim()
 383  0
                                         + " referenced in a @Rule of the parameter " + parameter.getId()
 384  0
                                         + " does not exist in the stage");
 385  0
                                 issue.setLocation(classEnhancementContext.getOriginalClassObject().getFQName());
 386  
 
 387  0
                                 UsageIssuesManagerImpl.getInstance().addIssue(issue);
 388  
                             }
 389  
                             else
 390  0
                                 param.setReferencedInARuleFromAnotherParameter(true);
 391  
                         }
 392  
         }
 393  0
     }
 394  
 
 395  
     /**
 396  
      * @see pt.digitalis.dif.codegen.util.IClassEnhancer#processAnnotation(pt.digitalis.dif.codegen.util.ClassEnhancementContext,
 397  
      *      pt.digitalis.utils.bytecode.holders.AnnotationHolder, pt.digitalis.dif.dem.DEMAnnotationLogic)
 398  
      */
 399  
     public void processAnnotation(ClassEnhancementContext classEnhancementContext, AnnotationHolder annotation,
 400  
             DEMAnnotationLogic annotationLogic) throws ResourceNotFoundException, CodeGenerationException,
 401  
             DIFCodeGenerationException
 402  
     {
 403  
 
 404  0
         String annotationName = annotation.getName();
 405  
 
 406  0
         ClassHolder clazz = classEnhancementContext.getOriginalClassObject();
 407  
 
 408  
         // *** Process behavior-triggering annotations ***
 409  
 
 410  0
         if (annotationName.equals(ExceptionHandler.class.getCanonicalName()))
 411  
         {
 412  0
             String[] exceptions = CGAncillaries.parse(
 413  0
                     annotation.getMembers().get(AnnotationMemberTags.ERROR_STAGE_EXCEPTIONS).toString(),
 414  0
                     CGAncillaries.COMMA);
 415  
 
 416  0
             for (int i = 0; i < exceptions.length; i++)
 417  0
                 ExceptionHandlers.addExceptionHandler(exceptions[i], EntityUtils.getEntityID(clazz));
 418  
 
 419  
         }
 420  0
         else if (annotationName.equals(Registrable.class.getCanonicalName()))
 421  
         {
 422  
 
 423  0
             Entity entityType = EntityUtils.getEntityType(clazz);
 424  0
             String entityID = EntityUtils.getEntityID(clazz);
 425  0
             String defaultName = annotation.getMembers().get("defaultRegisterName").toString();
 426  
 
 427  0
             if (entityType != null)
 428  
             {
 429  
                 // No default name means an unregistered but registrable registration.
 430  
                 // Inaccessible until a valid registration occurs.
 431  
 
 432  
                 // A default name will force a non-registrable so it can be accessed with the default name.
 433  0
                 if (defaultName.equals(AnnotationTags.NONE))
 434  0
                     defaultName = "";
 435  
 
 436  0
                 registrationManager.addToRegistry(entityType, entityID, defaultName, "".equals(defaultName));
 437  
             }
 438  
         }
 439  0
         else if (annotationName.equals(BindParameterIDs.class.getCanonicalName()))
 440  
         {
 441  
             // Parse String to array
 442  
             // String[] parametersIDs =
 443  
             // CGAncillaries.parse(annotation.getMembers().get("ids").toString(),
 444  
             // ",");
 445  
 
 446  
             // TODO: call the appropriate method on the ValidatorManager
 447  
             // Throw UnsupportedOpertationException to comply with Java
 448  
             // standards and warn user of unimplemented
 449  
             // feature.
 450  0
             throw new UnsupportedOperationException(annotationName + " not yet supported! Please remove it from class "
 451  0
                     + clazz.getFQName());
 452  
 
 453  
         }
 454  0
         else if (annotationName.equals(Users.class.getCanonicalName()))
 455  
         {
 456  0
             for (AnnotationHolder innerUser: annotation.getMembers().get(AnnotationMemberTags.VALUE)
 457  0
                     .toAnnotationList(clazz))
 458  0
                 processUserAnnotation(clazz, innerUser);
 459  
 
 460  
         }
 461  0
         else if (annotationName.equals(Groups.class.getCanonicalName()))
 462  
         {
 463  0
             for (AnnotationHolder innerGroup: annotation.getMembers().get(AnnotationMemberTags.VALUE)
 464  0
                     .toAnnotationList(clazz))
 465  
             {
 466  0
                 processGroupAnnotation(clazz, innerGroup);
 467  
             }
 468  
 
 469  
         }
 470  
 
 471  0
         else if (annotationName.equals(User.class.getCanonicalName()))
 472  
         {
 473  0
             processUserAnnotation(clazz, annotation);
 474  
 
 475  
         }
 476  0
         else if (annotationName.equals(Group.class.getCanonicalName()))
 477  
         {
 478  0
             processGroupAnnotation(clazz, annotation);
 479  
 
 480  
         }
 481  0
         else if (annotationName.equals(AccessControl.class.getCanonicalName()))
 482  
         {
 483  
 
 484  
             // Get the parent info
 485  0
             Entity entityType = EntityUtils.getEntityType(clazz);
 486  0
             String entityID = EntityUtils.getEntityID(clazz);
 487  
 
 488  0
             if (entityType.equals(Entity.APPLICATION) || entityType.equals(Entity.SERVICE)
 489  0
                     || entityType.equals(Entity.STAGE))
 490  
             {
 491  
                 // Get the parameters of the annotation
 492  0
                 String[] userIDs = CGAncillaries.parse(annotation.getMembers().get("users").toString(), ",");
 493  0
                 String[] groupIDs = CGAncillaries.parse(annotation.getMembers().get("groups").toString(), ",");
 494  0
                 boolean accessToNone = annotation.getMembers().get("none").toBoolean();
 495  
 
 496  0
                 if (userIDs.length == 0 || userIDs[0].equals(""))
 497  0
                     userIDs = new String[0];
 498  0
                 if (groupIDs.length == 0 || groupIDs[0].equals(""))
 499  0
                     groupIDs = new String[0];
 500  
 
 501  
                 try
 502  
                 {
 503  0
                     for (String userID: userIDs)
 504  
                     {
 505  
                         // Parse the user id and profile, using the notation:
 506  
                         // "userID:profileID, userID2:profileID2..."
 507  0
                         String[] userData = CGAncillaries.parse(userID, ":");
 508  
 
 509  0
                         if (!identityManager.userExists(userData[0]))
 510  
                         {
 511  
 
 512  0
                             if (userData.length < 2)
 513  
                             {
 514  0
                                 throw new DIFCodeGenerationException(
 515  0
                                         "The annotation AccessControl must declare a user with a valid profile. Configuration: "
 516  0
                                                 + annotation.getMembers().get("users").toString());
 517  
                             }
 518  
 
 519  0
                             if (!identityManager.groupExists(userData[1]))
 520  
                             {
 521  0
                                 IDIFGroup group = DIFIoCRegistry.getRegistry().getImplementation(IDIFGroup.class);
 522  0
                                 group.setID(userData[1]);
 523  0
                                 group.setName(userData[1]);
 524  
 
 525  0
                                 identityManager.addGroup(group);
 526  
                             }
 527  
 
 528  0
                             IDIFUser user = DIFIoCRegistry.getRegistry().getImplementation(IDIFUser.class);
 529  0
                             user.setID(userData[0]);
 530  0
                             user.setName(userData[0]);
 531  0
                             user.setNick(userData[0]);
 532  0
                             user.setPassword(userData[0]);
 533  0
                             user.setProfileID(userData[1]);
 534  
 
 535  0
                             identityManager.addUser(user);
 536  
                         }
 537  
 
 538  0
                         authorizationManager.grantDefaultAccessToUser(userData[0], entityType, entityID);
 539  
                     }
 540  
 
 541  0
                     for (String groupID: groupIDs)
 542  
                     {
 543  0
                         if (!identityManager.groupExists(groupID))
 544  
                         {
 545  0
                             IDIFGroup group = DIFIoCRegistry.getRegistry().getImplementation(IDIFGroup.class);
 546  0
                             group.setID(groupID);
 547  0
                             group.setName(groupID);
 548  
 
 549  0
                             identityManager.addGroup(group);
 550  
                         }
 551  
 
 552  0
                         authorizationManager.grantDefaultAccessToGroup(groupID, entityType, entityID);
 553  
                     }
 554  
                 }
 555  0
                 catch (IdentityManagerException identityManagerException)
 556  
                 {
 557  0
                     if (identityManager.isReadOnly())
 558  0
                         DIFLogger.getLogger().info("Identity Manager in Read Only mode.");
 559  
                     else
 560  0
                         DIFLogger.getLogger().warn(
 561  0
                                 "Could not access the identity manager!" + identityManagerException.getMessage());
 562  
                 }
 563  0
                 catch (AuthorizationManagerException authorizationManagerException)
 564  
                 {
 565  0
                     throw new ResourceNotFoundException("Could not access the authorization manager!",
 566  0
                             authorizationManagerException);
 567  
                 }
 568  
 
 569  0
                 if (accessToNone)
 570  0
                     authorizationManager.revokeAccessFromPublic(entityType, entityID);
 571  
 
 572  
             }
 573  
         }
 574  
         // *** Process code generation annotations ***
 575  
         else
 576  
             // Get the source code for the annotation
 577  0
             annotationLogic.addSourceCodeForAnnotation(annotation, classEnhancementContext);
 578  0
     }
 579  
 
 580  
     /**
 581  
      * @see pt.digitalis.dif.codegen.util.IClassEnhancer#processAnnotation(pt.digitalis.dif.codegen.util.ClassEnhancementContext,
 582  
      *      pt.digitalis.utils.bytecode.holders.AttributeHolder, pt.digitalis.utils.bytecode.holders.AnnotationHolder,
 583  
      *      pt.digitalis.dif.dem.DEMAnnotationLogic)
 584  
      */
 585  
     @SuppressWarnings("unchecked")
 586  
     public void processAnnotation(ClassEnhancementContext classEnhancementContext, AttributeHolder attribute,
 587  
             AnnotationHolder annotation, DEMAnnotationLogic annotationLogic) throws ResourceNotFoundException,
 588  
             CodeGenerationException, DIFCodeGenerationException
 589  
     {
 590  
 
 591  
         // *** Process behavior-triggering annotations ***
 592  
 
 593  0
         String annotationName = annotation.getName();
 594  0
         boolean generateSourceCode = true;
 595  
 
 596  
         // The following section implements the following annotations:
 597  
         // Parameter, Persist, Validator
 598  0
         if (annotationName.equals(Parameter.class.getCanonicalName()))
 599  
         {
 600  0
             Map<String, AnnotationMemberValueHolder> paramValues = annotation.getMembers();
 601  
 
 602  0
             String id = paramValues.get(AnnotationMemberTags.PARAMETER_ID).toString();
 603  0
             String constraints = paramValues.get(AnnotationMemberTags.PARAMETER_CONSTRAINTS).toString();
 604  0
             String defaultValue = paramValues.get(AnnotationMemberTags.PARAMETER_DEFAULT_VALUE).toString();
 605  0
             String linkForm = paramValues.get(AnnotationMemberTags.PARAMETER_LINK_TO_FORM).toString();
 606  0
             String[] regexp = paramValues.get(AnnotationMemberTags.PARAMETER_REGEXP_VALUE).toStringArray();
 607  
 
 608  
             // No id given, use the attribute name to lowercase
 609  0
             if (id.equals(AnnotationTags.GENERATE_ID))
 610  0
                 id = attribute.getName().toLowerCase();
 611  
 
 612  
             // No constraints identifier, set to empty constraint string
 613  0
             if (constraints.equals(AnnotationTags.NONE))
 614  0
                 constraints = "";
 615  
 
 616  0
             if (regexp.length == 1)
 617  
             {
 618  0
                 if (constraints.length() > 0)
 619  0
                     constraints += ",";
 620  0
                 constraints += "regex=" + regexp[0];
 621  
             }
 622  0
             else if (regexp.length == 2)
 623  
             {
 624  0
                 if (constraints.length() > 0)
 625  0
                     constraints += ",";
 626  
 
 627  0
                 constraints += "regex=" + ParameterConstraintRegexImpl.REGEXP_LIST_START
 628  0
                         + regexp[0].replaceAll(",", ParameterConstraintRegexImpl.REGEXP_COMMA)
 629  0
                         + ParameterConstraintRegexImpl.REGEXP_LIST_SEPARATOR
 630  0
                         + regexp[1].replaceAll(",", ParameterConstraintRegexImpl.REGEXP_COMMA)
 631  0
                         + ParameterConstraintRegexImpl.REGEXP_LIST_END;
 632  
             }
 633  0
             else if (regexp.length > 2)
 634  
             {
 635  0
                 UsageIssuesManagerImpl.getInstance().addIssue(
 636  0
                         IssueType.ERROR,
 637  0
                         IssueScope.LOADTIME,
 638  0
                         classEnhancementContext.getOriginalClassObject().getFQName(),
 639  0
                         "Parameter \"" + annotation.getParentAttribute().getName()
 640  0
                                 + "\" has more than 2 regular expressions associated. "
 641  0
                                 + "Must have one if common for java and JavaScript or two, if diferent. "
 642  0
                                 + "More that two is a configuration error. All regular expressions will be ignored!\"",
 643  0
                         null);
 644  
             }
 645  
 
 646  
             // No default value, set to empty string
 647  0
             if (defaultValue.equals(AnnotationTags.NONE))
 648  0
                 defaultValue = "";
 649  
 
 650  
             // No form to link, set to null
 651  0
             if (linkForm.equals(AnnotationTags.NONE))
 652  0
                 linkForm = null;
 653  
 
 654  
             // Defaults - Persist
 655  0
             ParameterScope scope = ParameterScope.REQUEST;
 656  0
             boolean persistentToRepository = false;
 657  0
             boolean formConfigurable = false;
 658  0
             boolean allowAnonymous = false;
 659  
 
 660  
             // Check for the persist annotation
 661  0
             AnnotationHolder persistAnnotation = annotation.getParentAttribute().getAnnotations()
 662  0
                     .get(Persist.class.getCanonicalName());
 663  
 
 664  0
             if (persistAnnotation != null)
 665  
             {
 666  
 
 667  0
                 Map<String, AnnotationMemberValueHolder> persistValues = persistAnnotation.getMembers();
 668  
 
 669  
                 // Override default from the declared parameters in @Persist
 670  0
                 scope = ParameterScope.valueOf(persistValues.get(AnnotationMemberTags.PERSIST_SCOPE)
 671  0
                         .enumValuetoString());
 672  0
                 persistentToRepository = persistValues.get(AnnotationMemberTags.PERSIST_REPOSITORY).toBoolean();
 673  0
                 allowAnonymous = persistValues.get(AnnotationMemberTags.PERSIST_ALLOW_ANONYMOUS).toBoolean();
 674  
 
 675  
                 // TODO: Implement this. Wait for the User/Group Manager
 676  
                 // String groupVisibility =
 677  
                 // persistValues.get(AnnotationMemberTags.PERSIST_GROUP_VISIBILITY).toString();
 678  
             }
 679  
 
 680  
             // Check for the formConfigurable annotation
 681  0
             formConfigurable = annotation.getParentAttribute().getAnnotations()
 682  0
                     .get(FormConfigurable.class.getCanonicalName()) != null;
 683  
 
 684  
             // Defaults - Rule
 685  0
             List<IParameterRule<?>> rules = new ArrayList<IParameterRule<?>>();
 686  0
             boolean ruleWithError = false;
 687  
 
 688  
             // Check for the rule annotation
 689  0
             AnnotationHolder ruleAnnotation = annotation.getParentAttribute().getAnnotations()
 690  0
                     .get(Rule.class.getCanonicalName());
 691  
 
 692  0
             if (ruleAnnotation != null)
 693  
             {
 694  0
                 IParameterRule<?> rule = getRule(id, ruleAnnotation);
 695  0
                 if (rule != null)
 696  0
                     rules.add(rule);
 697  
                 else
 698  0
                     ruleWithError = true;
 699  
             }
 700  
 
 701  
             // Check for the rules annotation
 702  0
             AnnotationHolder rulesAnnotation = annotation.getParentAttribute().getAnnotations()
 703  0
                     .get(Rules.class.getCanonicalName());
 704  
 
 705  0
             if (rulesAnnotation != null)
 706  0
                 for (AnnotationHolder innerRule: rulesAnnotation.getMembers().get(AnnotationMemberTags.VALUE)
 707  0
                         .toAnnotationList(attribute))
 708  
                 {
 709  0
                     IParameterRule<?> rule = getRule(id, innerRule);
 710  0
                     if (rule != null)
 711  0
                         rules.add(rule);
 712  
                     else
 713  0
                         ruleWithError = true;
 714  
                 }
 715  
 
 716  
             // TODO: Implement @Validator
 717  
 
 718  
             @SuppressWarnings("rawtypes")
 719  0
             IParameter param = parameterManager.getParameterInstanceForType(annotation.getParentAttribute()
 720  0
                     .getAttributeType());
 721  
 
 722  0
             if (param == null)
 723  
             {
 724  0
                 generateSourceCode = false;
 725  0
                 UsageIssuesManagerImpl.getInstance().addIssue(
 726  0
                         IssueType.ERROR,
 727  0
                         IssueScope.LOADTIME,
 728  0
                         classEnhancementContext.getOriginalClassObject().getFQName(),
 729  0
                         "Parameter \"" + annotation.getParentAttribute().getName() + "\" has an unsupported type \""
 730  0
                                 + annotation.getParentAttribute().getAttributeType() + "\"", null);
 731  
             }
 732  
             else
 733  
             {
 734  0
                 Entity parentType = EntityUtils.getEntityType(attribute.getParentClass());
 735  0
                 String parentID = EntityUtils.getEntityID(attribute.getParentClass());
 736  
 
 737  0
                 if (ruleWithError)
 738  
                 {
 739  0
                     UsageIssuesManagerImpl.getInstance().addIssue(IssueType.ERROR, IssueScope.LOADTIME,
 740  0
                             classEnhancementContext.getOriginalClassObject().getFQName(),
 741  0
                             "Parameter \"" + annotation.getParentAttribute().getName() + "\" has an unsupported rule",
 742  0
                             null);
 743  
                 }
 744  
 
 745  
                 try
 746  
                 {
 747  0
                     param.initialize(id, parentType, parentID, formConfigurable, persistentToRepository,
 748  0
                             allowAnonymous, scope, defaultValue, constraints, null, rules);
 749  0
                     param.setFormLinked(linkForm);
 750  0
                     parameterManager.registerParameter(param);
 751  
 
 752  
                 }
 753  0
                 catch (ParameterException e)
 754  
                 {
 755  
                     // Exception initializing the parameter. This parameter will be
 756  
                     // unavailable.
 757  0
                     generateSourceCode = false;
 758  
                 }
 759  
 
 760  
                 // Only generate initialization code if it is a stage. If on another
 761  
                 // entity it will only declare the
 762  
                 // parameter and not inject it
 763  0
                 generateSourceCode = (parentType == Entity.STAGE);
 764  
             }
 765  
         }
 766  
 
 767  
         // If the code generation has not been overridden with a
 768  
         // behavior-triggering annotation generate it
 769  0
         if (generateSourceCode)
 770  0
             annotationLogic.addSourceCodeForAnnotation(classEnhancementContext, annotation, attribute);
 771  0
     }
 772  
 
 773  
     /**
 774  
      * @see pt.digitalis.dif.codegen.util.IClassEnhancer#processAnnotation(pt.digitalis.dif.codegen.util.ClassEnhancementContext,
 775  
      *      pt.digitalis.utils.bytecode.holders.MethodHolder, pt.digitalis.utils.bytecode.holders.AnnotationHolder,
 776  
      *      pt.digitalis.dif.dem.DEMAnnotationLogic)
 777  
      */
 778  
     public void processAnnotation(ClassEnhancementContext classEnhancementContext, MethodHolder method,
 779  
             AnnotationHolder annotation, DEMAnnotationLogic annotationLogic) throws ResourceNotFoundException,
 780  
             CodeGenerationException, DIFCodeGenerationException
 781  
     {
 782  
 
 783  
         // Get the source code for the annotation
 784  0
         annotationLogic.addSourceCodeForAnnotation(classEnhancementContext, annotation, method);
 785  0
     }
 786  
 
 787  
     /**
 788  
      * Process the Group annotation
 789  
      * 
 790  
      * @param clazz
 791  
      *            the class instance
 792  
      * @param annotation
 793  
      *            the annotation to process
 794  
      * @throws ResourceNotFoundException
 795  
      */
 796  
     private void processGroupAnnotation(ClassHolder clazz, AnnotationHolder annotation)
 797  
             throws ResourceNotFoundException
 798  
     {
 799  
         // Get the parent info
 800  0
         Entity entityType = EntityUtils.getEntityType(clazz);
 801  
 
 802  0
         if (!identityManager.isReadOnly() && entityType.equals(Entity.APPLICATION))
 803  
         {
 804  0
             String groupName = annotation.getMembers().get("groupName").toString();
 805  
 
 806  
             try
 807  
             {
 808  0
                 if (!identityManager.groupExists(groupName))
 809  
                 {
 810  0
                     String fullName = annotation.getMembers().get("fullName").toString();
 811  0
                     String groupParent = annotation.getMembers().get("groupParent").toString();
 812  
 
 813  
                     // Set dynamic default values...
 814  0
                     if ("".equals(fullName))
 815  0
                         fullName = groupName;
 816  
 
 817  
                     // Check for parent group...
 818  0
                     if (!"".equals(groupParent) && !identityManager.groupExists(groupParent))
 819  
                     {
 820  0
                         IDIFGroup group = DIFIoCRegistry.getRegistry().getImplementation(IDIFGroup.class);
 821  0
                         group.setID(groupParent);
 822  0
                         group.setName(groupParent);
 823  0
                         group.setDescription(groupParent);
 824  0
                         group.setDefault(true);
 825  
 
 826  0
                         identityManager.addGroup(group);
 827  
                     }
 828  
 
 829  
                     // Create the group
 830  0
                     IDIFGroup group = DIFIoCRegistry.getRegistry().getImplementation(IDIFGroup.class);
 831  0
                     group.setID(groupName);
 832  0
                     group.setName(groupName);
 833  0
                     group.setDescription(fullName);
 834  
 
 835  0
                     if (!"".equals(groupParent))
 836  0
                         group.setParentGroupID(groupParent);
 837  
 
 838  0
                     group.setDefault(true);
 839  
 
 840  0
                     identityManager.addGroup(group);
 841  
                 }
 842  
             }
 843  0
             catch (IdentityManagerException identityManagerException)
 844  
             {
 845  0
                 if (identityManager.isReadOnly())
 846  0
                     DIFLogger.getLogger().info("Identity Manager in Read Only mode.");
 847  
                 else
 848  0
                     DIFLogger.getLogger().warn(
 849  0
                             "Could not access the identity manager!" + identityManagerException.getMessage());
 850  
             }
 851  
         }
 852  
 
 853  0
     }
 854  
 
 855  
     /**
 856  
      * Process the User annotation
 857  
      * 
 858  
      * @param clazz
 859  
      *            the class instance
 860  
      * @param annotation
 861  
      *            the annotation to process
 862  
      * @throws ResourceNotFoundException
 863  
      */
 864  
     private void processUserAnnotation(ClassHolder clazz, AnnotationHolder annotation) throws ResourceNotFoundException
 865  
     {
 866  
         // Get the parent info
 867  0
         Entity entityType = EntityUtils.getEntityType(clazz);
 868  
 
 869  0
         if (!identityManager.isReadOnly() && entityType.equals(Entity.APPLICATION))
 870  
         {
 871  0
             String userName = annotation.getMembers().get("userName").toString();
 872  
 
 873  
             try
 874  
             {
 875  
                 // If the user does not already exist...
 876  0
                 if (!identityManager.userExists(userName))
 877  
                 {
 878  0
                     String password = annotation.getMembers().get("password").toString();
 879  0
                     String fullName = annotation.getMembers().get("fullName").toString();
 880  0
                     String nick = annotation.getMembers().get("nick").toString();
 881  0
                     String email = annotation.getMembers().get("email").toString();
 882  0
                     String profile = annotation.getMembers().get("profile").toString();
 883  
 
 884  
                     // Set dynamic default values...
 885  0
                     if ("".equals(password))
 886  0
                         password = DEFAULT_PASSWORD;
 887  
 
 888  0
                     if ("".equals(fullName))
 889  0
                         fullName = userName;
 890  
 
 891  0
                     if ("".equals(nick))
 892  0
                         nick = userName;
 893  
 
 894  0
                     if ("".equals(email))
 895  0
                         email = userName + "@domain.com";
 896  
 
 897  0
                     String[] groups = CGAncillaries.parse(annotation.getMembers().get("groups").toString(), ",");
 898  0
                     String[] attributes = CGAncillaries
 899  0
                             .parse(annotation.getMembers().get("attributes").toString(), ",");
 900  
 
 901  
                     // Add the profile to the group list...
 902  0
                     List<String> allGroups = new ArrayList<String>(Arrays.asList(groups));
 903  0
                     allGroups.add(profile);
 904  
 
 905  
                     // Check all groups and create inexisting ones...
 906  0
                     for (String groupName: allGroups)
 907  0
                         if (!identityManager.groupExists(groupName))
 908  
                         {
 909  0
                             IDIFGroup group = DIFIoCRegistry.getRegistry().getImplementation(IDIFGroup.class);
 910  0
                             group.setID(groupName);
 911  0
                             group.setName(groupName);
 912  0
                             group.setDescription(groupName);
 913  0
                             group.setDefault(true);
 914  
 
 915  0
                             identityManager.addGroup(group);
 916  
                         }
 917  
 
 918  
                     // Create the user...
 919  0
                     IDIFUser user = DIFIoCRegistry.getRegistry().getImplementation(IDIFUser.class);
 920  0
                     user.setID(userName);
 921  0
                     user.setName(fullName);
 922  0
                     user.setNick(fullName);
 923  0
                     user.setPassword(password);
 924  0
                     user.setEmail(email);
 925  0
                     user.setProfileID(profile);
 926  0
                     user.setDefault(true);
 927  
 
 928  0
                     identityManager.addUser(user);
 929  
 
 930  
                     // Only after all groups and user have been created can we add the user to the groups
 931  0
                     for (String groupName: allGroups)
 932  0
                         identityManager.addUserToGroup(userName, groupName);
 933  
 
 934  
                     // Refresh the user, to pick up the repository bindings...
 935  0
                     user = identityManager.getUser(userName);
 936  
 
 937  
                     // Parse and set all attributes
 938  0
                     for (String attrPair: attributes)
 939  
                     {
 940  0
                         String[] values = CGAncillaries.parse(attrPair, "=");
 941  
 
 942  0
                         if (values.length == 2)
 943  
                             try
 944  
                             {
 945  0
                                 user.setAttribute(values[0], values[1]);
 946  
 
 947  
                             }
 948  0
                             catch (InternalFrameworkException e)
 949  
                             {
 950  0
                                 DIFLogger.getLogger().error(
 951  0
                                         "Could not add default attribute \"" + values[0] + " for user \"" + userName
 952  0
                                                 + "\"!");
 953  
                             }
 954  
                     }
 955  
                 }
 956  
             }
 957  0
             catch (IdentityManagerException identityManagerException)
 958  
             {
 959  0
                 if (identityManager.isReadOnly())
 960  0
                     DIFLogger.getLogger().info("Identity Manager in Read Only mode.");
 961  
                 else
 962  0
                     DIFLogger.getLogger().warn(
 963  0
                             "Could not access the identity manager!" + identityManagerException.getMessage());
 964  
             }
 965  
         }
 966  0
     }
 967  
 }