Coverage Report - pt.digitalis.dif.codegen.util.DEMLoaderEntityRegistry
 
Classes in this File Line Coverage Branch Coverage Complexity
DEMLoaderEntityRegistry
0%
0/124
0%
0/66
2,345
 
 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.codegen.util;
 7  
 
 8  
 import java.util.List;
 9  
 import java.util.Map;
 10  
 
 11  
 import pt.digitalis.dif.dem.Entity;
 12  
 import pt.digitalis.dif.dem.annotations.AnnotationTags;
 13  
 import pt.digitalis.dif.dem.config.IDEMRegistrator;
 14  
 import pt.digitalis.dif.utils.logging.DIFLogger;
 15  
 import pt.digitalis.utils.bytecode.holders.AnnotationHolder;
 16  
 import pt.digitalis.utils.bytecode.holders.ClassHolder;
 17  
 import pt.digitalis.utils.common.collections.CaseInsensitiveHashMap;
 18  
 import pt.digitalis.utils.inspection.exception.ResourceNotFoundException;
 19  
 
 20  
 /**
 21  
  * A temporary registry of DEM entities that helps the codegen utility to track down all entities on a first pass
 22  
  * 
 23  
  * @author Pedro Viegas <a href="mailto:pviegas@digitalis.pt">pviegas@digitalis.pt</a>
 24  
  * @author Rodrigo Gonçalves <a href="mailto:rgoncalves@digitalis.pt">rgoncalves@digitalis.pt</a>
 25  
  * @created Jul 23, 2007
 26  
  */
 27  0
 final public class DEMLoaderEntityRegistry {
 28  
 
 29  
     /** Map of application IDs and their class objects */
 30  0
     static private Map<String, ClassHolder> applications = new CaseInsensitiveHashMap<ClassHolder>();
 31  
 
 32  
     /** Map of provider IDs and their class objects */
 33  0
     static private Map<String, ClassHolder> providers = new CaseInsensitiveHashMap<ClassHolder>();
 34  
 
 35  
     /** Map of service IDs and their class objects */
 36  0
     static private Map<String, ClassHolder> services = new CaseInsensitiveHashMap<ClassHolder>();
 37  
 
 38  
     /** Map of stage IDs and their class objects */
 39  0
     static private Map<String, ClassHolder> stages = new CaseInsensitiveHashMap<ClassHolder>();
 40  
 
 41  
     /** Map of validator IDs and their class objects */
 42  0
     static private Map<String, ClassHolder> validators = new CaseInsensitiveHashMap<ClassHolder>();
 43  
 
 44  
     /**
 45  
      * Adds a application class to the temp DEM registry
 46  
      * 
 47  
      * @param id
 48  
      *            the ID of the DEM Entity
 49  
      * @param clazz
 50  
      *            the class object that represents the Entity
 51  
      */
 52  
     static public void addApplication(String id, ClassHolder clazz)
 53  
     {
 54  0
         applications.put(id.toLowerCase(), clazz);
 55  0
     }
 56  
 
 57  
     /**
 58  
      * Adds a provider class to the temp DEM registry
 59  
      * 
 60  
      * @param id
 61  
      *            the ID of the DEM Entity
 62  
      * @param clazz
 63  
      *            the class object that represents the Entity
 64  
      */
 65  
     static public void addProvider(String id, ClassHolder clazz)
 66  
     {
 67  0
         providers.put(id.toLowerCase(), clazz);
 68  0
     }
 69  
 
 70  
     /**
 71  
      * Adds a service class to the temp DEM registry
 72  
      * 
 73  
      * @param id
 74  
      *            the ID of the DEM Entity
 75  
      * @param clazz
 76  
      *            the class object that represents the Entity
 77  
      */
 78  
     static public void addService(String id, ClassHolder clazz)
 79  
     {
 80  0
         services.put(id.toLowerCase(), clazz);
 81  0
     }
 82  
 
 83  
     /**
 84  
      * Adds a stage class to the temp DEM registry
 85  
      * 
 86  
      * @param id
 87  
      *            the ID of the DEM Entity
 88  
      * @param clazz
 89  
      *            the class object that represents the Entity
 90  
      */
 91  
     static public void addStage(String id, ClassHolder clazz)
 92  
     {
 93  0
         stages.put(id.toLowerCase(), clazz);
 94  0
     }
 95  
 
 96  
     /**
 97  
      * Adds a validator class to the temp DEM registry
 98  
      * 
 99  
      * @param id
 100  
      *            the ID of the DEM Entity
 101  
      * @param clazz
 102  
      *            the class object that represents the Entity
 103  
      */
 104  
     static public void addValidator(String id, ClassHolder clazz)
 105  
     {
 106  0
         validators.put(id.toLowerCase(), clazz);
 107  0
     }
 108  
 
 109  
     /**
 110  
      * Performs memory clean up by releasing the internal Maps of entities when they are no longer needed. Must be
 111  
      * called since this is a static class with static attributes for temporary data.
 112  
      */
 113  
     static public void cleanUp()
 114  
     {
 115  
 
 116  
         // Detach all classes...
 117  0
         if (providers != null)
 118  0
             for (ClassHolder clazz: providers.values())
 119  0
                 clazz.cleanUp();
 120  
 
 121  0
         if (applications != null)
 122  0
             for (ClassHolder clazz: applications.values())
 123  0
                 clazz.cleanUp();
 124  
 
 125  0
         if (services != null)
 126  0
             for (ClassHolder clazz: services.values())
 127  0
                 clazz.cleanUp();
 128  
 
 129  0
         if (stages != null)
 130  0
             for (ClassHolder clazz: stages.values())
 131  0
                 clazz.cleanUp();
 132  
 
 133  0
         if (validators != null)
 134  0
             for (ClassHolder clazz: validators.values())
 135  0
                 clazz.cleanUp();
 136  
 
 137  0
         providers = new CaseInsensitiveHashMap<ClassHolder>();
 138  0
         applications = new CaseInsensitiveHashMap<ClassHolder>();
 139  0
         services = new CaseInsensitiveHashMap<ClassHolder>();
 140  0
         stages = new CaseInsensitiveHashMap<ClassHolder>();
 141  0
         validators = new CaseInsensitiveHashMap<ClassHolder>();
 142  0
     }
 143  
 
 144  
     /**
 145  
      * Searches the applications for the entry with the given ID
 146  
      * 
 147  
      * @param id
 148  
      *            the ID of the Entity to search
 149  
      * @return the class object of the Entity
 150  
      */
 151  
     static public ClassHolder getApplication(String id)
 152  
     {
 153  0
         if (applications == null)
 154  0
             return null;
 155  
         else
 156  0
             return applications.get(id.toLowerCase());
 157  
     }
 158  
 
 159  
     /**
 160  
      * Returns the registered applications count
 161  
      * 
 162  
      * @return the number of Applications
 163  
      */
 164  
     static public int getApplicationCount()
 165  
     {
 166  0
         return (applications == null) ? 0 : applications.size();
 167  
     }
 168  
 
 169  
     /**
 170  
      * Returns the Map of registered applications with the ID and their class objects
 171  
      * 
 172  
      * @return the Applications Map
 173  
      */
 174  
     static public Map<String, ClassHolder> getApplications()
 175  
     {
 176  0
         return applications;
 177  
     }
 178  
 
 179  
     /**
 180  
      * Returns the total number of entities registered
 181  
      * 
 182  
      * @return the entity count
 183  
      */
 184  
     static public int getEntityCount()
 185  
     {
 186  
 
 187  0
         int entityTotal = 0;
 188  
 
 189  0
         entityTotal += DEMLoaderEntityRegistry.getProviderCount();
 190  0
         entityTotal += DEMLoaderEntityRegistry.getApplicationCount();
 191  0
         entityTotal += DEMLoaderEntityRegistry.getServiceCount();
 192  0
         entityTotal += DEMLoaderEntityRegistry.getStageCount();
 193  0
         entityTotal += DEMLoaderEntityRegistry.getValidatorCount();
 194  
 
 195  0
         return entityTotal;
 196  
     }
 197  
 
 198  
     /**
 199  
      * Searches the providers for the entry with the given ID
 200  
      * 
 201  
      * @param id
 202  
      *            the ID of the Entity to search
 203  
      * @return the class object of the Entity
 204  
      */
 205  
     static public ClassHolder getProvider(String id)
 206  
     {
 207  0
         if (providers == null)
 208  0
             return null;
 209  
         else
 210  0
             return providers.get(id.toLowerCase());
 211  
     }
 212  
 
 213  
     /**
 214  
      * Returns the registered providers count
 215  
      * 
 216  
      * @return the number of Providers
 217  
      */
 218  
     static public int getProviderCount()
 219  
     {
 220  0
         return (providers == null) ? 0 : providers.size();
 221  
     }
 222  
 
 223  
     /**
 224  
      * Returns the Map of registered providers with the ID and their class objects
 225  
      * 
 226  
      * @return the Providers Map
 227  
      */
 228  
     static public Map<String, ClassHolder> getProviders()
 229  
     {
 230  0
         return providers;
 231  
     }
 232  
 
 233  
     /**
 234  
      * Searches the services for the entry with the given ID
 235  
      * 
 236  
      * @param id
 237  
      *            the ID of the Entity to search
 238  
      * @return the class object of the Entity
 239  
      */
 240  
     static public ClassHolder getService(String id)
 241  
     {
 242  0
         if (services == null)
 243  0
             return null;
 244  
         else
 245  0
             return services.get(id.toLowerCase());
 246  
     }
 247  
 
 248  
     /**
 249  
      * Returns the registered services count
 250  
      * 
 251  
      * @return the number of Services
 252  
      */
 253  
     static public int getServiceCount()
 254  
     {
 255  0
         return (services == null) ? 0 : services.size();
 256  
     }
 257  
 
 258  
     /**
 259  
      * Returns the Map of registered services with the ID and their class objects
 260  
      * 
 261  
      * @return the Services Map
 262  
      */
 263  
     static public Map<String, ClassHolder> getServices()
 264  
     {
 265  0
         return services;
 266  
     }
 267  
 
 268  
     /**
 269  
      * Searches the stages for the entry with the given ID
 270  
      * 
 271  
      * @param id
 272  
      *            the ID of the Entity to search
 273  
      * @return the class object of the Entity
 274  
      */
 275  
     static public ClassHolder getStage(String id)
 276  
     {
 277  0
         if (stages == null)
 278  0
             return null;
 279  
         else
 280  0
             return stages.get(id.toLowerCase());
 281  
     }
 282  
 
 283  
     /**
 284  
      * Returns the registered stages count
 285  
      * 
 286  
      * @return the number of Stages
 287  
      */
 288  
     static public int getStageCount()
 289  
     {
 290  0
         return (stages == null) ? 0 : stages.size();
 291  
     }
 292  
 
 293  
     /**
 294  
      * Returns the Map of registered stages with the ID and their class objects
 295  
      * 
 296  
      * @return the Stages Map
 297  
      */
 298  
     static public Map<String, ClassHolder> getStages()
 299  
     {
 300  0
         return stages;
 301  
     }
 302  
 
 303  
     /**
 304  
      * Searches the validators for the entry with the given ID
 305  
      * 
 306  
      * @param id
 307  
      *            the ID of the Entity to search
 308  
      * @return the class object of the Entity
 309  
      */
 310  
     static public ClassHolder getValidator(String id)
 311  
     {
 312  0
         if (validators == null)
 313  0
             return null;
 314  
         else
 315  0
             return validators.get(id.toLowerCase());
 316  
     }
 317  
 
 318  
     /**
 319  
      * Returns the registered validators count
 320  
      * 
 321  
      * @return the number if Validators
 322  
      */
 323  
     static public int getValidatorCount()
 324  
     {
 325  0
         return (validators == null) ? 0 : validators.size();
 326  
     }
 327  
 
 328  
     /**
 329  
      * Returns the Map of registered validators with the ID and their class objects
 330  
      * 
 331  
      * @return the Validators Map
 332  
      */
 333  
     static public Map<String, ClassHolder> getValidators()
 334  
     {
 335  0
         return validators;
 336  
     }
 337  
 
 338  
     /**
 339  
      * Analyzes the given classes to determine witch of them are DEM Entity. It adds them to the corresponding DEM list.
 340  
      * All read operations are executed by Javassist so classes are not loaded by the JVM.
 341  
      * 
 342  
      * @param classes
 343  
      *            the classes to analyze
 344  
      * @param demRegistrator
 345  
      *            the DEM registrator
 346  
      * @throws ResourceNotFoundException
 347  
      *             if any class could not be found or an annotation can't be read
 348  
      * @throws IllegalAccessException
 349  
      * @throws InstantiationException
 350  
      * @throws ClassNotFoundException
 351  
      */
 352  
     static public void loadEntityClasses(List<ClassHolder> classes, IDEMRegistrator demRegistrator)
 353  
             throws ResourceNotFoundException, ClassNotFoundException, InstantiationException, IllegalAccessException
 354  
     {
 355  
 
 356  
         // For all defined classes...
 357  0
         for (ClassHolder clazz: classes)
 358  
         {
 359  
             /*
 360  
              * Treat class according the annotation. Implementation Note: The algorithm just considers the first primary
 361  
              * DEM-Entity Annotation Entity found.
 362  
              */
 363  
 
 364  
             // If it's a @ValidationDefinition
 365  0
             if (clazz.containsAnnotation(Entity.VALIDATOR.getFullyQualifiedName()))
 366  
             {
 367  0
                 if (!demRegistrator.getEntitiesToExclude(Entity.VALIDATOR).contains(
 368  0
                         clazz.getFQName()))
 369  0
                     processValidator(clazz);
 370  
                 else
 371  
                 {
 372  0
                     DIFLogger.getLogger().info(
 373  0
                             "The Validator '" + clazz.getClassInstance().getClass().getCanonicalName()
 374  0
                                     + "' was excluded from load process");
 375  
                 }
 376  
             }
 377  
             // If it's a @ProviderDefinition
 378  0
             else if (clazz.containsAnnotation(Entity.PROVIDER.getFullyQualifiedName()))
 379  
             {
 380  0
                 if (!demRegistrator.getEntitiesToExclude(Entity.PROVIDER).contains(
 381  0
                         clazz.getFQName()))
 382  0
                     processProvider(clazz);
 383  
                 else
 384  
                 {
 385  0
                     DIFLogger.getLogger().info(
 386  0
                             "The Provider '" + clazz.getClassInstance().getClass().getCanonicalName()
 387  0
                                     + "' was excluded from load process");
 388  
                 }
 389  
             }
 390  
 
 391  
             // If it's a @ApplicationDefinition
 392  0
             else if (clazz.containsAnnotation(Entity.APPLICATION.getFullyQualifiedName()))
 393  
             {
 394  0
                 if (!demRegistrator.getEntitiesToExclude(Entity.APPLICATION).contains(
 395  0
                         clazz.getFQName()))
 396  0
                     processApplication(clazz);
 397  
                 else
 398  
                 {
 399  0
                     DIFLogger.getLogger().info(
 400  0
                             "The Application '" + clazz.getClassInstance().getClass().getCanonicalName()
 401  0
                                     + "' was excluded from load process");
 402  
                 }
 403  
             }
 404  
 
 405  
             // If it's a @ServiceDefinition
 406  0
             else if (clazz.containsAnnotation(Entity.SERVICE.getFullyQualifiedName()))
 407  
             {
 408  0
                 if (!demRegistrator.getEntitiesToExclude(Entity.SERVICE).contains(
 409  0
                         clazz.getFQName()))
 410  0
                     processService(clazz);
 411  
                 else
 412  
                 {
 413  0
                     DIFLogger.getLogger().info(
 414  0
                             "The Service '" + clazz.getClassInstance().getClass().getCanonicalName()
 415  0
                                     + "' was excluded from load process");
 416  
                 }
 417  
             }
 418  
 
 419  
             // If it's a @StageDefinition
 420  0
             else if (clazz.containsAnnotation(Entity.STAGE.getFullyQualifiedName()))
 421  
             {
 422  0
                 if (!demRegistrator.getEntitiesToExclude(Entity.STAGE).contains(
 423  0
                         clazz.getFQName()))
 424  0
                     processStage(clazz);
 425  
                 else
 426  
                 {
 427  0
                     DIFLogger.getLogger().info(
 428  0
                             "The Stage '" + clazz.getClassInstance().getClass().getCanonicalName()
 429  0
                                     + "' was excluded from load process");
 430  
                 }
 431  
             }
 432  
         }
 433  0
     }
 434  
 
 435  
     /**
 436  
      * Process the <code>@ProviderDefinition</code> annotation, Reads it's member values and
 437  
      * 
 438  
      * @param clazz
 439  
      *            the Provider class
 440  
      * @throws ResourceNotFoundException
 441  
      *             if annotation member values can't be read
 442  
      */
 443  
     static private void processApplication(ClassHolder clazz) throws ResourceNotFoundException
 444  
     {
 445  
 
 446  
         // Add application to DEMLoaderEntityRegistry
 447  0
         addApplication(processEntity(clazz, Entity.APPLICATION), clazz);
 448  0
     }
 449  
 
 450  
     /**
 451  
      * Process the entity annotation.
 452  
      * 
 453  
      * @param clazz
 454  
      *            the Entity class
 455  
      * @param entity
 456  
      *            the entity to process
 457  
      * @return the processed Entity ID
 458  
      * @throws ResourceNotFoundException
 459  
      *             if annotation member values can't be read
 460  
      */
 461  
     static private String processEntity(ClassHolder clazz, Entity entity) throws ResourceNotFoundException
 462  
     {
 463  
         // Get the Annotation
 464  0
         AnnotationHolder entityAnnotation = clazz.getAnnotations().get(entity.getFullyQualifiedName());
 465  
 
 466  0
         if (entityAnnotation == null)
 467  0
             throw new ResourceNotFoundException("Could not get @" + entity.getName()
 468  0
                     + " annotation instance! Unable to proceed...");
 469  
 
 470  0
         String entityID = entityAnnotation.getMembers().get("id").toString();
 471  
 
 472  0
         if (AnnotationTags.GENERATE_ID.equals(entityID))
 473  0
             entityID = clazz.generateID();
 474  
 
 475  0
         return entityID;
 476  
     }
 477  
 
 478  
     /**
 479  
      * Process the <code>@ProviderDefinition</code> annotation.
 480  
      * 
 481  
      * @param clazz
 482  
      *            the Provider class
 483  
      * @throws ResourceNotFoundException
 484  
      *             if annotation member values can't be read
 485  
      */
 486  
     static private void processProvider(ClassHolder clazz) throws ResourceNotFoundException
 487  
     {
 488  
 
 489  
         // Add provider to DEMLoaderEntityRegistry
 490  0
         addProvider(processEntity(clazz, Entity.PROVIDER), clazz);
 491  0
     }
 492  
 
 493  
     /**
 494  
      * Process the <code>@ServiceDefinition</code> annotation.
 495  
      * 
 496  
      * @param clazz
 497  
      *            the Service class
 498  
      * @throws ResourceNotFoundException
 499  
      *             if annotation member values can't be read
 500  
      */
 501  
     static private void processService(ClassHolder clazz) throws ResourceNotFoundException
 502  
     {
 503  
 
 504  
         // Add service to DEMLoaderEntityRegistry
 505  0
         addService(processEntity(clazz, Entity.SERVICE), clazz);
 506  0
     }
 507  
 
 508  
     /**
 509  
      * Process the <code>@StageDefinition</code> annotation.
 510  
      * 
 511  
      * @param clazz
 512  
      *            the Stage class
 513  
      * @throws ResourceNotFoundException
 514  
      *             if annotation member values can't be read
 515  
      */
 516  
     static private void processStage(ClassHolder clazz) throws ResourceNotFoundException
 517  
     {
 518  
 
 519  
         // Add stage to DEMLoaderEntityRegistry
 520  0
         addStage(processEntity(clazz, Entity.STAGE), clazz);
 521  0
     }
 522  
 
 523  
     /**
 524  
      * Process the <code>@ValidatorDefinition</code> annotation.
 525  
      * 
 526  
      * @param clazz
 527  
      *            the Validator class
 528  
      * @throws ResourceNotFoundException
 529  
      *             if annotation member values can't be read
 530  
      */
 531  
     static private void processValidator(ClassHolder clazz) throws ResourceNotFoundException
 532  
     {
 533  
 
 534  
         // Add validator to DEMLoaderEntityRegistry
 535  0
         addValidator(processEntity(clazz, Entity.VALIDATOR), clazz);
 536  0
     }
 537  
 }