Coverage Report - pt.digitalis.dif.dem.DEMAnnotationLogic
 
Classes in this File Line Coverage Branch Coverage Complexity
DEMAnnotationLogic
0%
0/748
0%
0/404
7,833
 
 1  
 /**
 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.dem;
 7  
 
 8  
 import java.lang.reflect.Constructor;
 9  
 import java.lang.reflect.InvocationTargetException;
 10  
 import java.net.URL;
 11  
 import java.util.ArrayList;
 12  
 import java.util.HashMap;
 13  
 import java.util.List;
 14  
 import java.util.Map;
 15  
 import java.util.Set;
 16  
 
 17  
 import javassist.bytecode.annotation.MemberValue;
 18  
 
 19  
 import org.apache.commons.lang.StringUtils;
 20  
 
 21  
 import pt.digitalis.dif.codegen.CGAncillaries;
 22  
 import pt.digitalis.dif.codegen.util.ClassEnhancementContext;
 23  
 import pt.digitalis.dif.codegen.util.DEMLoaderEntityRegistry;
 24  
 import pt.digitalis.dif.codegen.util.DEMLoaderHelper;
 25  
 import pt.digitalis.dif.codegen.util.EntityUtils;
 26  
 import pt.digitalis.dif.controller.security.managers.IAuthorizationManager;
 27  
 import pt.digitalis.dif.dem.annotations.AnnotationMemberTags;
 28  
 import pt.digitalis.dif.dem.annotations.AnnotationTags;
 29  
 import pt.digitalis.dif.dem.annotations.Application;
 30  
 import pt.digitalis.dif.dem.annotations.Provider;
 31  
 import pt.digitalis.dif.dem.annotations.ProviderList;
 32  
 import pt.digitalis.dif.dem.annotations.Service;
 33  
 import pt.digitalis.dif.dem.annotations.entities.ApplicationDefinition;
 34  
 import pt.digitalis.dif.dem.annotations.entities.ProviderDefinition;
 35  
 import pt.digitalis.dif.dem.annotations.entities.ServiceDefinition;
 36  
 import pt.digitalis.dif.dem.annotations.entities.StageDefinition;
 37  
 import pt.digitalis.dif.dem.annotations.entities.ValidatorDefinition;
 38  
 import pt.digitalis.dif.dem.annotations.metaannotations.MetaAnnotationMemberTags;
 39  
 import pt.digitalis.dif.dem.annotations.metaannotations.Primary;
 40  
 import pt.digitalis.dif.dem.annotations.parameter.AddDocumentToRepository;
 41  
 import pt.digitalis.dif.dem.annotations.parameter.CustomParameters;
 42  
 import pt.digitalis.dif.dem.annotations.parameter.FormConfigurable;
 43  
 import pt.digitalis.dif.dem.annotations.parameter.InjectParameter;
 44  
 import pt.digitalis.dif.dem.annotations.parameter.InjectParameterErrors;
 45  
 import pt.digitalis.dif.dem.annotations.parameter.InjectParameters;
 46  
 import pt.digitalis.dif.dem.annotations.parameter.Parameter;
 47  
 import pt.digitalis.dif.dem.annotations.parameter.Persist;
 48  
 import pt.digitalis.dif.dem.annotations.security.AccessControl;
 49  
 import pt.digitalis.dif.dem.annotations.stage.Callback;
 50  
 import pt.digitalis.dif.dem.annotations.stage.Context;
 51  
 import pt.digitalis.dif.dem.annotations.stage.ErrorStage;
 52  
 import pt.digitalis.dif.dem.annotations.stage.ErrorView;
 53  
 import pt.digitalis.dif.dem.annotations.stage.Execute;
 54  
 import pt.digitalis.dif.dem.annotations.stage.Finalize;
 55  
 import pt.digitalis.dif.dem.annotations.stage.Init;
 56  
 import pt.digitalis.dif.dem.annotations.stage.InjectMessages;
 57  
 import pt.digitalis.dif.dem.annotations.stage.Stage;
 58  
 import pt.digitalis.dif.dem.annotations.stage.View;
 59  
 import pt.digitalis.dif.dem.annotations.stage.controller.DispatcherMode;
 60  
 import pt.digitalis.dif.dem.annotations.stage.controller.InjectAuthenticationError;
 61  
 import pt.digitalis.dif.dem.interfaces.IApplication;
 62  
 import pt.digitalis.dif.dem.interfaces.IProvider;
 63  
 import pt.digitalis.dif.dem.managers.IDEMManager;
 64  
 import pt.digitalis.dif.dem.managers.IMessageManager;
 65  
 import pt.digitalis.dif.dem.managers.IParameterManager;
 66  
 import pt.digitalis.dif.dem.managers.impl.UsageIssuesManagerImpl;
 67  
 import pt.digitalis.dif.dem.objects.ViewType;
 68  
 import pt.digitalis.dif.dem.objects.issues.IssueScope;
 69  
 import pt.digitalis.dif.dem.objects.issues.IssueType;
 70  
 import pt.digitalis.dif.dem.objects.messages.MessageList;
 71  
 import pt.digitalis.dif.dem.objects.parameters.IParameter;
 72  
 import pt.digitalis.dif.dem.objects.parameters.IParameters;
 73  
 import pt.digitalis.dif.dem.objects.parameters.ParameterScope;
 74  
 import pt.digitalis.dif.exception.codegen.AnnotationMisuseException;
 75  
 import pt.digitalis.dif.exception.codegen.DIFCodeGenerationException;
 76  
 import pt.digitalis.dif.exception.codegen.IllegalAnnotationUsage;
 77  
 import pt.digitalis.dif.exception.codegen.IncompatiblePrimaryAnnotationsException;
 78  
 import pt.digitalis.dif.ioc.DIFIoCRegistry;
 79  
 import pt.digitalis.dif.startup.DIFStartupConfiguration;
 80  
 import pt.digitalis.dif.utils.extensions.document.DocumentRepositoryEntry;
 81  
 import pt.digitalis.log.LogLevel;
 82  
 import pt.digitalis.utils.CodeGenUtils;
 83  
 import pt.digitalis.utils.bytecode.holders.AnnotationHolder;
 84  
 import pt.digitalis.utils.bytecode.holders.AnnotationMemberValueHolder;
 85  
 import pt.digitalis.utils.bytecode.holders.AttributeHolder;
 86  
 import pt.digitalis.utils.bytecode.holders.ClassHolder;
 87  
 import pt.digitalis.utils.bytecode.holders.MethodHolder;
 88  
 import pt.digitalis.utils.inspection.exception.AuxiliaryOperationException;
 89  
 import pt.digitalis.utils.inspection.exception.ResourceNotFoundException;
 90  
 
 91  
 import com.google.inject.Inject;
 92  
 
 93  
 /**
 94  
  * Defines validation and enrichment logic for an annotationName or family of annotations. A set of methods validate
 95  
  * general rules for any annotationName. Specific methods that can be overrided on sub-classes allow fine-grained
 96  
  * validation rules. Methods that define the source code used on the code generation are also part of this class. TODO:
 97  
  * Some logic that read the annotation values for processing is repeated here and in the ClassEnhancerImpl. Should be
 98  
  * refactored for a single read operation. Maybe in 2.1 TODO: Making the xHolder classes inherit from a parent would
 99  
  * eliminate the need of several similar methods with just different parameter types (as in validate() and
 100  
  * validatePrimary()).
 101  
  * 
 102  
  * @author Pedro Viegas <a href="mailto:pviegas@digitalis.pt">pviegas@digitalis.pt</a>
 103  
  * @author Rodrigo Gonçalves <a href="mailto:rgoncalves@digitalis.pt">rgoncalves@digitalis.pt</a>
 104  
  * @author João Galaio <a href="mailto:jgalaio@digitalis.pt">jgalaio@digitalis.pt</a>
 105  
  * @created Aug 29, 2007
 106  
  */
 107  0
 public class DEMAnnotationLogic {
 108  
 
 109  
     /** The 'application' attribute name. */
 110  
     final static protected String APPLICATION_ATTRIBUTE_NAME = "application";
 111  
 
 112  
     /** The authorization manager instance */
 113  
     static private IAuthorizationManager authorizationManager;
 114  
 
 115  
     /** The the default DEM Annotation Logic class. */
 116  0
     final static public String DEFAULT_DEM_ANNOTATION_LOGIC_CLASS = DEMAnnotationLogic.class.getSimpleName();
 117  
 
 118  
     /** List of invalid characters for entity names/id's */
 119  
     static private final String ENTITY_NAME_BAD_CHARS = "\"\'?&";
 120  
 
 121  
     /** The 'provider' attribute name. */
 122  
     final static protected String PROVIDER_ATTRIBUTE_NAME = "provider";
 123  
 
 124  
     /** The 'service' attribute name. */
 125  
     final static protected String SERVICE_ATTRIBUTE_NAME = "service";
 126  
 
 127  
     /** The 'target' attribute name. */
 128  
     final static protected String TARGET_ATTRIBUTE_NAME = "target";
 129  
 
 130  
     /**
 131  
      * Factory method for DEMAnnotationLogic objects. Gets the name of a DEMAnnotationLogic subtype and generates the
 132  
      * appropriate object. Encapsulates the complex code used to create the objects by reflection. This method's client
 133  
      * is the <code>pt.digitalis.dif.codegen.util.DEMLoaderHelper#getAnnotationLogicMap()</code> which generates a map
 134  
      * whose values are DEMAnnotationLogic subclasses. These values can't be inserted on the map if they belong to a
 135  
      * runtime determined type.
 136  
      * 
 137  
      * @param annotationLogicClassName
 138  
      *            The name of the annotationName logic class
 139  
      * @param annotationClass
 140  
      *            The argument annotationName
 141  
      * @return a new DEMAnnotationLogic instance of the appropriate subclass
 142  
      * @throws ResourceNotFoundException
 143  
      *             if any needed class cannot be found
 144  
      * @throws AuxiliaryOperationException
 145  
      *             if any illegal operation or instantiation exceptions are raised
 146  
      */
 147  
     static public DEMAnnotationLogic makeObject(String annotationLogicClassName, ClassHolder annotationClass)
 148  
             throws ResourceNotFoundException, AuxiliaryOperationException
 149  
     {
 150  
 
 151  0
         String annotationClassName = annotationClass.getName();
 152  0
         boolean isPrimary = annotationClass.containsAnnotation(Primary.class.getCanonicalName());
 153  
 
 154  0
         DEMAnnotationLogic annotationLogicClassObject = null;
 155  
 
 156  0
         if (annotationLogicClassName.equals(DEMAnnotationLogic.DEFAULT_DEM_ANNOTATION_LOGIC_CLASS))
 157  0
             annotationLogicClassObject = new DEMAnnotationLogic(annotationClass.getFQName(), annotationClassName,
 158  0
                     isPrimary);
 159  
 
 160  
         else
 161  
         {
 162  
 
 163  
             // TODO: All this should be in the inspection utils utility classes.
 164  
             // Move it there.
 165  
 
 166  0
             Class<?> annotationLogicClass = null;
 167  
 
 168  
             try
 169  
             {
 170  
                 // Create an instance of the logic class
 171  0
                 annotationLogicClass = Class.forName(annotationLogicClassName);
 172  
 
 173  
             }
 174  0
             catch (ClassNotFoundException classNotFoundException)
 175  
             {
 176  0
                 throw new ResourceNotFoundException("Could not create class " + annotationLogicClassName
 177  0
                         + " (Does such type exists?)", classNotFoundException);
 178  
             }
 179  
 
 180  
             // Convert to subclass (NOTE: any class is a subclass of itself)
 181  0
             Class<? extends DEMAnnotationLogic> annotationLogicClassAsSubclass = annotationLogicClass
 182  0
                     .asSubclass(DEMAnnotationLogic.class);
 183  
 
 184  
             // DIFInitializer ctor holder
 185  
             Constructor<? extends DEMAnnotationLogic> constructor;
 186  
             try
 187  
             {
 188  
                 // Get the constructor with the appropriate number of args
 189  0
                 constructor = annotationLogicClassAsSubclass.getConstructor(String.class, String.class, boolean.class);
 190  
 
 191  
             }
 192  0
             catch (NoSuchMethodException noSuchMethodException)
 193  
             {
 194  0
                 throw new ResourceNotFoundException("Could not found an appropriate constructor for "
 195  0
                         + annotationLogicClassAsSubclass.getCanonicalName() + " (Wrong number or type of args?)",
 196  0
                         noSuchMethodException);
 197  
             }
 198  
 
 199  
             try
 200  
             {
 201  
                 // Create object of the exact type
 202  0
                 annotationLogicClassObject = constructor.newInstance(annotationClass.getFQName(), annotationClassName,
 203  0
                         isPrimary);
 204  
 
 205  
             }
 206  0
             catch (IllegalArgumentException illegalArgumentException)
 207  
             {
 208  0
                 throw new AuxiliaryOperationException("Could not create "
 209  0
                         + annotationLogicClassAsSubclass.getCanonicalName() + " object! (Illegal argument?)",
 210  0
                         illegalArgumentException);
 211  
             }
 212  0
             catch (InstantiationException instantiationException)
 213  
             {
 214  0
                 throw new AuxiliaryOperationException(
 215  0
                         "Could not create " + annotationLogicClassAsSubclass.getCanonicalName()
 216  0
                                 + " object! (Interface or abstract class?)", instantiationException);
 217  
             }
 218  0
             catch (IllegalAccessException illegalAccessException)
 219  
             {
 220  0
                 throw new AuxiliaryOperationException("Could not create "
 221  0
                         + annotationLogicClassAsSubclass.getCanonicalName() + " object! (Non-public constructor?)",
 222  0
                         illegalAccessException);
 223  
             }
 224  0
             catch (InvocationTargetException invocationTargetException)
 225  
             {
 226  0
                 throw new AuxiliaryOperationException(
 227  0
                         "Could not create " + annotationLogicClassAsSubclass.getCanonicalName()
 228  0
                                 + " object! (Previously thrown exception?)", invocationTargetException);
 229  
             }
 230  
         }
 231  
 
 232  
         // Return result
 233  0
         return annotationLogicClassObject;
 234  
     }
 235  
 
 236  
     /** The canonical annotation name to validate. */
 237  
     private final String annotationFQName;
 238  
 
 239  
     /** The annotation name to validate. */
 240  
     private String annotationName;
 241  
 
 242  
     /** DEM primary annotationName flag. */
 243  
     private final boolean primary;
 244  
 
 245  
     /**
 246  
      * Constructor.
 247  
      * 
 248  
      * @param annotationFQName
 249  
      *            the annotation fully qualified name
 250  
      * @param annotationName
 251  
      *            the annotation simple name
 252  
      * @param isPrimary
 253  
      *            T if annotation is primary, F otherwise
 254  
      */
 255  0
     public DEMAnnotationLogic(String annotationFQName, String annotationName, boolean isPrimary)
 256  
     {
 257  0
         this.annotationFQName = annotationFQName;
 258  0
         this.annotationName = annotationName;
 259  0
         this.primary = isPrimary;
 260  0
     }
 261  
 
 262  
     /**
 263  
      * This method will define the code to enhance the classes based on the annotations. It will create the appropriate
 264  
      * methods and their code and add them to the classEnhancement object.
 265  
      * 
 266  
      * @param classEnhancementContext
 267  
      *            the class enhancement context
 268  
      * @param annotation
 269  
      *            the annotation used to define the source code needed for enhancement
 270  
      * @throws ResourceNotFoundException
 271  
      *             if annotation members can't be accessed
 272  
      * @throws DIFCodeGenerationException
 273  
      */
 274  
     public void addSourceCodeForAnnotation(AnnotationHolder annotation, ClassEnhancementContext classEnhancementContext)
 275  
             throws ResourceNotFoundException, DIFCodeGenerationException
 276  
     {
 277  
         try
 278  
         {
 279  
             // Get the class holder
 280  0
             ClassHolder clazz = classEnhancementContext.getOriginalClassObject();
 281  
 
 282  
             // Get member values
 283  0
             Map<String, AnnotationMemberValueHolder> memberValues = annotation.getMembers();
 284  
 
 285  
             // Get annotation type name
 286  0
             String annotationName = annotation.getName();
 287  
 
 288  
             // Prepare source for annotations...
 289  0
             if (annotationName.equals(ProviderDefinition.class.getCanonicalName()))
 290  
             {
 291  
                 // Get annotation member values
 292  0
                 String id = memberValues.get(AnnotationMemberTags.ENTITY_DEFINITION_ID).toString();
 293  0
                 boolean defaultProvider = memberValues.get(AnnotationMemberTags.PROVIDER_DEFINITION_DEFAULT_PROVIDER)
 294  0
                         .toBoolean();
 295  
 
 296  
                 // Check if id generation is needed...
 297  0
                 if (AnnotationTags.GENERATE_ID.equals(id))
 298  0
                     id = CodeGenUtils.generateID(clazz.getName());
 299  
 
 300  
                 // Add source to class enhancement context
 301  0
                 classEnhancementContext.addEnhancement(CGAncillaries.ENTITY_GET_ID_METHOD, "{return \"" + id.toString()
 302  0
                         + "\";}");
 303  
 
 304  
                 // Get annotation member values for name
 305  0
                 String name = memberValues.get(AnnotationMemberTags.ENTITY_DEFINITION_NAME).toString();
 306  
                 // Add source to class enhancement context
 307  0
                 classEnhancementContext.addEnhancement(CGAncillaries.ENTITY_GET_NAME_METHOD,
 308  0
                         "{return \"" + name.toString() + "\";}");
 309  0
                 classEnhancementContext.addEnhancement(CGAncillaries.ENTITY_GET_ORIGINALCLASSNAME_METHOD, "{return \""
 310  0
                         + clazz.getFQName() + "\";}");
 311  
 
 312  0
                 if (!StringUtils.containsNone(id, ENTITY_NAME_BAD_CHARS.toCharArray()))
 313  0
                     UsageIssuesManagerImpl.getInstance().addIssue(IssueType.ERROR, IssueScope.LOADTIME,
 314  0
                             classEnhancementContext.getOriginalClassObject().getFQName(),
 315  0
                             "Cannot use any of \"" + ENTITY_NAME_BAD_CHARS + "\" for entity id's", null);
 316  0
                 if (!StringUtils.containsNone(name, ENTITY_NAME_BAD_CHARS.toCharArray()))
 317  0
                     UsageIssuesManagerImpl.getInstance().addIssue(IssueType.ERROR, IssueScope.LOADTIME,
 318  0
                             classEnhancementContext.getOriginalClassObject().getFQName(),
 319  0
                             "Cannot use any of \"" + ENTITY_NAME_BAD_CHARS + "\" for entity names", null);
 320  
 
 321  0
                 if (defaultProvider)
 322  0
                     DEMRegistryImpl.setDefaultProvider(id);
 323  
 
 324  
             }
 325  0
             else if (annotationName.equals(ApplicationDefinition.class.getCanonicalName()))
 326  
             {
 327  
                 // Get annotation member values for id
 328  0
                 String id = memberValues.get(AnnotationMemberTags.ENTITY_DEFINITION_ID).toString();
 329  
 
 330  
                 // Check if id generation is needed...
 331  0
                 if (AnnotationTags.GENERATE_ID.equals(id))
 332  0
                     id = CodeGenUtils.generateID(clazz.getName());
 333  
 
 334  
                 // Add source to class enhancement context
 335  0
                 classEnhancementContext.addEnhancement(CGAncillaries.ENTITY_GET_ID_METHOD, "{return \"" + id.toString()
 336  0
                         + "\";}");
 337  
 
 338  
                 // Get annotation member values for name
 339  0
                 String name = memberValues.get(AnnotationMemberTags.ENTITY_DEFINITION_NAME).toString();
 340  
 
 341  0
                 if (!StringUtils.containsNone(id, ENTITY_NAME_BAD_CHARS.toCharArray()))
 342  0
                     UsageIssuesManagerImpl.getInstance().addIssue(IssueType.ERROR, IssueScope.LOADTIME,
 343  0
                             classEnhancementContext.getOriginalClassObject().getFQName(),
 344  0
                             "Cannot use any of \"" + ENTITY_NAME_BAD_CHARS + "\" for entity id's", null);
 345  0
                 if (!StringUtils.containsNone(name, ENTITY_NAME_BAD_CHARS.toCharArray()))
 346  0
                     UsageIssuesManagerImpl.getInstance().addIssue(IssueType.ERROR, IssueScope.LOADTIME,
 347  0
                             classEnhancementContext.getOriginalClassObject().getFQName(),
 348  0
                             "Cannot use any of \"" + ENTITY_NAME_BAD_CHARS + "\" for entity names", null);
 349  
 
 350  0
                 classEnhancementContext.addEnhancement(CGAncillaries.ENTITY_GET_NAME_METHOD,
 351  0
                         "{return \"" + name.toString() + "\";}");
 352  0
                 classEnhancementContext.addEnhancement(CGAncillaries.ENTITY_GET_ORIGINALCLASSNAME_METHOD, "{return \""
 353  0
                         + clazz.getFQName() + "\";}");
 354  
 
 355  
                 // Get annotation member values for provider
 356  0
                 String provider = memberValues.get(AnnotationMemberTags.APPLICATION_DEFINITION_PROVIDER).toString();
 357  
 
 358  
                 // Check if it's the default provider and proceed accordingly
 359  0
                 if (AnnotationTags.DEFAULT_PROVIDER.equals(provider))
 360  0
                     classEnhancementContext.addEnhancement(CGAncillaries.APPLICATION_GET_PROVIDER_METHOD,
 361  0
                             "{return getTemplateResources().getDEMManager().getDefaultProvider();}");
 362  
                 else
 363  0
                     classEnhancementContext.addEnhancement(CGAncillaries.APPLICATION_GET_PROVIDER_METHOD,
 364  0
                             "{return getTemplateResources().getDEMManager().getProvider(\"" + provider + "\");}");
 365  
 
 366  
                 // Add default access. If access control exists it will be processed
 367  
                 // later on
 368  0
                 if (!clazz.containsAnnotation(AccessControl.class.getCanonicalName()))
 369  0
                     getAuthorizationManager().grantDefaultPublicAccess(Entity.APPLICATION, id);
 370  
 
 371  
             }
 372  0
             else if (annotationName.equals(ServiceDefinition.class.getCanonicalName()))
 373  
             {
 374  
 
 375  
                 // Get annotation member values for id
 376  0
                 String id = memberValues.get(AnnotationMemberTags.ENTITY_DEFINITION_ID).toString();
 377  
 
 378  
                 // Check if id generation is needed...
 379  0
                 if (AnnotationTags.GENERATE_ID.equals(id))
 380  0
                     id = CodeGenUtils.generateID(clazz.getName());
 381  
 
 382  0
                 classEnhancementContext.addEnhancement(CGAncillaries.ENTITY_GET_ID_METHOD, "{return \"" + id.toString()
 383  0
                         + "\";}");
 384  
 
 385  
                 // Get annotation member values for name
 386  0
                 String name = memberValues.get(AnnotationMemberTags.ENTITY_DEFINITION_NAME).toString();
 387  0
                 classEnhancementContext.addEnhancement(CGAncillaries.ENTITY_GET_NAME_METHOD,
 388  0
                         "{return \"" + name.toString() + "\";}");
 389  0
                 classEnhancementContext.addEnhancement(CGAncillaries.ENTITY_GET_ORIGINALCLASSNAME_METHOD, "{return \""
 390  0
                         + clazz.getFQName() + "\";}");
 391  
 
 392  
                 // Get annotation member values for application
 393  0
                 String application = memberValues.get(AnnotationMemberTags.SERVICE_DEFINITION_APPLICATION).toString();
 394  
 
 395  0
                 classEnhancementContext.addEnhancement(CGAncillaries.SERVICE_GET_APPLICATION_METHOD,
 396  0
                         "{return getTemplateResources().getDEMManager().getApplication(\"" + application + "\");}");
 397  
 
 398  0
                 if (!StringUtils.containsNone(id, ENTITY_NAME_BAD_CHARS.toCharArray()))
 399  0
                     UsageIssuesManagerImpl.getInstance().addIssue(IssueType.ERROR, IssueScope.LOADTIME,
 400  0
                             classEnhancementContext.getOriginalClassObject().getFQName(),
 401  0
                             "Cannot use any of \"" + ENTITY_NAME_BAD_CHARS + "\" for entity id's", null);
 402  0
                 if (!StringUtils.containsNone(name, ENTITY_NAME_BAD_CHARS.toCharArray()))
 403  0
                     UsageIssuesManagerImpl.getInstance().addIssue(IssueType.ERROR, IssueScope.LOADTIME,
 404  0
                             classEnhancementContext.getOriginalClassObject().getFQName(),
 405  0
                             "Cannot use any of \"" + ENTITY_NAME_BAD_CHARS + "\" for entity names", null);
 406  
 
 407  
                 // Add default access. If access control exists it will be processed
 408  
                 // later on
 409  0
                 if (!clazz.containsAnnotation(AccessControl.class.getCanonicalName()))
 410  0
                     getAuthorizationManager().grantDefaultPublicAccess(Entity.SERVICE, id);
 411  
 
 412  
             }
 413  0
             else if (annotationName.equals(StageDefinition.class.getCanonicalName()))
 414  
             {
 415  
 
 416  
                 // Get annotation member values for id and override stage
 417  0
                 String id = memberValues.get(AnnotationMemberTags.ENTITY_DEFINITION_ID).toString();
 418  0
                 String override = memberValues.get(AnnotationMemberTags.STAGE_OVERRIDE_DEFAULT).toString();
 419  
 
 420  
                 // Check if id generation is needed...
 421  0
                 if (AnnotationTags.GENERATE_ID.equals(id))
 422  0
                     id = CodeGenUtils.generateID(clazz.getName());
 423  
                 else
 424  0
                     id = id.toLowerCase();
 425  
 
 426  0
                 classEnhancementContext.addEnhancement(CGAncillaries.ENTITY_GET_ID_METHOD, "{return \"" + id + "\";}");
 427  
 
 428  0
                 if (!AnnotationTags.NONE.equals(override))
 429  0
                     classEnhancementContext.addEnhancement(CGAncillaries.ENTITY_GET_OVERRIDE_METHOD, "{return \""
 430  0
                             + override + "\";}");
 431  
 
 432  
                 // Get annotation member values for name
 433  0
                 String name = memberValues.get(AnnotationMemberTags.ENTITY_DEFINITION_NAME).toString();
 434  0
                 classEnhancementContext.addEnhancement(CGAncillaries.ENTITY_GET_NAME_METHOD,
 435  0
                         "{return \"" + name.toString() + "\";}");
 436  0
                 classEnhancementContext.addEnhancement(CGAncillaries.ENTITY_GET_ORIGINALCLASSNAME_METHOD, "{return \""
 437  0
                         + clazz.getFQName() + "\";}");
 438  0
                 classEnhancementContext.addEnhancement(CGAncillaries.ENTITY_GET_STAGEINSTANCECLASSNAME_METHOD,
 439  0
                         "{return \"" + clazz.getFQName() + CGAncillaries.STAGE_INSTANCE_ID + "\";}");
 440  
 
 441  
                 // Get annotation member values for service
 442  0
                 String service = memberValues.get(AnnotationMemberTags.STAGE_DEFINITION_SERVICE).toString();
 443  
 
 444  0
                 if (!StringUtils.containsNone(id, ENTITY_NAME_BAD_CHARS.toCharArray()))
 445  0
                     UsageIssuesManagerImpl.getInstance().addIssue(IssueType.ERROR, IssueScope.LOADTIME,
 446  0
                             classEnhancementContext.getOriginalClassObject().getFQName(),
 447  0
                             "Cannot use any of \"" + ENTITY_NAME_BAD_CHARS + "\" for entity id's", null);
 448  0
                 if (!StringUtils.containsNone(name, ENTITY_NAME_BAD_CHARS.toCharArray()))
 449  0
                     UsageIssuesManagerImpl.getInstance().addIssue(IssueType.ERROR, IssueScope.LOADTIME,
 450  0
                             classEnhancementContext.getOriginalClassObject().getFQName(),
 451  0
                             "Cannot use any of \"" + ENTITY_NAME_BAD_CHARS + "\" for entity names", null);
 452  
 
 453  0
                 classEnhancementContext.addEnhancement(CGAncillaries.STAGE_GET_SERVICE_METHOD,
 454  0
                         "{return getTemplateResources().getDEMManager().getService(\"" + service + "\");}");
 455  
 
 456  
                 // Add default access. If access control exists it will be processed
 457  
                 // later on
 458  0
                 if (!clazz.containsAnnotation(AccessControl.class.getCanonicalName()))
 459  0
                     getAuthorizationManager().grantDefaultPublicAccess(Entity.STAGE, id);
 460  
 
 461  
             }
 462  0
             else if (annotationName.equals(ValidatorDefinition.class.getCanonicalName()))
 463  
             {
 464  
 
 465  
                 // TODO: Create Unit tests for this annotation when the ValidatorManager is implemented
 466  
 
 467  0
                 String validatorID = annotation.getMembers().get(AnnotationMemberTags.ENTITY_DEFINITION_ID).toString();
 468  
 
 469  
                 // Implementing IValidator interface methods
 470  0
                 classEnhancementContext.addEnhancement(CGAncillaries.ENTITY_GET_ID_METHOD, "{return \"" + validatorID
 471  0
                         + "\";}");
 472  
 
 473  
                 // TODO: This validatorManager does not exist. Determine what this
 474  
                 // implementation should be.
 475  0
                 classEnhancementContext.addEnhancement(CGAncillaries.VALIDATOR_GET_BOUND_PARAMETER_IDS_METHOD,
 476  0
                         "{return getTemplateResources().getValidatorManager().getBoundParameters(\"" + validatorID
 477  0
                                 + "\");}");
 478  
 
 479  
                 // Throw UnsupportedOpertationException to comply with Java
 480  
                 // standards and warn user of unimplemented
 481  
                 // feature.
 482  0
                 throw new UnsupportedOperationException(annotationName
 483  0
                         + " not yet supported! Please remove it from class " + clazz.getFQName());
 484  
             }
 485  
 
 486  0
             else if (annotationName.equals(Callback.class.getCanonicalName()))
 487  
             {
 488  
 
 489  
                 CallbackType callbackType;
 490  
 
 491  
                 // Get Callback type
 492  0
                 AnnotationMemberValueHolder memberValue = memberValues.get(AnnotationMemberTags.ANNOTATION_VALUE);
 493  
 
 494  0
                 if (memberValue.getManagedAnnotationValue() == null)
 495  0
                     callbackType = CallbackType.SIMPLE;
 496  
                 else
 497  0
                     callbackType = CallbackType.getCallbackTypeByName(memberValue.enumValuetoString());
 498  
 
 499  
                 // If callback type is OFF the code is the same copied from the
 500  
                 // template
 501  0
                 if (!callbackType.equals(CallbackType.OFF))
 502  
                 {
 503  0
                     classEnhancementContext.addEnhancement(CGAncillaries.CALLBACK_GET_CALLBACK_TYPE_METHOD,
 504  0
                             "{return getTemplateResources().getCallBack(\"" + callbackType + "\");}");
 505  
 
 506  0
                     classEnhancementContext.addEnhancement(CGAncillaries.CALLBACK_HAS_CALLBACK_ENABLED_METHOD,
 507  0
                             "{return true;}");
 508  
                 }
 509  
 
 510  
             }
 511  0
             else if (annotationName.equals(ErrorStage.class.getCanonicalName()))
 512  
             {
 513  0
                 addStage(annotation, classEnhancementContext, true, true, null);
 514  
             }
 515  0
             else if (annotationName.equals(View.class.getCanonicalName()))
 516  
             {
 517  0
                 addView(annotation, classEnhancementContext, false, true, null);
 518  
             }
 519  0
             else if (annotationName.equals(ErrorView.class.getCanonicalName()))
 520  
             {
 521  0
                 addView(annotation, classEnhancementContext, true, true, null);
 522  
             }
 523  0
             else if (annotationName.equals(DispatcherMode.class.getCanonicalName()))
 524  
             {
 525  
 
 526  
                 /*
 527  
                  * Implementation Note: This annotation treatment is done if the members evaluate to false!
 528  
                  */
 529  
 
 530  0
                 if (annotation.getMembers().containsKey(AnnotationMemberTags.DISPATCHER_MODE_AUTHENTICATE)
 531  0
                         && !annotation.getMembers().get(AnnotationMemberTags.DISPATCHER_MODE_AUTHENTICATE).toBoolean())
 532  0
                     classEnhancementContext.addEnhancement(CGAncillaries.STAGE_HAS_AUTHENTICATION, "{return false;}");
 533  
 
 534  0
                 if (annotation.getMembers().containsKey(AnnotationMemberTags.DISPATCHER_MODE_AUTHORIZE)
 535  0
                         && !annotation.getMembers().get(AnnotationMemberTags.DISPATCHER_MODE_AUTHORIZE).toBoolean())
 536  0
                     classEnhancementContext.addEnhancement(CGAncillaries.STAGE_HAS_AUTHORIZATION, "{return false;}");
 537  
             }
 538  
         }
 539  0
         catch (ResourceNotFoundException e)
 540  
         {
 541  
             // Rethrow for outer handling
 542  0
             throw e;
 543  
         }
 544  0
         catch (Exception e)
 545  
         {
 546  
             DIFCodeGenerationException codeGenException;
 547  
 
 548  0
             if (e instanceof DIFCodeGenerationException)
 549  
             {
 550  0
                 codeGenException = (DIFCodeGenerationException) e;
 551  
             }
 552  
             else
 553  
             {
 554  
 
 555  0
                 codeGenException = new DIFCodeGenerationException(e);
 556  0
                 codeGenException.addToExceptionContext("Original Class Name", classEnhancementContext
 557  0
                         .getOriginalClassObject().getFQName());
 558  
             }
 559  
 
 560  0
             codeGenException.addToExceptionContext("Annotation", annotation.getName());
 561  
 
 562  0
             throw codeGenException;
 563  
         }
 564  0
     }
 565  
 
 566  
     /**
 567  
      * This method will define the code to enhance the attributes based on the annotations. It will create the
 568  
      * appropriate methods and their code and add them to the classEnhancement object.
 569  
      * 
 570  
      * @param classEnhancementContext
 571  
      *            the class enhancement context
 572  
      * @param annotation
 573  
      *            the annotation used to define the source code needed for enhancement
 574  
      * @param attribute
 575  
      *            the attribute to be enhanced (to make the context available to the source building process)
 576  
      * @throws ResourceNotFoundException
 577  
      *             if annotation members can't be accessed
 578  
      * @throws DIFCodeGenerationException
 579  
      */
 580  
     public void addSourceCodeForAnnotation(ClassEnhancementContext classEnhancementContext,
 581  
             AnnotationHolder annotation, AttributeHolder attribute) throws ResourceNotFoundException,
 582  
             DIFCodeGenerationException
 583  
     {
 584  
         try
 585  
         {
 586  
             // Get the attribute name
 587  0
             String attributeName = attribute.getName();
 588  
 
 589  
             // Get annotation type name
 590  0
             String annotationName = annotation.getName();
 591  
 
 592  
             // Get member values
 593  0
             Map<String, AnnotationMemberValueHolder> memberValues = annotation.getMembers();
 594  
 
 595  0
             if (annotationName.equals(Context.class.getCanonicalName()))
 596  
             {
 597  
                 // DIFContext is the 1st argument of
 598  
                 // EntityCGTemplate.DIF_INIT_METHOD_NAME
 599  0
                 classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 600  0
                         CGAncillaries.STAGE_INJECTED_ATTRIBUTES_INIT_METHOD_NAME, "this." + attributeName
 601  0
                                 + "=this.getContext();");
 602  
 
 603  
             }
 604  0
             else if (annotationName.equals(InjectMessages.class.getCanonicalName()))
 605  
             {
 606  0
                 classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 607  0
                         CGAncillaries.STAGE_INJECTED_ATTRIBUTES_INIT_METHOD_NAME, "this." + attributeName
 608  0
                                 + "=this.getMessages();");
 609  
             }
 610  0
             else if (annotationName.equals(Stage.class.getCanonicalName()))
 611  
             {
 612  0
                 addStage(annotation, classEnhancementContext, false, false, attributeName);
 613  
             }
 614  0
             else if (annotationName.equals(ErrorStage.class.getCanonicalName()))
 615  
             {
 616  0
                 addStage(annotation, classEnhancementContext, true, false, attributeName);
 617  
             }
 618  0
             else if (annotationName.equals(View.class.getCanonicalName()))
 619  
             {
 620  0
                 addView(annotation, classEnhancementContext, false, annotation.getMembers().get("defaultView")
 621  0
                         .toBoolean(), attributeName);
 622  
             }
 623  0
             else if (annotationName.equals(ErrorView.class.getCanonicalName()))
 624  
             {
 625  0
                 addView(annotation, classEnhancementContext, true, false, attributeName);
 626  
             }
 627  0
             else if (annotationName.equals(Provider.class.getCanonicalName()))
 628  
             {
 629  0
                 classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 630  0
                         CGAncillaries.STAGE_INJECTED_ATTRIBUTES_INIT_METHOD_NAME, attributeName
 631  0
                                 + "=getService().getApplication().getProvider();");
 632  
             }
 633  0
             else if (annotationName.equals(Application.class.getCanonicalName()))
 634  
             {
 635  0
                 classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 636  0
                         CGAncillaries.STAGE_INJECTED_ATTRIBUTES_INIT_METHOD_NAME, attributeName
 637  0
                                 + "=getService().getApplication();");
 638  
             }
 639  0
             else if (annotationName.equals(Service.class.getCanonicalName()))
 640  
             {
 641  0
                 classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 642  0
                         CGAncillaries.STAGE_INJECTED_ATTRIBUTES_INIT_METHOD_NAME, attributeName + "=getService();");
 643  
 
 644  
                 // The following section implements the following annotations:
 645  
                 // Parameter, Persist, Validator
 646  
             }
 647  0
             else if (annotationName.equals(Parameter.class.getCanonicalName()))
 648  
             {
 649  
                 // Fetch id
 650  0
                 String id = memberValues.get(AnnotationMemberTags.PARAMETER_ID).toString();
 651  
 
 652  
                 // No id given, use the attribute name to lower case
 653  0
                 if (id.equals(AnnotationTags.GENERATE_ID))
 654  0
                     id = attribute.getName().toLowerCase();
 655  
 
 656  
                 // Get the ID and the type of the parent...
 657  0
                 String parentID = EntityUtils.getEntityID(attribute.getParentClass());
 658  0
                 Entity parentType = EntityUtils.getEntityType(attribute.getParentClass());
 659  
 
 660  0
                 IParameterManager parameterManager = DIFIoCRegistry.getRegistry().getImplementation(
 661  0
                         IParameterManager.class);
 662  
 
 663  0
                 IParameter<?> param = parameterManager.getParameter(parentType, parentID, id);
 664  
 
 665  0
                 if (param == null)
 666  
                 {
 667  
                     // Parameter was erronious. Report it.
 668  0
                     UsageIssuesManagerImpl.getInstance().addIssue(IssueType.ERROR, IssueScope.LOADTIME, parentID,
 669  0
                             "Bad parameter: \"" + id + "\"", null);
 670  
                 }
 671  
                 else
 672  
                 {
 673  
                     // Init/finalize code...
 674  0
                     String attrInitializer = attributeName
 675  0
                             + " = ("
 676  0
                             + annotation.getParentAttribute().getAttributeType()
 677  0
                             + ")_CG_parameterErrors.refreshParameter(getParameters().getStageParameters().getParameter(\""
 678  0
                             + id + "\"), this);";
 679  
 
 680  0
                     if (attribute.containsAnnotation(AddDocumentToRepository.class.getCanonicalName()))
 681  
                     {
 682  0
                         if (annotation.getParentAttribute().getAttributeType()
 683  0
                                 .equals(DocumentRepositoryEntry.class.getCanonicalName()))
 684  0
                             attrInitializer += " if (" + attributeName + " != null && " + attributeName
 685  0
                                     + ".getId() == null ) {" + attributeName
 686  0
                                     + " = getTemplateResources().getDocumentRepositoryManager().addDocument("
 687  0
                                     + attributeName + ");" + "}";
 688  
                     }
 689  
 
 690  0
                     classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 691  0
                             CGAncillaries.STAGE_INJECTED_ATTRIBUTES_INIT_METHOD_NAME, attrInitializer);
 692  
 
 693  0
                     if (!param.isReadonly())
 694  
                     {
 695  0
                         String attrFinalizer = "getParameters().getStageParameters().getParameter(\"" + id
 696  0
                                 + "\").setValue(" + attributeName + ", this);";
 697  0
                         classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 698  0
                                 CGAncillaries.STAGE_POSTPROCESSING_METHOD_NAME, attrFinalizer);
 699  
                     }
 700  
                 }
 701  
 
 702  
             }
 703  0
             else if (annotationName.equals(InjectParameter.class.getCanonicalName()))
 704  
             {
 705  
 
 706  
                 // Fetch id
 707  0
                 String id = memberValues.get(AnnotationMemberTags.PARAMETER_ID).toString();
 708  
 
 709  
                 // No id given, use the attribute name to lower case
 710  0
                 if (id.equals(AnnotationTags.GENERATE_ID))
 711  0
                     id = attribute.getName().toLowerCase();
 712  
 
 713  
                 // Get the parent service ID...
 714  0
                 AnnotationHolder stageDefinitionAnnotation = attribute.getParentClass().getAnnotations()
 715  0
                         .get(StageDefinition.class.getCanonicalName());
 716  0
                 String serviceID = stageDefinitionAnnotation.getMembers()
 717  0
                         .get(AnnotationMemberTags.STAGE_DEFINITION_SERVICE).toString();
 718  
 
 719  0
                 IParameterManager parameterManager = DIFIoCRegistry.getRegistry().getImplementation(
 720  0
                         IParameterManager.class);
 721  
 
 722  0
                 IParameter<?> param = parameterManager.getParameter(Entity.SERVICE, serviceID, id);
 723  0
                 String parameterGetter = null;
 724  
 
 725  
                 // Try to find the parameter through the DEM hierarchy
 726  0
                 if (param != null)
 727  0
                     parameterGetter = "getServiceParameters()";
 728  
                 else
 729  
                 {
 730  0
                     IDEMManager demManager = DIFIoCRegistry.getRegistry().getImplementation(IDEMManager.class);
 731  0
                     IApplication application = demManager.getService(serviceID).getApplication();
 732  0
                     param = parameterManager.getParameters(application).getParameter(id);
 733  
 
 734  0
                     if (param != null)
 735  0
                         parameterGetter = "getApplicationParameters()";
 736  
                     else
 737  
                     {
 738  0
                         IProvider provider = application.getProvider();
 739  0
                         param = parameterManager.getParameters(provider).getParameter(id);
 740  
 
 741  0
                         if (param != null)
 742  0
                             parameterGetter = "getProviderParameters()";
 743  
                     }
 744  
                 }
 745  
 
 746  0
                 if (parameterGetter == null)
 747  
                     // Throw UnsupportedOpertationException to comply with Java
 748  
                     // standards and warn user of the misusage.
 749  0
                     throw new UnsupportedOperationException("Parameter injection failed for attribute: \""
 750  0
                             + attributeName + "\"\n" + "Could not find a parameter for the id \"" + id
 751  0
                             + "\" in the DEM hierarchy.");
 752  
 
 753  
                 // Init/finalize code...
 754  0
                 String attrInitializer = attributeName + " = (" + annotation.getParentAttribute().getAttributeType()
 755  0
                         + ")_CG_parameterErrors.refreshParameter(getParameters()." + parameterGetter
 756  0
                         + ".getParameter(\"" + id + "\"), this);";
 757  
 
 758  0
                 classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 759  0
                         CGAncillaries.STAGE_INJECTED_ATTRIBUTES_INIT_METHOD_NAME, attrInitializer);
 760  
 
 761  0
                 if (param != null && !param.isReadonly())
 762  
                 {
 763  0
                     String attrFinalizer = "getParameters()." + parameterGetter + ".getParameter(\"" + id
 764  0
                             + "\").setValue(" + attributeName + ", this);";
 765  0
                     classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 766  0
                             CGAncillaries.STAGE_POSTPROCESSING_METHOD_NAME, attrFinalizer);
 767  
                 }
 768  
 
 769  
             }
 770  0
             else if (annotationName.equals(InjectParameters.class.getCanonicalName()))
 771  
             {
 772  0
                 classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 773  0
                         CGAncillaries.STAGE_INJECTED_ATTRIBUTES_INIT_METHOD_NAME, attributeName + "= getParameters();");
 774  
 
 775  
             }
 776  0
             else if (annotationName.equals(InjectParameterErrors.class.getCanonicalName()))
 777  
             {
 778  0
                 classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 779  0
                         CGAncillaries.STAGE_INJECTED_ATTRIBUTES_INIT_METHOD_NAME, attributeName
 780  0
                                 + "= getParameterErrors();");
 781  0
                 classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 782  0
                         CGAncillaries.STAGE_POSTPROCESSING_METHOD_NAME, "setParameterErrors(" + attributeName + ");");
 783  
 
 784  0
                 classEnhancementContext.addEnhancement(CGAncillaries.STAGE_HAS_PARAMETER_ERROR_INJECTION,
 785  0
                         "return true;");
 786  
 
 787  
             }
 788  0
             else if (annotationName.equals(ProviderList.class.getCanonicalName()))
 789  
             {
 790  
 
 791  0
                 String source = null;
 792  0
                 String signature = attribute.getSignature();
 793  
 
 794  
                 // TODO: The invocation of other classes is slow to compile
 795  
                 // in Javassist. This line is taking 50 to
 796  
                 // 100 times more to compile than all other ones.
 797  
 
 798  0
                 if (signature.contains(CGAncillaries.MAP_RETURN))
 799  
                 {
 800  0
                     source = attributeName + "=getTemplateResources().getDEMManager().getProviders();";
 801  
                 }
 802  0
                 else if (signature.contains(CGAncillaries.LIST_RETURN))
 803  
                 {
 804  0
                     source = attributeName + "= getTemplateResources().getProvidersAsList();";
 805  
                 }
 806  
 
 807  0
                 classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 808  0
                         CGAncillaries.STAGE_INJECTED_ATTRIBUTES_INIT_METHOD_NAME, source);
 809  
 
 810  
             }
 811  0
             else if (annotationName.equals(Inject.class.getCanonicalName()))
 812  
             {
 813  0
                 Entity parentType = EntityUtils.getEntityType(attribute.getParentClass());
 814  0
                 if (parentType == Entity.STAGE)
 815  0
                     classEnhancementContext.addEnhancement(CGAncillaries.STAGE_PROXY_ID,
 816  0
                             CGAncillaries.STAGE_HAS_INJECTED_CONTRIBUTIONS, "return true;");
 817  
                 else
 818  0
                     throw new UnsupportedOperationException("Dependency injection failed for attribute: \""
 819  0
                             + attributeName + "\"\n" + "@Inject can only be used in STAGE classes and not in "
 820  0
                             + parentType.toString() + ".");
 821  
             }
 822  0
             else if (annotationName.equals(InjectAuthenticationError.class.getCanonicalName()))
 823  
             {
 824  0
                 classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 825  0
                         CGAncillaries.STAGE_INJECTED_ATTRIBUTES_INIT_METHOD_NAME, attributeName
 826  0
                                 + "= getAuthenticationError();");
 827  0
                 classEnhancementContext.addEnhancement(CGAncillaries.STAGE_PROXY_ID,
 828  0
                         CGAncillaries.STAGE_HAS_AUTHENTICATION_ERROR_INJECTION, "return true;");
 829  
             }
 830  
         }
 831  0
         catch (ResourceNotFoundException e)
 832  
         {
 833  
             // Rethrow for outer handling
 834  0
             throw e;
 835  
         }
 836  0
         catch (Exception e)
 837  
         {
 838  
             DIFCodeGenerationException codeGenException;
 839  
 
 840  0
             if (e instanceof DIFCodeGenerationException)
 841  
             {
 842  0
                 codeGenException = (DIFCodeGenerationException) e;
 843  
             }
 844  
             else
 845  
             {
 846  
 
 847  0
                 codeGenException = new DIFCodeGenerationException(e);
 848  0
                 codeGenException.addToExceptionContext("Original Class Name", classEnhancementContext
 849  0
                         .getOriginalClassObject().getFQName());
 850  
             }
 851  
 
 852  0
             codeGenException.addToExceptionContext("Annotation", annotation.getName());
 853  0
             codeGenException.addToExceptionContext("Attribute", attribute.getName());
 854  
 
 855  0
             throw codeGenException;
 856  
         }
 857  0
     }
 858  
 
 859  
     /**
 860  
      * This method will define the code to enhance the methods based on the annotations. It will create the appropriate
 861  
      * methods and their code and add them to the classEnhancement object.
 862  
      * 
 863  
      * @param classEnhancementContext
 864  
      *            the class enhancement context
 865  
      * @param annotation
 866  
      *            the annotation used to define the source code needed for enhancement
 867  
      * @param method
 868  
      *            the method to be enhanced (to make the context available to the source building process)
 869  
      * @throws ResourceNotFoundException
 870  
      *             if annotation members can't be accessed
 871  
      * @throws DIFCodeGenerationException
 872  
      */
 873  
     public void addSourceCodeForAnnotation(ClassEnhancementContext classEnhancementContext,
 874  
             AnnotationHolder annotation, MethodHolder method) throws ResourceNotFoundException,
 875  
             DIFCodeGenerationException
 876  
     {
 877  
         try
 878  
         {
 879  
             // Get annotation and method info
 880  0
             String annotationName = annotation.getName();
 881  0
             String methodName = method.getName();
 882  0
             String signature = method.getSignature();
 883  
 
 884  0
             if (annotationName.equals(CustomParameters.class.getCanonicalName()))
 885  
             {
 886  
 
 887  
                 // Get the ID and the type of the parent...
 888  0
                 String parentID = EntityUtils.getEntityID(method.getParentClass());
 889  0
                 Entity parentType = EntityUtils.getEntityType(method.getParentClass());
 890  
 
 891  0
                 if (parentType == Entity.STAGE)
 892  
                 {
 893  0
                     if (signature.equals(CGAncillaries.IPARAMETERS_ARGS + CGAncillaries.VOID_RETURN))
 894  
                     {
 895  0
                         classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 896  0
                                 CGAncillaries.CALL_INIT_CUSTOM_PARAMETERS_METHOD, "{this." + methodName
 897  0
                                         + "($1);_CG_hasCustomParameters = true;}");
 898  
                     }
 899  
                     else
 900  
                     {
 901  0
                         throw new UnsupportedOperationException("(" + parentType.toString() + ": " + parentID
 902  0
                                 + ", method: " + methodName + ") @" + CustomParameters.class.getSimpleName()
 903  0
                                 + " can only be used on methods with void return and a single parameter of type "
 904  0
                                 + IParameters.class.getSimpleName() + ".");
 905  
                     }
 906  
                 }
 907  
                 else
 908  0
                     throw new UnsupportedOperationException("(" + parentType.toString() + ": " + parentID + ") @"
 909  0
                             + CustomParameters.class.getSimpleName() + " can only be used for Stage entities.");
 910  
             }
 911  0
             else if (annotationName.equals(Init.class.getCanonicalName()))
 912  
             {
 913  
 
 914  
                 // Get the ID and the type of the parent...
 915  0
                 String parentID = EntityUtils.getEntityID(method.getParentClass());
 916  0
                 Entity parentType = EntityUtils.getEntityType(method.getParentClass());
 917  
 
 918  0
                 if (parentType == Entity.APPLICATION)
 919  
                 {
 920  0
                     if (signature.equals(CGAncillaries.VOID_ARGS + CGAncillaries.VOID_RETURN))
 921  
                     {
 922  0
                         classEnhancementContext.addEnhancement(CGAncillaries.APP_INIT_METHOD, "{this." + methodName
 923  0
                                 + "();}");
 924  
                     }
 925  
                     else
 926  
                     {
 927  0
                         throw new UnsupportedOperationException("(" + parentType.toString() + ": " + parentID
 928  0
                                 + ") @Init events for applications must comply with: no arguments and void return.");
 929  
                     }
 930  
                 }
 931  0
                 else if (parentType == Entity.STAGE)
 932  
                 {
 933  0
                     if (signature.equals(CGAncillaries.VOID_ARGS + CGAncillaries.VOID_RETURN))
 934  
                     {
 935  
                         /*
 936  
                          * IMPLEMENTATION NOTE: Albeit the annotated method's return is void, IStage#init(DIFContext)
 937  
                          * returns a boolean, so the code generation must inject a boolean return. It always returns T.
 938  
                          */
 939  0
                         classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 940  0
                                 CGAncillaries.CALL_INIT_METHOD, "{this." + methodName + "(); return true;}");
 941  
 
 942  
                     }
 943  0
                     else if (signature.equals(CGAncillaries.IDIF_CONTEXT_ARGS + CGAncillaries.VOID_RETURN))
 944  
                     {
 945  
                         /*
 946  
                          * IMPLEMENTATION NOTE: Albeit the annotated method's return is void, IStage#init(DIFContext)
 947  
                          * returns a boolean, so the code generation must inject a boolean return. It always returns T.
 948  
                          */
 949  0
                         classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 950  0
                                 CGAncillaries.CALL_INIT_METHOD, "{this." + methodName + "($1); return true;}");
 951  
 
 952  
                     }
 953  0
                     else if (signature.equals(CGAncillaries.VOID_ARGS + CGAncillaries.BOOLEAN_RETURN))
 954  
                     {
 955  0
                         classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 956  0
                                 CGAncillaries.CALL_INIT_METHOD, "{return this." + methodName + "();}");
 957  
 
 958  
                     }
 959  0
                     else if (signature.equals(CGAncillaries.IDIF_CONTEXT_ARGS + CGAncillaries.BOOLEAN_RETURN))
 960  
                     {
 961  0
                         classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 962  0
                                 CGAncillaries.CALL_INIT_METHOD, "{return this." + methodName + "($1);}");
 963  
                     }
 964  
                 }
 965  
                 else
 966  0
                     throw new UnsupportedOperationException("(" + parentType.toString() + ": " + parentID
 967  0
                             + ") @Init can only be user for Stage or Application entities.");
 968  
             }
 969  0
             else if (annotationName.equals(Execute.class.getCanonicalName()))
 970  
             {
 971  
 
 972  0
                 String code = getCodeForExecutionMethod(signature, methodName);
 973  
 
 974  0
                 if (code != null)
 975  0
                     classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 976  0
                             CGAncillaries.CALL_EXEC_METHOD, code);
 977  
 
 978  
             }
 979  0
             else if (annotationName.equals(Finalize.class.getCanonicalName()))
 980  
             {
 981  
 
 982  0
                 if (signature.equals(CGAncillaries.VOID_ARGS + CGAncillaries.VOID_RETURN))
 983  
                 {
 984  
                     /*
 985  
                      * IMPLEMENTATION NOTE: Although the annotated method's return is void, IStage#finalize(DIFContext)
 986  
                      * returns a boolean, so the code generation must inject a boolean return. It always returns T.
 987  
                      */
 988  0
                     classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 989  0
                             CGAncillaries.CALL_FINALIZE_METHOD, "{this." + methodName + "(); return true;}");
 990  
                 }
 991  0
                 else if (signature.equals(CGAncillaries.IDIF_CONTEXT_ARGS + CGAncillaries.VOID_RETURN))
 992  
                 {
 993  
                     /*
 994  
                      * IMPLEMENTATION NOTE: Albeit the annotated method's return is void, IStage#finalize(DIFContext)
 995  
                      * returns a boolean, so the code generation must inject a boolean return. It always returns T.
 996  
                      */
 997  0
                     classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 998  0
                             CGAncillaries.CALL_FINALIZE_METHOD, "{this." + methodName + "($1); return true;}");
 999  
                 }
 1000  0
                 else if (signature.equals(CGAncillaries.VOID_ARGS + CGAncillaries.BOOLEAN_RETURN))
 1001  
                 {
 1002  0
                     classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 1003  0
                             CGAncillaries.CALL_FINALIZE_METHOD, "{return this." + methodName + "();}");
 1004  
                 }
 1005  0
                 else if (signature.equals(CGAncillaries.IDIF_CONTEXT_ARGS + CGAncillaries.BOOLEAN_RETURN))
 1006  
                 {
 1007  0
                     classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 1008  0
                             CGAncillaries.CALL_FINALIZE_METHOD, "{return this." + methodName + "($1);}");
 1009  
                 }
 1010  
             }
 1011  0
             else if (annotationName.equals(Inject.class.getCanonicalName()))
 1012  
             {
 1013  0
                 Entity parentType = EntityUtils.getEntityType(method.getParentClass());
 1014  0
                 if (parentType == Entity.STAGE)
 1015  0
                     classEnhancementContext.addEnhancement(CGAncillaries.STAGE_PROXY_ID,
 1016  0
                             CGAncillaries.STAGE_HAS_INJECTED_CONTRIBUTIONS, "return true;");
 1017  
                 else
 1018  0
                     throw new UnsupportedOperationException("Dependency injection failed for method: \"" + method
 1019  0
                             + "\"\n" + "@Inject can only be used in STAGE classes and not in " + parentType.toString()
 1020  0
                             + ".");
 1021  
             }
 1022  
         }
 1023  0
         catch (ResourceNotFoundException e)
 1024  
         {
 1025  
             // Rethrow for outer handling
 1026  0
             throw e;
 1027  
         }
 1028  0
         catch (Exception e)
 1029  
         {
 1030  
             DIFCodeGenerationException codeGenException;
 1031  
 
 1032  0
             if (e instanceof DIFCodeGenerationException)
 1033  
             {
 1034  0
                 codeGenException = (DIFCodeGenerationException) e;
 1035  
             }
 1036  
             else
 1037  
             {
 1038  
 
 1039  0
                 codeGenException = new DIFCodeGenerationException(e);
 1040  0
                 codeGenException.addToExceptionContext("Original Class Name", classEnhancementContext
 1041  0
                         .getOriginalClassObject().getFQName());
 1042  
             }
 1043  
 
 1044  0
             codeGenException.addToExceptionContext("Annotation", annotation.getName());
 1045  0
             codeGenException.addToExceptionContext("Method", method.getName());
 1046  
 
 1047  0
             throw codeGenException;
 1048  
         }
 1049  0
     }
 1050  
 
 1051  
     /**
 1052  
      * Adds an injected stage to the current stage to enhance. Injects it the the attribute associated (if passed) and
 1053  
      * to the inner Maps.
 1054  
      * 
 1055  
      * @param annotation
 1056  
      *            the annotation that declared the stage
 1057  
      * @param classEnhancementContext
 1058  
      *            the class enhancement context
 1059  
      * @param errorStage
 1060  
      *            if the stage to add is an error stage
 1061  
      * @param defaultStage
 1062  
      *            if the current stage is the default stage
 1063  
      * @param attributeName
 1064  
      *            the name of the attribute to assign the new stage to
 1065  
      * @throws ResourceNotFoundException
 1066  
      *             if the annotation cannot be read
 1067  
      * @throws DIFCodeGenerationException
 1068  
      */
 1069  
     protected void addStage(AnnotationHolder annotation, ClassEnhancementContext classEnhancementContext,
 1070  
             boolean errorStage, boolean defaultStage, String attributeName) throws ResourceNotFoundException,
 1071  
             DIFCodeGenerationException
 1072  
     {
 1073  
         try
 1074  
         {
 1075  
             String stageID;
 1076  
 
 1077  0
             AnnotationMemberValueHolder target = annotation.getMembers().get("target");
 1078  
 
 1079  0
             if (target == null)
 1080  0
                 target = annotation.getMembers().get("value");
 1081  
 
 1082  0
             if (target != null)
 1083  0
                 stageID = "\"" + target.toString() + "\"";
 1084  
             else
 1085  0
                 stageID = attributeName + ".getID()";
 1086  
 
 1087  0
             String stageDeclaration = "getTemplateResources().getDEMManager().getStage(" + stageID + ")";
 1088  
 
 1089  
             // If no attribute is available the stage will be obtained from the
 1090  
             // manager...
 1091  0
             if (attributeName != null)
 1092  0
                 classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 1093  0
                         CGAncillaries.STAGE_INJECTED_ATTRIBUTES_INIT_METHOD_NAME, attributeName + " = "
 1094  0
                                 + stageDeclaration + ";");
 1095  
 
 1096  0
             classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INJECTED_STAGES_BUILDER, "injectedStages.add("
 1097  0
                     + stageID + ");");
 1098  
 
 1099  0
             if (errorStage)
 1100  
             {
 1101  0
                 String[] exceptions = CGAncillaries.parse(
 1102  0
                         annotation.getMembers().get(AnnotationMemberTags.ERROR_STAGE_EXCEPTIONS).toString(),
 1103  0
                         CGAncillaries.COMMA);
 1104  
 
 1105  0
                 for (int i = 0; i < exceptions.length; i++)
 1106  0
                     classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INJECTED_ERRORSTAGES_BUILDER,
 1107  0
                             "errorStages.put(\"" + exceptions[i] + "\"," + stageID + ");");
 1108  
             }
 1109  
 
 1110  0
             String key = CGAncillaries.STAGE_GET_DEFAULT_ERROR_STAGE;
 1111  
 
 1112  
             // If it's the default error stage or there is none yet defined yet,
 1113  
             // this will become it!
 1114  0
             if (errorStage && (defaultStage || !classEnhancementContext.containsEnhancement(key)))
 1115  
             {
 1116  0
                 classEnhancementContext.addEnhancement(key, "{return " + stageDeclaration + ";}");
 1117  
             }
 1118  
         }
 1119  0
         catch (ResourceNotFoundException e)
 1120  
         {
 1121  
             // Rethrow for outer handling
 1122  0
             throw e;
 1123  
         }
 1124  0
         catch (Exception e)
 1125  
         {
 1126  
             DIFCodeGenerationException codeGenException;
 1127  
 
 1128  0
             if (e instanceof DIFCodeGenerationException)
 1129  
             {
 1130  0
                 codeGenException = (DIFCodeGenerationException) e;
 1131  
             }
 1132  
             else
 1133  
             {
 1134  
 
 1135  0
                 codeGenException = new DIFCodeGenerationException(e);
 1136  0
                 codeGenException.addToExceptionContext("Original Class Name", classEnhancementContext
 1137  0
                         .getOriginalClassObject().getFQName());
 1138  
             }
 1139  
 
 1140  0
             codeGenException.addToExceptionContext("Annotation", annotation.getName());
 1141  0
             codeGenException.addToExceptionContext("Attribute", attributeName);
 1142  
 
 1143  0
             throw codeGenException;
 1144  
         }
 1145  0
     }
 1146  
 
 1147  
     /**
 1148  
      * Adds an injected view to the current stage to enhance. Injects it the the attribute associated (if passed) and to
 1149  
      * the inner Maps.
 1150  
      * 
 1151  
      * @param annotation
 1152  
      *            the annotation that declared the stage
 1153  
      * @param classEnhancementContext
 1154  
      *            the class enhancement context
 1155  
      * @param errorView
 1156  
      *            if the view to add is an error view
 1157  
      * @param defaultView
 1158  
      *            if the view to add is the default stage view
 1159  
      * @param attributeName
 1160  
      *            the name of the attribute to assign the new view to
 1161  
      * @throws ResourceNotFoundException
 1162  
      *             if the annotation cannot be read
 1163  
      * @throws DIFCodeGenerationException
 1164  
      */
 1165  
     protected void addView(AnnotationHolder annotation, ClassEnhancementContext classEnhancementContext,
 1166  
             boolean errorView, boolean defaultView, String attributeName) throws ResourceNotFoundException,
 1167  
             DIFCodeGenerationException
 1168  
     {
 1169  
         try
 1170  
         {
 1171  
             // Get Error Stage id
 1172  0
             String target = annotation.getMembers().get(AnnotationMemberTags.VIEW_TARGET).toString();
 1173  
 
 1174  
             // Get view engine
 1175  0
             String engine = annotation.getMembers().get(AnnotationMemberTags.VIEW_ENGINE).toString();
 1176  
 
 1177  
             // Infer the view engine if not passed
 1178  0
             if (engine.equals(AnnotationTags.NONE))
 1179  
             {
 1180  0
                 int posExtension = target.lastIndexOf(".");
 1181  
 
 1182  0
                 if (posExtension != -1)
 1183  0
                     engine = target.substring(posExtension + 1);
 1184  
             }
 1185  
 
 1186  
             // Set view type
 1187  0
             ViewType viewType = null;
 1188  
 
 1189  0
             if (errorView)
 1190  0
                 viewType = ViewType.ERROR;
 1191  
             else
 1192  0
                 viewType = ViewType.NORMAL;
 1193  
 
 1194  0
             String viewDeclaration = "createView(\"" + engine + "\",\"" + viewType + "\",\"" + target + "\","
 1195  0
                     + defaultView + ")";
 1196  
 
 1197  
             // If no attribute is available the view will be generated...
 1198  0
             if (attributeName != null)
 1199  0
                 classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INSTANCE_ID,
 1200  0
                         CGAncillaries.STAGE_INJECTED_ATTRIBUTES_INIT_METHOD_NAME, attributeName + " = "
 1201  0
                                 + viewDeclaration + ";");
 1202  
 
 1203  0
             classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INJECTED_VIEWS_BUILDER, "injectedViews.add("
 1204  0
                     + viewDeclaration + ");");
 1205  
 
 1206  0
             if (errorView)
 1207  
             {
 1208  0
                 String[] exceptions = CGAncillaries.parse(
 1209  0
                         annotation.getMembers().get(AnnotationMemberTags.ERROR_STAGE_EXCEPTIONS).toString(),
 1210  0
                         CGAncillaries.COMMA);
 1211  
 
 1212  0
                 for (int i = 0; i < exceptions.length; i++)
 1213  0
                     classEnhancementContext.addEnhancement(CGAncillaries.STAGE_INJECTED_ERRORVIEWS_BUILDER,
 1214  0
                             "\nerrorViews.put(\"" + exceptions[i] + "\"," + viewDeclaration + ");");
 1215  
             }
 1216  
 
 1217  0
             String key = errorView ? CGAncillaries.STAGE_GET_DEFAULT_ERROR_VIEW : CGAncillaries.STAGE_GET_DEFAULT_VIEW;
 1218  
 
 1219  
             // If it's the default error stage or there is none yet defined yet,
 1220  
             // this will become it!
 1221  0
             if (defaultView || !classEnhancementContext.containsEnhancement(key))
 1222  
             {
 1223  0
                 classEnhancementContext.addEnhancement(key, "{return " + viewDeclaration + ";}");
 1224  
             }
 1225  
         }
 1226  0
         catch (ResourceNotFoundException e)
 1227  
         {
 1228  
             // Rethrow for outer handling
 1229  0
             throw e;
 1230  
         }
 1231  0
         catch (Exception e)
 1232  
         {
 1233  
             DIFCodeGenerationException codeGenException;
 1234  
 
 1235  0
             if (e instanceof DIFCodeGenerationException)
 1236  
             {
 1237  0
                 codeGenException = (DIFCodeGenerationException) e;
 1238  
             }
 1239  
             else
 1240  
             {
 1241  
 
 1242  0
                 codeGenException = new DIFCodeGenerationException(e);
 1243  0
                 codeGenException.addToExceptionContext("Original Class Name", classEnhancementContext
 1244  0
                         .getOriginalClassObject().getFQName());
 1245  
             }
 1246  
 
 1247  0
             codeGenException.addToExceptionContext("Annotation", annotation.getName());
 1248  0
             codeGenException.addToExceptionContext("Attribute", attributeName);
 1249  
 
 1250  0
             throw codeGenException;
 1251  
         }
 1252  0
     }
 1253  
 
 1254  
     /**
 1255  
      * Checks if a given annotation can be used with another.
 1256  
      * 
 1257  
      * @param annotationToCheck
 1258  
      *            the annotation to check
 1259  
      * @param thisAnnotation
 1260  
      *            the annotation to validate against
 1261  
      * @return F if the annotation to check is primary and doesn't yield to the other, T otherwise
 1262  
      * @throws ResourceNotFoundException
 1263  
      *             if any resource needed for validation could not be found.
 1264  
      */
 1265  
     protected boolean checkUseWith(AnnotationHolder annotationToCheck, AnnotationHolder thisAnnotation)
 1266  
             throws ResourceNotFoundException
 1267  
     {
 1268  
 
 1269  0
         if (annotationToCheck.getName().equals(thisAnnotation.getName()))
 1270  0
             return true;
 1271  
 
 1272  0
         if (isPrimary(annotationToCheck) && isPrimary(thisAnnotation))
 1273  
         {
 1274  0
             if (yieldsTo(annotationToCheck, thisAnnotation.getName())
 1275  0
                     || yieldsTo(thisAnnotation, annotationToCheck.getName()))
 1276  0
                 return true;
 1277  
             else
 1278  0
                 return false;
 1279  
         }
 1280  
 
 1281  0
         return true;
 1282  
     }
 1283  
 
 1284  
     /**
 1285  
      * Returns the annotationName.
 1286  
      * 
 1287  
      * @return the value of the annotationName
 1288  
      */
 1289  
     public String getAnnotation()
 1290  
     {
 1291  0
         return this.annotationName;
 1292  
     }
 1293  
 
 1294  
     /**
 1295  
      * @return the authorizationManager
 1296  
      */
 1297  
     protected IAuthorizationManager getAuthorizationManager()
 1298  
     {
 1299  0
         if (authorizationManager == null)
 1300  0
             authorizationManager = DIFIoCRegistry.getRegistry().getImplementation(IAuthorizationManager.class);
 1301  
 
 1302  0
         return authorizationManager;
 1303  
     }
 1304  
 
 1305  
     /**
 1306  
      * Return the appropriated execute method call injecting a return view if necessary and the appropriated parameters
 1307  
      * 
 1308  
      * @param signature
 1309  
      *            the method to call signature
 1310  
      * @param methodName
 1311  
      *            the method name to call
 1312  
      * @return the line of code for the calling of the method
 1313  
      */
 1314  
     protected String getCodeForExecutionMethod(String signature, String methodName)
 1315  
     {
 1316  
 
 1317  
         /*
 1318  
          * IMPLEMENTATION NOTE: Although the annotated method's return is void, IStage#execute(DIFContext) returns a
 1319  
          * ViewObject, so the code generation must inject a ViewObject return. It returns the default view.
 1320  
          */
 1321  
 
 1322  0
         if (signature.equals(CGAncillaries.VOID_ARGS + CGAncillaries.VOID_RETURN))
 1323  
         {
 1324  0
             return "{this." + methodName + "(); return this.getDefaultView();}";
 1325  
 
 1326  
         }
 1327  0
         else if (signature.equals(CGAncillaries.IDIF_CONTEXT_ARGS + CGAncillaries.VOID_RETURN))
 1328  
         {
 1329  0
             return "{this." + methodName + "($1); return this.getDefaultView();}";
 1330  
 
 1331  
         }
 1332  0
         else if (signature.equals(CGAncillaries.IDIF_CONTEXT_ARGS + CGAncillaries.VIEW_OBJECT_RETURN))
 1333  
         {
 1334  0
             return "{return this." + methodName + "($1);}";
 1335  
 
 1336  
         }
 1337  0
         else if (signature.equals(CGAncillaries.VOID_ARGS + CGAncillaries.VIEW_OBJECT_RETURN))
 1338  
         {
 1339  0
             return "{return this." + methodName + "();}";
 1340  
 
 1341  
         }
 1342  
         else
 1343  0
             return null;
 1344  
     }
 1345  
 
 1346  
     /**
 1347  
      * @return T if the current annotation is a DEM annotation
 1348  
      */
 1349  
     protected boolean isDEMAnnotation()
 1350  
     {
 1351  
         try
 1352  
         {
 1353  
             // Google Guice's @Inject is a special case since it exists in the DEMLogicMap but is not itself a DEM
 1354  
             // annotation
 1355  0
             return (!annotationFQName.equals(Inject.class.getCanonicalName()))
 1356  0
                     && (DEMLoaderHelper.getAnnotationLogicMap().keySet().contains(this.annotationFQName));
 1357  
 
 1358  
         }
 1359  0
         catch (ResourceNotFoundException e)
 1360  
         {
 1361  0
             return false;
 1362  
         }
 1363  0
         catch (AuxiliaryOperationException e)
 1364  
         {
 1365  0
             return false;
 1366  
         }
 1367  
     }
 1368  
 
 1369  
     /**
 1370  
      * Returns the value of the primary annotationName flag.
 1371  
      * 
 1372  
      * @return T if the annotationName is primary, F otherwise
 1373  
      */
 1374  
     final public boolean isPrimary()
 1375  
     {
 1376  0
         return primary;
 1377  
     }
 1378  
 
 1379  
     /**
 1380  
      * Checks if a given annotation is primary.
 1381  
      * 
 1382  
      * @param annotation
 1383  
      *            the annotation to check
 1384  
      * @return T if annotation is meta-annotated with <code>@Primary</code>, F otherwise.
 1385  
      * @throws ResourceNotFoundException
 1386  
      *             if meta-annotations can't be found
 1387  
      */
 1388  
     protected boolean isPrimary(AnnotationHolder annotation) throws ResourceNotFoundException
 1389  
     {
 1390  0
         return annotation.getMetaAnnotations().keySet().contains(Primary.class.getCanonicalName());
 1391  
     }
 1392  
 
 1393  
     /**
 1394  
      * Checks if a given set of access flags matches a static member.
 1395  
      * 
 1396  
      * @param accessFlags
 1397  
      *            the members access flags
 1398  
      * @return T if it's a private member, F otherwise
 1399  
      */
 1400  
     private boolean isPrivate(int accessFlags)
 1401  
     {
 1402  0
         if ((accessFlags & 2) == 2)
 1403  0
             return true;
 1404  
         else
 1405  0
             return false;
 1406  
     }
 1407  
 
 1408  
     /**
 1409  
      * Checks if a given set of access flags matches a static member.
 1410  
      * 
 1411  
      * @param accessFlags
 1412  
      *            the member's access flags
 1413  
      * @return T if it's a static member, F otherwise
 1414  
      */
 1415  
     private boolean isStatic(int accessFlags)
 1416  
     {
 1417  
         // 8 is the static flag on the JVM. See the JVM Specs for more info.
 1418  0
         if ((accessFlags & 8) == 8)
 1419  0
             return true;
 1420  
         else
 1421  0
             return false;
 1422  
     }
 1423  
 
 1424  
     /**
 1425  
      * Prepares the exception context from the attribute.
 1426  
      * 
 1427  
      * @param attribute
 1428  
      *            the class object
 1429  
      * @return the exception context
 1430  
      */
 1431  
     protected Map<String, Object> prepareExceptionContext(AttributeHolder attribute)
 1432  
     {
 1433  
         // Set exception context
 1434  0
         Map<String, Object> exceptionContext = new HashMap<String, Object>();
 1435  
 
 1436  0
         exceptionContext.put(AnnotationMisuseException.ContextKeys.ANNOTATION_SCOPE,
 1437  0
                 IncompatiblePrimaryAnnotationsException.ATTRIBUTE_SCOPE);
 1438  0
         exceptionContext.put(AnnotationMisuseException.ContextKeys.CLASS, attribute.getParentClassName());
 1439  0
         exceptionContext.put(AnnotationMisuseException.ContextKeys.METHOD, attribute.getName());
 1440  
 
 1441  
         try
 1442  
         {
 1443  
 
 1444  0
             List<String> annotationsFound = new ArrayList<String>();
 1445  
 
 1446  0
             for (AnnotationHolder annotation: attribute.getAnnotations().values())
 1447  
             {
 1448  0
                 if (annotation.getMetaAnnotations().containsKey(Primary.class.getCanonicalName()))
 1449  
                 {
 1450  0
                     annotationsFound.add(annotation.getName());
 1451  
                 }
 1452  
             }
 1453  
 
 1454  0
             exceptionContext.put(AnnotationMisuseException.ContextKeys.ANNOTATIONS_FOUND, annotationsFound);
 1455  
 
 1456  
         }
 1457  0
         catch (ResourceNotFoundException resourceNotFoundException)
 1458  
         {
 1459  0
             exceptionContext.put(AnnotationMisuseException.ContextKeys.ANNOTATIONS_FOUND, resourceNotFoundException);
 1460  
         }
 1461  
 
 1462  0
         return exceptionContext;
 1463  
     }
 1464  
 
 1465  
     /**
 1466  
      * Prepares the exception context from the class.
 1467  
      * 
 1468  
      * @param clazz
 1469  
      *            the class object
 1470  
      * @return the exception context
 1471  
      */
 1472  
     protected Map<String, Object> prepareExceptionContext(ClassHolder clazz)
 1473  
     {
 1474  
         // Set exception context
 1475  0
         Map<String, Object> exceptionContext = new HashMap<String, Object>();
 1476  
 
 1477  0
         exceptionContext.put(AnnotationMisuseException.ContextKeys.ANNOTATION_SCOPE,
 1478  0
                 IncompatiblePrimaryAnnotationsException.CLASS_SCOPE);
 1479  0
         exceptionContext.put(AnnotationMisuseException.ContextKeys.CLASS, clazz.getFQName());
 1480  
 
 1481  
         try
 1482  
         {
 1483  
 
 1484  0
             List<String> annotationsFound = new ArrayList<String>();
 1485  
 
 1486  0
             for (AnnotationHolder annotation: clazz.getAnnotations().values())
 1487  
             {
 1488  0
                 if (annotation.getMetaAnnotations().containsKey(Primary.class.getCanonicalName()))
 1489  
                 {
 1490  0
                     annotationsFound.add(annotation.getName());
 1491  
                 }
 1492  
             }
 1493  
 
 1494  0
             exceptionContext.put(AnnotationMisuseException.ContextKeys.ANNOTATIONS_FOUND, annotationsFound);
 1495  
 
 1496  
         }
 1497  0
         catch (ResourceNotFoundException resourceNotFoundException)
 1498  
         {
 1499  0
             exceptionContext.put(AnnotationMisuseException.ContextKeys.ANNOTATIONS_FOUND, resourceNotFoundException);
 1500  
         }
 1501  
 
 1502  0
         return exceptionContext;
 1503  
     }
 1504  
 
 1505  
     /**
 1506  
      * Prepares the exception context from the method.
 1507  
      * 
 1508  
      * @param method
 1509  
      *            the class object
 1510  
      * @return the exception context
 1511  
      */
 1512  
     protected Map<String, Object> prepareExceptionContext(MethodHolder method)
 1513  
     {
 1514  
         // Set exception context
 1515  0
         Map<String, Object> exceptionContext = new HashMap<String, Object>();
 1516  
 
 1517  0
         exceptionContext.put(AnnotationMisuseException.ContextKeys.ANNOTATION_SCOPE,
 1518  0
                 IncompatiblePrimaryAnnotationsException.METHOD_SCOPE);
 1519  0
         exceptionContext.put(AnnotationMisuseException.ContextKeys.CLASS, method.getParentClassName());
 1520  0
         exceptionContext.put(AnnotationMisuseException.ContextKeys.METHOD, method.getName());
 1521  
 
 1522  
         try
 1523  
         {
 1524  
 
 1525  0
             List<String> annotationsFound = new ArrayList<String>();
 1526  
 
 1527  0
             for (AnnotationHolder annotation: method.getAnnotations().values())
 1528  
             {
 1529  0
                 if (annotation.getMetaAnnotations().containsKey(Primary.class.getCanonicalName()))
 1530  
                 {
 1531  0
                     annotationsFound.add(annotation.getName());
 1532  
                 }
 1533  
             }
 1534  
 
 1535  0
             exceptionContext.put(AnnotationMisuseException.ContextKeys.ANNOTATIONS_FOUND, annotationsFound);
 1536  
 
 1537  
         }
 1538  0
         catch (ResourceNotFoundException resourceNotFoundException)
 1539  
         {
 1540  0
             exceptionContext.put(AnnotationMisuseException.ContextKeys.ANNOTATIONS_FOUND, resourceNotFoundException);
 1541  
         }
 1542  
 
 1543  0
         return exceptionContext;
 1544  
     }
 1545  
 
 1546  
     /**
 1547  
      * Sets the annotationName value.
 1548  
      * 
 1549  
      * @param newAnnotation
 1550  
      *            the new annotationName value
 1551  
      */
 1552  
     public void setAnnotation(String newAnnotation)
 1553  
     {
 1554  0
         this.annotationName = newAnnotation;
 1555  0
     }
 1556  
 
 1557  
     /**
 1558  
      * Validates if the entities referred on the annotation parameters are valid on the DEM context.
 1559  
      * 
 1560  
      * @param annotationName
 1561  
      *            the name of the annotation to validate
 1562  
      * @param clazz
 1563  
      *            the class holder
 1564  
      * @throws ResourceNotFoundException
 1565  
      *             if any resource needed for the validation can't be found
 1566  
      */
 1567  
     protected void validateDEMConsistency(String annotationName, ClassHolder clazz) throws ResourceNotFoundException
 1568  
     {
 1569  
 
 1570  
         // Fetch class annotations
 1571  0
         Map<String, AnnotationHolder> classAnnotations = clazz.getAnnotations();
 1572  
 
 1573  0
         AnnotationHolder theAnnotation = null;
 1574  
 
 1575  
         // @ApplicationDefinition annotation
 1576  0
         if (ApplicationDefinition.class.getCanonicalName().contains(annotationName)
 1577  0
                 && classAnnotations.containsKey(ApplicationDefinition.class.getCanonicalName()))
 1578  
         {
 1579  
 
 1580  0
             theAnnotation = classAnnotations.get(ApplicationDefinition.class.getCanonicalName());
 1581  
 
 1582  0
             String provider = theAnnotation.getMembers().get(PROVIDER_ATTRIBUTE_NAME).toString();
 1583  
 
 1584  0
             if (DEMLoaderEntityRegistry.getProvider(provider.toLowerCase()) == null)
 1585  0
                 warnOfEnityMisuseOnClass(clazz.getFQName(), provider);
 1586  
         }
 1587  
         // @ServiceDefinition annotation
 1588  0
         else if (ServiceDefinition.class.getCanonicalName().contains(annotationName)
 1589  0
                 && classAnnotations.containsKey(ServiceDefinition.class.getCanonicalName()))
 1590  
         {
 1591  0
             theAnnotation = classAnnotations.get(ServiceDefinition.class.getCanonicalName());
 1592  
 
 1593  0
             String application = theAnnotation.getMembers().get(APPLICATION_ATTRIBUTE_NAME).toString();
 1594  
 
 1595  0
             if (DEMLoaderEntityRegistry.getApplication(application.toLowerCase()) == null)
 1596  0
                 warnOfEnityMisuseOnClass(clazz.getFQName(), application);
 1597  
         }
 1598  
         // @StageDefinition annotation
 1599  0
         else if (StageDefinition.class.getCanonicalName().contains(annotationName)
 1600  0
                 && classAnnotations.containsKey(StageDefinition.class.getCanonicalName()))
 1601  
         {
 1602  0
             theAnnotation = classAnnotations.get(StageDefinition.class.getCanonicalName());
 1603  
 
 1604  0
             String service = theAnnotation.getMembers().get(SERVICE_ATTRIBUTE_NAME).toString();
 1605  
 
 1606  0
             if (DEMLoaderEntityRegistry.getService(service.toLowerCase()) == null)
 1607  0
                 warnOfEnityMisuseOnClass(clazz.getFQName(), service);
 1608  
         }
 1609  0
     }
 1610  
 
 1611  
     /**
 1612  
      * Validates if a given class message file exists. Only works if DiF is in DEBUG mode.
 1613  
      * 
 1614  
      * @param clazz
 1615  
      *            the class to validate the messages *
 1616  
      * @throws ResourceNotFoundException
 1617  
      *             if any resource needed for the validation can't be found
 1618  
      */
 1619  
     protected void validateMessages(ClassHolder clazz) throws ResourceNotFoundException
 1620  
     {
 1621  
 
 1622  
         // If DiF's in DEBUG...
 1623  0
         if (LogLevel.DEBUG.equals(DIFStartupConfiguration.getLogLevel()))
 1624  
         {
 1625  
 
 1626  0
             Entity entityType = null;
 1627  0
             String parentID = null;
 1628  
 
 1629  0
             Map<String, AnnotationHolder> annotations = clazz.getAnnotations();
 1630  
 
 1631  
             // @ProviderDefinition annotation (does not have a parent, parentID will be null)
 1632  0
             if (annotations.containsKey(ProviderDefinition.class.getCanonicalName()))
 1633  
             {
 1634  0
                 entityType = Entity.PROVIDER;
 1635  
             }
 1636  
             // @ApplicationDefinition annotation
 1637  0
             else if (annotations.containsKey(ApplicationDefinition.class.getCanonicalName()))
 1638  
             {
 1639  0
                 entityType = Entity.APPLICATION;
 1640  0
                 parentID = annotations.get(ApplicationDefinition.class.getCanonicalName()).getMembers()
 1641  0
                         .get(PROVIDER_ATTRIBUTE_NAME).getManagedAnnotationValue().toString();
 1642  
             }
 1643  
             // @ServiceDefinition annotation
 1644  0
             else if (annotations.containsKey(ServiceDefinition.class.getCanonicalName()))
 1645  
             {
 1646  0
                 entityType = Entity.SERVICE;
 1647  0
                 parentID = annotations.get(ServiceDefinition.class.getCanonicalName()).getMembers()
 1648  0
                         .get(APPLICATION_ATTRIBUTE_NAME).getManagedAnnotationValue().toString();
 1649  
             }
 1650  
             // @StageDefinition annotation
 1651  0
             else if (annotations.containsKey(StageDefinition.class.getCanonicalName()))
 1652  
             {
 1653  0
                 entityType = Entity.STAGE;
 1654  0
                 parentID = annotations.get(StageDefinition.class.getCanonicalName()).getMembers()
 1655  0
                         .get(SERVICE_ATTRIBUTE_NAME).getManagedAnnotationValue().toString();
 1656  
 
 1657  
             }
 1658  
 
 1659  
             // Remove the leading and trailing quotation marks
 1660  0
             if (parentID != null)
 1661  0
                 parentID = parentID.substring(1, parentID.length() - 1);
 1662  
 
 1663  
             // Get the message manager...
 1664  0
             IMessageManager messageManager = DIFIoCRegistry.getRegistry().getImplementation(IMessageManager.class);
 1665  
 
 1666  
             // ...fetch messages for this class from the message manager
 1667  0
             MessageList messages = messageManager.collectEntityMessagesFromRepository(entityType, clazz.generateID(),
 1668  0
                     clazz.getFQName(), parentID);
 1669  
 
 1670  
             // If there are no messages, warn user..
 1671  0
             if (messages == null || messages.getMessageIDs().size() == 0)
 1672  
             {
 1673  0
                 UsageIssuesManagerImpl.getInstance().addIssue(IssueType.WARN, IssueScope.LOADTIME, clazz.getFQName(),
 1674  0
                         "Missing messages file!", null);
 1675  
             }
 1676  
         }
 1677  0
     }
 1678  
 
 1679  
     /**
 1680  
      * Validates that the attribute is non-private.
 1681  
      * 
 1682  
      * @param attribute
 1683  
      *            the attribute to validate
 1684  
      * @return T if the attribute is non-private, F otherwise
 1685  
      */
 1686  
     protected boolean validateNonPrivate(AttributeHolder attribute)
 1687  
     {
 1688  
 
 1689  
         // Should only validate DEM annotations
 1690  0
         if (isDEMAnnotation())
 1691  
         {
 1692  0
             int accessFlags = attribute.getManagedAttribute().getModifiers();
 1693  
 
 1694  0
             if (isPrivate(accessFlags))
 1695  0
                 return false;
 1696  
             else
 1697  0
                 return true;
 1698  
 
 1699  
         }
 1700  
         else
 1701  0
             return true;
 1702  
     }
 1703  
 
 1704  
     /**
 1705  
      * Validates the use of primary annotations on a given attribute.
 1706  
      * 
 1707  
      * @param attribute
 1708  
      *            the attribute to search for primary annotations
 1709  
      * @throws AnnotationMisuseException
 1710  
      *             if an annotation is misused
 1711  
      * @throws ResourceNotFoundException
 1712  
      *             if any resource needed for validation could not be found.
 1713  
      */
 1714  
     protected void validatePrimary(AttributeHolder attribute) throws AnnotationMisuseException,
 1715  
             ResourceNotFoundException
 1716  
     {
 1717  
         // If this annotation is primary...
 1718  0
         if (this.isPrimary())
 1719  
         {
 1720  
 
 1721  
             // Find the FQN for the current annotation
 1722  0
             Set<String> annotationNames = attribute.getAnnotations().keySet();
 1723  
 
 1724  0
             String thisAnnotationFQN = null;
 1725  
 
 1726  0
             for (String annotationName: annotationNames)
 1727  
             {
 1728  0
                 if (annotationName.contains(this.annotationName))
 1729  
                 {
 1730  0
                     thisAnnotationFQN = annotationName;
 1731  0
                     break;
 1732  
                 }
 1733  
             }
 1734  
 
 1735  
             // Fetch instance of current annotation
 1736  0
             AnnotationHolder thisAnnotation = new AnnotationHolder(attribute, attribute.getAnnotations()
 1737  0
                     .get(thisAnnotationFQN).getManagedAnnotation());
 1738  
 
 1739  
             // Get all the method's annotations...
 1740  0
             for (AnnotationHolder annotation: attribute.getAnnotations().values())
 1741  
             {
 1742  
                 // Check use with the the present annotation
 1743  0
                 if (!checkUseWith(annotation, thisAnnotation))
 1744  
                     // If annotation is misused throw an exception
 1745  0
                     throw new IncompatiblePrimaryAnnotationsException(
 1746  0
                             IncompatiblePrimaryAnnotationsException.INCOMPATIBLE_PRIMARY_ANNOTATIONS_MESSAGE,
 1747  0
                             prepareExceptionContext(attribute));
 1748  
             }
 1749  
         }
 1750  0
     }
 1751  
 
 1752  
     /**
 1753  
      * Validates the use of primary annotations on a given class.
 1754  
      * 
 1755  
      * @param clazz
 1756  
      *            the class to search for primary annotations
 1757  
      * @throws AnnotationMisuseException
 1758  
      *             if an annotation is misused
 1759  
      * @throws ResourceNotFoundException
 1760  
      *             if any resource needed for validation could not be found.
 1761  
      */
 1762  
     protected void validatePrimary(ClassHolder clazz) throws AnnotationMisuseException, ResourceNotFoundException
 1763  
     {
 1764  
         // If this annotation is primary...
 1765  0
         if (this.isPrimary())
 1766  
         {
 1767  
 
 1768  
             // Find the FQN for the current annotation
 1769  0
             Set<String> annotationNames = clazz.getAnnotations().keySet();
 1770  
 
 1771  0
             String thisAnnotationFQN = null;
 1772  
 
 1773  0
             for (String annotationName: annotationNames)
 1774  
             {
 1775  0
                 if (annotationName.contains(this.annotationName))
 1776  
                 {
 1777  0
                     thisAnnotationFQN = annotationName;
 1778  0
                     break;
 1779  
                 }
 1780  
             }
 1781  
 
 1782  
             // Fetch instance of current annotation
 1783  0
             AnnotationHolder thisAnnotation = new AnnotationHolder(clazz, clazz.getAnnotations().get(thisAnnotationFQN)
 1784  0
                     .getManagedAnnotation());
 1785  
 
 1786  0
             for (AnnotationHolder annotation: clazz.getAnnotations().values())
 1787  
             {
 1788  
                 // Check use with the the present annotation
 1789  0
                 if (!checkUseWith(annotation, thisAnnotation))
 1790  
                     // If annotation is misused throw an exception
 1791  0
                     throw new IncompatiblePrimaryAnnotationsException(
 1792  0
                             IncompatiblePrimaryAnnotationsException.INCOMPATIBLE_PRIMARY_ANNOTATIONS_MESSAGE,
 1793  0
                             prepareExceptionContext(clazz));
 1794  
             }
 1795  
         }
 1796  0
     }
 1797  
 
 1798  
     /**
 1799  
      * Validates the use of primary annotations on a given method.
 1800  
      * 
 1801  
      * @param method
 1802  
      *            the method to search for primary annotations
 1803  
      * @throws AnnotationMisuseException
 1804  
      *             if an annotation is misused
 1805  
      * @throws ResourceNotFoundException
 1806  
      *             if any resource needed for validation could not be found.
 1807  
      */
 1808  
     protected void validatePrimary(MethodHolder method) throws AnnotationMisuseException, ResourceNotFoundException
 1809  
     {
 1810  
         // If this annotation is primary...
 1811  0
         if (this.isPrimary())
 1812  
         {
 1813  
 
 1814  
             // Find the FQN for the current annotation
 1815  0
             Set<String> annotationNames = method.getAnnotations().keySet();
 1816  
 
 1817  0
             String thisAnnotationFQN = null;
 1818  
 
 1819  0
             for (String annotationName: annotationNames)
 1820  
             {
 1821  0
                 if (annotationName.contains(this.annotationName))
 1822  
                 {
 1823  0
                     thisAnnotationFQN = annotationName;
 1824  0
                     break;
 1825  
                 }
 1826  
             }
 1827  
 
 1828  
             // Fetch instance of current annotation
 1829  0
             AnnotationHolder thisAnnotation = new AnnotationHolder(method, method.getAnnotations()
 1830  0
                     .get(thisAnnotationFQN).getManagedAnnotation());
 1831  
 
 1832  
             // Get all the method's annotations...
 1833  0
             for (AnnotationHolder annotation: method.getAnnotations().values())
 1834  
             {
 1835  
                 // Check use with the the present annotation
 1836  0
                 if (!checkUseWith(annotation, thisAnnotation))
 1837  
                     // If annotation is misused throw an exception
 1838  0
                     throw new IncompatiblePrimaryAnnotationsException(
 1839  0
                             IncompatiblePrimaryAnnotationsException.INCOMPATIBLE_PRIMARY_ANNOTATIONS_MESSAGE,
 1840  0
                             prepareExceptionContext(method));
 1841  
             }
 1842  
         }
 1843  0
     }
 1844  
 
 1845  
     /**
 1846  
      * Validates the usage scope of attribute annotations.
 1847  
      * 
 1848  
      * @param annotationName
 1849  
      *            the name of the annotation to validate
 1850  
      * @param attribute
 1851  
      *            the attribute to validate
 1852  
      * @return T if the scope is correct, F otherwise
 1853  
      * @throws ResourceNotFoundException
 1854  
      *             if any resource needed for the validation can't be found
 1855  
      */
 1856  
     protected boolean validateScope(String annotationName, AttributeHolder attribute) throws ResourceNotFoundException
 1857  
     {
 1858  
 
 1859  0
         Map<String, AnnotationHolder> attributeAnnotations = attribute.getAnnotations();
 1860  
 
 1861  
         // @Persist annotation
 1862  0
         if (Persist.class.getCanonicalName().contains(annotationName)
 1863  0
                 && attributeAnnotations.containsKey(Persist.class.getCanonicalName()))
 1864  
         {
 1865  0
             final String SCOPE_ID = "scope";
 1866  
             // Check scope
 1867  0
             if ((attributeAnnotations.get(Persist.class.getCanonicalName())).getMembers().containsKey(SCOPE_ID))
 1868  
             {
 1869  0
                 AnnotationMemberValueHolder scope = attributeAnnotations.get(Persist.class.getName()).getMembers()
 1870  0
                         .get(SCOPE_ID);
 1871  0
                 MemberValue scopeValue = scope.getManagedAnnotationValue();
 1872  
 
 1873  0
                 if (scopeValue.toString().contains(ParameterScope.STATIC.toString())
 1874  0
                         && !isStatic(attribute.getManagedAttribute().getModifiers()))
 1875  
                 {
 1876  0
                     UsageIssuesManagerImpl.getInstance().addIssue(
 1877  0
                             IssueType.WARN,
 1878  0
                             IssueScope.LOADTIME,
 1879  0
                             attribute.getParentClassName(),
 1880  0
                             "Using @" + Persist.class.getSimpleName() + " scope " + ParameterScope.STATIC
 1881  0
                                     + " on non-static attribute: " + attribute.getName(), null);
 1882  0
                     return false;
 1883  
                 }
 1884  
             }
 1885  
         }
 1886  0
         else if (FormConfigurable.class.getCanonicalName().contains(annotationName)
 1887  0
                 && attributeAnnotations.containsKey(FormConfigurable.class.getCanonicalName()))
 1888  
         {
 1889  0
             final String LINKED_FORM_ID = "linkToForm";
 1890  
 
 1891  
             // Check linkedToForm
 1892  0
             AnnotationMemberValueHolder linkedToForm = null;
 1893  0
             AnnotationHolder parameterAnnotation = attributeAnnotations.get(Parameter.class.getName());
 1894  0
             if (parameterAnnotation != null)
 1895  0
                 linkedToForm = parameterAnnotation.getMembers().get(LINKED_FORM_ID);
 1896  
 
 1897  0
             if (linkedToForm == null)
 1898  
             {
 1899  0
                 UsageIssuesManagerImpl.getInstance().addIssue(
 1900  0
                         IssueType.WARN,
 1901  0
                         IssueScope.LOADTIME,
 1902  0
                         attribute.getParentClassName(),
 1903  0
                         "Using @" + FormConfigurable.class.getSimpleName() + " for attribute: " + attribute.getName()
 1904  0
                                 + ", that does not have a @" + Parameter.class.getSimpleName() + " with the "
 1905  0
                                 + LINKED_FORM_ID + " attribute defined", null);
 1906  0
                 return false;
 1907  
             }
 1908  
         }
 1909  
 
 1910  0
         return true;
 1911  
     }
 1912  
 
 1913  
     /**
 1914  
      * Defines specific rules for applying the annotationName on a given attribute. Returns T by default.
 1915  
      * 
 1916  
      * @param attribute
 1917  
      *            the annotated attribute
 1918  
      * @param annotationName
 1919  
      *            the annotationName
 1920  
      * @return T if all conditions are verified, F otherwise
 1921  
      * @throws ResourceNotFoundException
 1922  
      */
 1923  
     protected boolean validateSpecificRules(String annotationName, AttributeHolder attribute)
 1924  
             throws ResourceNotFoundException
 1925  
     {
 1926  
         // TODO: Uncomment after bug #9863
 1927  
         // validateViewExistence(attribute.getName(), attribute.getParentClassName(), attribute.getAnnotations());
 1928  0
         return true;
 1929  
     }
 1930  
 
 1931  
     /**
 1932  
      * Defines specific rules for applying the annotationName on a given class. Returns T by default.
 1933  
      * 
 1934  
      * @param annotationName
 1935  
      *            the annotationName
 1936  
      * @param clazz
 1937  
      *            the annotated class
 1938  
      * @return T if all conditions are verified, F otherwise
 1939  
      * @throws ResourceNotFoundException
 1940  
      *             if any needed resource for validation is not found
 1941  
      */
 1942  
     protected boolean validateSpecificRules(String annotationName, ClassHolder clazz) throws ResourceNotFoundException
 1943  
     {
 1944  
         // TODO: Uncomment after bug #9863
 1945  
         // validateViewExistence(null, clazz.getFQName(), clazz.getAnnotations());
 1946  
 
 1947  0
         if (annotationName.equals(ProviderDefinition.class.getSimpleName())
 1948  0
                 || annotationName.equals(ApplicationDefinition.class.getSimpleName())
 1949  0
                 || annotationName.equals(ServiceDefinition.class.getSimpleName())
 1950  0
                 || annotationName.equals(StageDefinition.class.getSimpleName()))
 1951  
         {
 1952  0
             validateMessages(clazz);
 1953  
         }
 1954  
 
 1955  0
         return true;
 1956  
     }
 1957  
 
 1958  
     /**
 1959  
      * Defines specific rules for applying the annotationName on a given method. Returns T by default.
 1960  
      * 
 1961  
      * @param method
 1962  
      *            the annotated method
 1963  
      * @param annotationName
 1964  
      *            the annotationName
 1965  
      * @return T if all conditions are verified, F otherwise
 1966  
      * @throws ResourceNotFoundException
 1967  
      */
 1968  
     protected boolean validateSpecificRules(String annotationName, MethodHolder method)
 1969  
             throws ResourceNotFoundException
 1970  
     {
 1971  0
         return true;
 1972  
     }
 1973  
 
 1974  
     /**
 1975  
      * Validates the use of the annotation on a given attribute. Validation includes checking if multiple primary
 1976  
      * annotations are used, if the scope is correct, if the annotation members provide information consistent with the
 1977  
      * DEM and if any other specific rules apply.
 1978  
      * 
 1979  
      * @param attribute
 1980  
      *            the attribute on which the annotationName is used
 1981  
      * @throws AnnotationMisuseException
 1982  
      *             if an inappropriate annotation usage was made
 1983  
      * @throws ResourceNotFoundException
 1984  
      *             if any resource needed for the validation can't be found
 1985  
      */
 1986  
     final public void validateUsage(AttributeHolder attribute) throws AnnotationMisuseException,
 1987  
             ResourceNotFoundException
 1988  
     {
 1989  0
         if (!validateNonPrivate(attribute))
 1990  
         {
 1991  0
             throw new IllegalAnnotationUsage("Annotated attribute " + attribute.getName() + " on class "
 1992  0
                     + attribute.getParentClassName()
 1993  0
                     + " is private! (Annotations can only be applied on non-private members)",
 1994  0
                     prepareExceptionContext(attribute));
 1995  
         }
 1996  0
         validatePrimary(attribute);
 1997  0
         validateScope(annotationName, attribute);
 1998  0
         validateSpecificRules(annotationName, attribute);
 1999  0
     }
 2000  
 
 2001  
     /**
 2002  
      * Validates the use of the annotation on a given class. Validation includes checking if multiple primary
 2003  
      * annotations are used, if the scope is correct, if the annotation members provide information consistent with the
 2004  
      * DEM and if any other specific rules apply.
 2005  
      * 
 2006  
      * @param clazz
 2007  
      *            the class on which the annotation is used
 2008  
      * @throws AnnotationMisuseException
 2009  
      *             if an inappropriate annotation usage was made
 2010  
      * @throws ResourceNotFoundException
 2011  
      *             if any resource needed for the validation can't be found
 2012  
      */
 2013  
     final public void validateUsage(ClassHolder clazz) throws AnnotationMisuseException, ResourceNotFoundException
 2014  
     {
 2015  0
         validatePrimary(clazz);
 2016  
         // validateScope(clazz);
 2017  0
         validateDEMConsistency(annotationName, clazz);
 2018  0
         validateSpecificRules(annotationName, clazz);
 2019  0
     }
 2020  
 
 2021  
     /**
 2022  
      * Validates the use of the annotation on a given method. Validation includes checking if multiple primary
 2023  
      * annotations are used, if the scope is correct and if any other specific rules apply.
 2024  
      * 
 2025  
      * @param method
 2026  
      *            the method on which the annotation is used
 2027  
      * @throws AnnotationMisuseException
 2028  
      *             if an inappropriate annotation usage was made
 2029  
      * @throws ResourceNotFoundException
 2030  
      *             if any resource needed for the validation can't be found
 2031  
      */
 2032  
     final public void validateUsage(MethodHolder method) throws AnnotationMisuseException, ResourceNotFoundException
 2033  
     {
 2034  0
         validatePrimary(method);
 2035  
         // validateScope(method);
 2036  0
         validateSpecificRules(annotationName, method);
 2037  0
     }
 2038  
 
 2039  
     /**
 2040  
      * Checks if the received set of annotations contains the
 2041  
      * 
 2042  
      * @View annotation and if the referenced view exists. Logs a warning if the view doesn't exist.
 2043  
      * @param attributeName
 2044  
      *            the name of the annotated attribute if it exists
 2045  
      * @param className
 2046  
      *            the name of the annotated class or the attribute's class name
 2047  
      * @param annotations
 2048  
      *            the annotation set to validate
 2049  
      * @throws ResourceNotFoundException
 2050  
      *             if any resource needed for the validation can't be found
 2051  
      */
 2052  
     protected void validateViewExistence(String attributeName, String className,
 2053  
             Map<String, AnnotationHolder> annotations) throws ResourceNotFoundException
 2054  
     {
 2055  0
         AnnotationHolder theAnnotation = null;
 2056  
 
 2057  0
         if (View.class.getCanonicalName().contains(annotationName)
 2058  0
                 && annotations.containsKey(View.class.getCanonicalName()))
 2059  
         {
 2060  0
             theAnnotation = annotations.get(View.class.getCanonicalName());
 2061  
 
 2062  0
             String target = theAnnotation.getMembers().get(TARGET_ATTRIBUTE_NAME).toString();
 2063  
 
 2064  0
             URL view = this.getClass().getClassLoader().getResource(target);
 2065  
 
 2066  0
             if (view == null)
 2067  
             {
 2068  0
                 if (attributeName != null)
 2069  
                 {
 2070  0
                     UsageIssuesManagerImpl.getInstance().addIssue(IssueType.WARN, IssueScope.LOADTIME, className,
 2071  0
                             "Attribute " + attributeName + " refers to inexistant view: " + target, null);
 2072  
                 }
 2073  
                 else
 2074  0
                     UsageIssuesManagerImpl.getInstance().addIssue(IssueType.WARN, IssueScope.LOADTIME, className,
 2075  0
                             "Class refers to inexistant view: " + target, null);
 2076  
             }
 2077  
         }
 2078  0
     }
 2079  
 
 2080  
     /**
 2081  
      * Warns of an entity misuse on a given class.
 2082  
      * 
 2083  
      * @param className
 2084  
      *            the name of the class where the reference is being made
 2085  
      * @param entityName
 2086  
      *            the name of the referred entity
 2087  
      */
 2088  
     protected void warnOfEnityMisuseOnClass(String className, String entityName)
 2089  
     {
 2090  0
         UsageIssuesManagerImpl.getInstance().addIssue(IssueType.WARN, IssueScope.LOADTIME, className,
 2091  0
                 "Class refers to an inexistant DEM entity: " + entityName, null);
 2092  0
     }
 2093  
 
 2094  
     /**
 2095  
      * Checks if a given primary annotation has the 'yieldTo' member value and if it contains a given annotation name.
 2096  
      * 
 2097  
      * @param annotation
 2098  
      *            the primary annotation to check
 2099  
      * @param yieldToAnnotationName
 2100  
      *            the name on the 'yieldTo' value
 2101  
      * @return T if the primary annotation yields to the passed name, F otherwise
 2102  
      */
 2103  
     protected boolean yieldsTo(AnnotationHolder annotation, String yieldToAnnotationName)
 2104  
     {
 2105  
 
 2106  
         try
 2107  
         {
 2108  0
             AnnotationHolder primaryMetaAnnotation = annotation.getMetaAnnotations().get(
 2109  0
                     Primary.class.getCanonicalName());
 2110  
 
 2111  0
             if (primaryMetaAnnotation.getMembers().get(MetaAnnotationMemberTags.PRIMARY_YIELD_TO).toString()
 2112  0
                     .contains(yieldToAnnotationName))
 2113  
             {
 2114  0
                 return true;
 2115  
             }
 2116  
 
 2117  
         }
 2118  0
         catch (ResourceNotFoundException resourceNotFoundException)
 2119  
         {
 2120  
 
 2121  
         }
 2122  
 
 2123  0
         return false;
 2124  
     }
 2125  
 }