Coverage Report - pt.digitalis.dif.codegen.DIFCodeGenerator
 
Classes in this File Line Coverage Branch Coverage Complexity
DIFCodeGenerator
0%
0/82
0%
0/34
5,2
 
 1  0
 /**
 2  
  * - Digitalis Internal Framework v2.0 - (C) 2007, Digitalis Informatica. Distribuicao e Gestao de Informatica, Lda.
 3  
  * Estrada de Paco de Arcos num.9 - Piso -1 2780-666 Paco de Arcos Telefone: (351) 21 4408990 Fax: (351) 21 4408999
 4  
  * http://www.digitalis.pt
 5  
  */
 6  
 package pt.digitalis.dif.codegen;
 7  
 
 8  
 import java.util.ArrayList;
 9  
 import java.util.List;
 10  
 import java.util.Map;
 11  
 import java.util.Map.Entry;
 12  
 
 13  
 import pt.digitalis.dif.codegen.util.DEMLoaderEntityRegistry;
 14  
 import pt.digitalis.dif.codegen.util.DEMLoaderHelper;
 15  
 import pt.digitalis.dif.codegen.util.IClassEnhancer;
 16  
 import pt.digitalis.dif.dem.DEMRegistryImpl;
 17  
 import pt.digitalis.dif.dem.Entity;
 18  
 import pt.digitalis.dif.dem.annotations.AnnotationMemberTags;
 19  
 import pt.digitalis.dif.dem.annotations.entities.ApplicationDefinition;
 20  
 import pt.digitalis.dif.dem.annotations.entities.ServiceDefinition;
 21  
 import pt.digitalis.dif.dem.annotations.entities.StageDefinition;
 22  
 import pt.digitalis.dif.dem.config.IDEMRegistrator;
 23  
 import pt.digitalis.dif.dem.config.IEntityRegistration;
 24  
 import pt.digitalis.dif.dem.managers.impl.UsageIssuesManagerImpl;
 25  
 import pt.digitalis.dif.dem.objects.issues.IssueScope;
 26  
 import pt.digitalis.dif.dem.objects.issues.IssueType;
 27  
 import pt.digitalis.dif.exception.codegen.AnnotationMisuseException;
 28  
 import pt.digitalis.dif.exception.codegen.DIFCodeGenerationException;
 29  
 import pt.digitalis.dif.ioc.DIFIoCRegistry;
 30  
 import pt.digitalis.dif.utils.logging.DIFLogger;
 31  
 import pt.digitalis.utils.bytecode.exceptions.CodeGenerationException;
 32  
 import pt.digitalis.utils.bytecode.holders.AnnotationHolder;
 33  
 import pt.digitalis.utils.bytecode.holders.ClassHolder;
 34  
 import pt.digitalis.utils.bytecode.holders.HolderRepository;
 35  
 import pt.digitalis.utils.inspection.exception.ResourceNotFoundException;
 36  
 
 37  
 import com.google.inject.Inject;
 38  
 
 39  
 /**
 40  
  * The framework's main code generation facility. It is an utility class that is called by the frameworks initialization
 41  
  * procedure
 42  
  * 
 43  
  * @author Pedro Viegas <a href="mailto:pviegas@digitalis.pt">pviegas@digitalis.pt</a>
 44  
  * @author Rodrigo Gonçalves <a href="mailto:rgoncalves@digitalis.pt">rgoncalves@digitalis.pt</a>
 45  
  * @created Jul 23, 2007
 46  
  */
 47  0
 public class DIFCodeGenerator {
 48  
 
 49  
     /** The class enhancer */
 50  
     @Inject
 51  
     private IClassEnhancer classEnhancer;
 52  
 
 53  
     /** The package registrator */
 54  
     @Inject
 55  
     private IDEMRegistrator demRegistrator;
 56  
 
 57  
     /**
 58  
      * Performs cleanup operations.
 59  
      */
 60  
     public void cleanUp()
 61  
     {
 62  
         // Perform memory cleanup
 63  0
         DEMLoaderEntityRegistry.cleanUp();
 64  0
         DEMLoaderHelper.cleanUp();
 65  0
         HolderRepository.cleanUp();
 66  
 
 67  
         /*
 68  
          * TODO: After these cleanups, some containers are set to null and not reinitialized again. This might originate
 69  
          * NullPointerExceptions. The unit tests might not run properly. If such a situation arises it will be
 70  
          * appropriated to move these clean-up operations to a separate method that will be called explicitly by the
 71  
          * developer.
 72  
          */
 73  0
     }
 74  
 
 75  
     /**
 76  
      * Collects all contributed package registrations in the registry
 77  
      * 
 78  
      * @throws ResourceNotFoundException
 79  
      *             if it can't get no classes to enhancement
 80  
      * @throws CodeGenerationException
 81  
      *             if a class can't be enhanced
 82  
      */
 83  
     public void collectRegisteredPackages() throws ResourceNotFoundException, CodeGenerationException
 84  
     {
 85  
 
 86  
         // Get all contributed implementation of the EntityRegistration class
 87  0
         List<IEntityRegistration> entityRegistrators = DIFIoCRegistry.getRegistry().getImplementations(
 88  0
                 IEntityRegistration.class);
 89  
 
 90  
         // ...and run them
 91  0
         for (IEntityRegistration entityRegistration: entityRegistrators)
 92  0
             entityRegistration.registerEntitys(demRegistrator);
 93  0
     }
 94  
 
 95  
     /**
 96  
      * Searches all registered packages for DEM entities and performs the Class enhance operations.
 97  
      * 
 98  
      * @throws CodeGenerationException
 99  
      *             if a class can't be enhanced
 100  
      * @throws ResourceNotFoundException
 101  
      *             if it can't get no classes to enhancement
 102  
      * @throws DIFCodeGenerationException
 103  
      */
 104  
     public void enhanceDEMClasses() throws CodeGenerationException, ResourceNotFoundException,
 105  
             DIFCodeGenerationException
 106  
     {
 107  
 
 108  0
         List<String> stagesToRemove = new ArrayList<String>();
 109  0
         List<String> servicesToRemove = new ArrayList<String>();
 110  0
         List<String> applicationsToRemove = new ArrayList<String>();
 111  
 
 112  
         /* Remove from Registry the incoherent entities */
 113  0
         for (Entry<String, ClassHolder> entry: DEMLoaderEntityRegistry.getStages().entrySet())
 114  
         {
 115  0
             String stageID = entry.getKey();
 116  0
             ClassHolder clazz = entry.getValue();
 117  
 
 118  0
             AnnotationHolder annotationHolder = clazz.getAnnotations().get(StageDefinition.class.getCanonicalName());
 119  0
             String serviceID = annotationHolder.getMembers().get(AnnotationMemberTags.STAGE_DEFINITION_SERVICE)
 120  0
                     .toString();
 121  
 
 122  0
             if (DEMLoaderEntityRegistry.getServices().containsKey(serviceID))
 123  
             {
 124  0
                 clazz = DEMLoaderEntityRegistry.getServices().get(serviceID);
 125  
 
 126  0
                 annotationHolder = clazz.getAnnotations().get(ServiceDefinition.class.getCanonicalName());
 127  0
                 String applicationID = annotationHolder.getMembers()
 128  0
                         .get(AnnotationMemberTags.SERVICE_DEFINITION_APPLICATION).toString();
 129  
 
 130  0
                 if (DEMLoaderEntityRegistry.getApplications().containsKey(applicationID))
 131  
                 {
 132  0
                     clazz = DEMLoaderEntityRegistry.getApplications().get(applicationID);
 133  
 
 134  0
                     annotationHolder = clazz.getAnnotations().get(ApplicationDefinition.class.getCanonicalName());
 135  0
                     String providerID = annotationHolder.getMembers()
 136  0
                             .get(AnnotationMemberTags.APPLICATION_DEFINITION_PROVIDER).toString();
 137  
 
 138  0
                     if (!DEMLoaderEntityRegistry.getProviders().containsKey(providerID))
 139  
                     {
 140  0
                         applicationsToRemove.add(applicationID);
 141  0
                         servicesToRemove.add(serviceID);
 142  0
                         stagesToRemove.add(stageID);
 143  
                     }
 144  
                 }
 145  
                 else
 146  
                 {
 147  0
                     servicesToRemove.add(serviceID);
 148  0
                     stagesToRemove.add(stageID);
 149  
                 }
 150  
             }
 151  
             else
 152  
             {
 153  0
                 stagesToRemove.add(stageID);
 154  
             }
 155  
         }
 156  
 
 157  0
         for (String applicationId: applicationsToRemove)
 158  
         {
 159  0
             DEMLoaderEntityRegistry.getServices().remove(applicationId);
 160  0
             DIFLogger.getLogger().info(
 161  0
                     "The application '" + applicationId + "' has been excluded due to the lack of suitable provider");
 162  
         }
 163  
 
 164  0
         for (String serviceId: servicesToRemove)
 165  
         {
 166  0
             DEMLoaderEntityRegistry.getServices().remove(serviceId);
 167  0
             DIFLogger.getLogger().info(
 168  0
                     "The service '" + serviceId + "' has been excluded due to the lack of suitable application");
 169  
         }
 170  
 
 171  0
         for (String stageId: stagesToRemove)
 172  
         {
 173  0
             DEMLoaderEntityRegistry.getStages().remove(stageId);
 174  0
             DIFLogger.getLogger().info(
 175  0
                     "The stage '" + stageId + "' has been excluded due to the lack of suitable service");
 176  
         }
 177  
 
 178  
         /*
 179  
          * Enhance each entity class. Note that the enhancement order is relevant and respects the DEM hierarchy. Each
 180  
          * class is also added to the respective slot in the DEMRegistry
 181  
          */
 182  
 
 183  0
         enhanceEntities(Entity.VALIDATOR, DEMLoaderEntityRegistry.getValidators());
 184  0
         enhanceEntities(Entity.PROVIDER, DEMLoaderEntityRegistry.getProviders());
 185  0
         enhanceEntities(Entity.APPLICATION, DEMLoaderEntityRegistry.getApplications());
 186  0
         enhanceEntities(Entity.SERVICE, DEMLoaderEntityRegistry.getServices());
 187  0
         enhanceEntities(Entity.STAGE, DEMLoaderEntityRegistry.getStages());
 188  
 
 189  0
     }
 190  
 
 191  
     /**
 192  
      * Performs the bytecode enhancement to the given entity classes
 193  
      * 
 194  
      * @param entityType
 195  
      *            the entity type
 196  
      * @param entityMap
 197  
      *            the map of entities to add
 198  
      * @throws CodeGenerationException
 199  
      *             if a class can't be enhanced
 200  
      * @throws ResourceNotFoundException
 201  
      *             if it can't get no classes to enhancement
 202  
      * @throws DIFCodeGenerationException
 203  
      */
 204  
     private void enhanceEntities(Entity entityType, Map<String, ClassHolder> entityMap) throws CodeGenerationException,
 205  
             ResourceNotFoundException, DIFCodeGenerationException
 206  
     {
 207  
 
 208  
         ClassHolder entityClazz;
 209  
 
 210  0
         if (entityMap != null)
 211  0
             for (ClassHolder clazz: entityMap.values())
 212  
             {
 213  
                 try
 214  
                 {
 215  
 
 216  0
                     entityClazz = classEnhancer.enhance(clazz);
 217  
 
 218  0
                     if (!entityType.equals(Entity.VALIDATOR))
 219  
                     {
 220  0
                         DEMRegistryImpl.addEntity(entityType, entityClazz);
 221  
                     }
 222  
 
 223  
                 }
 224  0
                 catch (AnnotationMisuseException annotationMisuseException)
 225  
                 {
 226  0
                     UsageIssuesManagerImpl.getInstance().addIssue(
 227  0
                             IssueType.ERROR,
 228  0
                             IssueScope.LOADTIME,
 229  0
                             annotationMisuseException.getExceptionContext()
 230  0
                                     .get(AnnotationMisuseException.ContextKeys.CLASS).toString(),
 231  0
                             annotationMisuseException.getMessage(), annotationMisuseException);
 232  
                 }
 233  
             }
 234  0
     }
 235  
 
 236  
     /**
 237  
      * Searches all registered packages for DEM entities and other DIF elements.
 238  
      * 
 239  
      * @throws ResourceNotFoundException
 240  
      *             if it can't get no classes to enhancement
 241  
      * @throws CodeGenerationException
 242  
      *             if a class can't be enhanced
 243  
      */
 244  
     public void searchRegisteredPackages() throws ResourceNotFoundException, CodeGenerationException
 245  
     {
 246  
 
 247  
         /*
 248  
          * Iterate through the DEM-registered folders for annotated classes and separate them by their corresponding
 249  
          * entity types in the DEM load time registry
 250  
          */
 251  0
         for (String packageName: DEMLoaderHelper.getPackageList())
 252  
         {
 253  
 
 254  
             // Get all classes in this folder
 255  0
             List<ClassHolder> classes = new ArrayList<ClassHolder>();
 256  
 
 257  
             try
 258  
             {
 259  0
                 classes = DEMLoaderHelper.getDEMEntityClassesInPackage(packageName);
 260  
 
 261  
             }
 262  0
             catch (ResourceNotFoundException resourceNotFoundException)
 263  
             {
 264  0
                 throw new ResourceNotFoundException("Could not find any classes for enhancement in package "
 265  0
                         + packageName, resourceNotFoundException);
 266  
             }
 267  
 
 268  
             // Load the classes which are entities
 269  
             try
 270  
             {
 271  0
                 DEMLoaderEntityRegistry.loadEntityClasses(classes, demRegistrator);
 272  
             }
 273  0
             catch (ClassNotFoundException e)
 274  
             {
 275  0
                 throw new CodeGenerationException(e);
 276  
             }
 277  0
             catch (InstantiationException e)
 278  
             {
 279  0
                 throw new CodeGenerationException(e);
 280  
             }
 281  0
             catch (IllegalAccessException e)
 282  
             {
 283  0
                 throw new CodeGenerationException(e);
 284  
             }
 285  
         }
 286  0
     }
 287  
 }