Coverage Report - org.codehaus.plexus.component.repository.ComponentDescriptor
 
Classes in this File Line Coverage Branch Coverage Complexity
ComponentDescriptor
80 %
113/141
62 %
30/48
1,474
 
 1  
 package org.codehaus.plexus.component.repository;
 2  
 
 3  
 /*
 4  
  * Copyright 2001-2006 Codehaus Foundation.
 5  
  *
 6  
  * Licensed under the Apache License, Version 2.0 (the "License");
 7  
  * you may not use this file except in compliance with the License.
 8  
  * You may obtain a copy of the License at
 9  
  *
 10  
  *      http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing, software
 13  
  * distributed under the License is distributed on an "AS IS" BASIS,
 14  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15  
  * See the License for the specific language governing permissions and
 16  
  * limitations under the License.
 17  
  */
 18  
 
 19  
 import org.codehaus.plexus.PlexusConstants;
 20  
 import org.codehaus.plexus.classworlds.realm.ClassRealm;
 21  
 import org.codehaus.plexus.configuration.PlexusConfiguration;
 22  
 
 23  
 import java.util.ArrayList;
 24  
 import java.util.List;
 25  
 import java.util.Arrays;
 26  
 import java.util.Collections;
 27  
 
 28  
 /**
 29  
  * Component instantiation description.
 30  
  *
 31  
  * @author Jason van Zyl
 32  
  * @author <a href="mailto:bob@eng.werken.com">bob mcwhirter</a>
 33  
  * @author <a href="mailto:mmaczka@interia.pl">Michal Maczka</a>
 34  
  * @version $Id$
 35  
  */
 36  
 public class ComponentDescriptor<T>
 37  
 {
 38  2484
     private String alias = null;
 39  
 
 40  2484
     private String role = null;
 41  
 
 42  
     private Class<T> roleClass;
 43  
 
 44  2484
     private String roleHint = PlexusConstants.PLEXUS_DEFAULT_HINT;
 45  
 
 46  
     private String implementation;
 47  
 
 48  
     private Class<? extends T> implementationClass;
 49  
 
 50  
     private String version;
 51  
 
 52  
     private String componentType;
 53  
 
 54  
     private PlexusConfiguration configuration;
 55  
 
 56  
     private String instantiationStrategy;
 57  
 
 58  
     private String lifecycleHandler;
 59  
 
 60  
     private String componentProfile;
 61  
 
 62  2484
     private final List<ComponentRequirement> requirements = new ArrayList<ComponentRequirement>();
 63  
 
 64  
     private String componentFactory;
 65  
 
 66  
     private String componentComposer;
 67  
 
 68  
     private String componentConfigurator;
 69  
 
 70  
     private String description;
 71  
 
 72  
     private ClassRealm realm;
 73  
 
 74  
     // ----------------------------------------------------------------------
 75  
     // These two fields allow for the specification of an isolated class realm
 76  
     // and dependencies that might be specified in a component configuration
 77  
     // setup by a user i.e. this is here to allow isolation for components
 78  
     // that are not picked up by the discovery mechanism.
 79  
     // ----------------------------------------------------------------------
 80  
 
 81  
     private boolean isolatedRealm;
 82  
 
 83  
     // ----------------------------------------------------------------------
 84  
 
 85  
     private ComponentSetDescriptor componentSetDescriptor;
 86  
 
 87  
     private String source;
 88  
 
 89  
     // ----------------------------------------------------------------------
 90  
     // Instance methods
 91  
     // ----------------------------------------------------------------------
 92  
 
 93  
     public ComponentDescriptor()
 94  121
     {
 95  121
     }
 96  
 
 97  
     public ComponentDescriptor( Class<T> implementationClass, ClassRealm realm )
 98  2362
     {
 99  2363
         this.implementationClass = implementationClass;
 100  2363
         this.implementation = implementationClass.getName();
 101  2363
         this.realm = realm;
 102  2363
     }
 103  
 
 104  
     /**
 105  
      * The location this information came from (descriptor file URI).
 106  
      */
 107  
     public void setSource( String source )
 108  
     {
 109  821
         this.source = source;
 110  821
     }
 111  
 
 112  
     /**
 113  
      * The location this information came from (descriptor file URI).
 114  
      */
 115  
     public String getSource()
 116  
     {
 117  0
         return source;
 118  
     }
 119  
 
 120  
     /**
 121  
      * Returns a human-friendly key, suitable for display.
 122  
      *
 123  
      * @return a human-friendly key
 124  
      */
 125  
     public String getHumanReadableKey()
 126  
     {
 127  15
         StringBuilder key = new StringBuilder();
 128  
 
 129  15
         key.append( "role: '" ).append( getRole() ).append( "'" );
 130  
 
 131  15
         key.append( ", implementation: '" ).append( getImplementation() ).append( "'" );
 132  
 
 133  15
         if ( roleHint != null )
 134  
         {
 135  15
             key.append( ", role hint: '" ).append( getRoleHint() ).append( "'" );
 136  
         }
 137  
 
 138  15
         if ( alias != null )
 139  
         {
 140  0
             key.append( ", alias: '" ).append( getAlias() ).append( "'" );
 141  
         }
 142  
 
 143  15
         return key.toString();
 144  
     }
 145  
 
 146  
     /**
 147  
      * Returns an alias for this component. An alias as an alternate name other than the normal key.
 148  
      *
 149  
      * @return an alias for this component
 150  
      */
 151  
     public String getAlias()
 152  
     {
 153  0
         return alias;
 154  
     }
 155  
 
 156  
     /**
 157  
      * Sets the alias for this component.
 158  
      *
 159  
      * @param alias alternate name to set
 160  
      */
 161  
     public void setAlias( String alias )
 162  
     {
 163  2359
         this.alias = alias;
 164  2359
     }
 165  
 
 166  
     /**
 167  
      * Returns the role of this component.
 168  
      *
 169  
      * @return the role of this component
 170  
      */
 171  
     public String getRole()
 172  
     {
 173  903444
         return role;
 174  
     }
 175  
 
 176  
     public Class<T> getRoleClass()
 177  
     {
 178  125303
         attemptRoleLoad();
 179  
 
 180  125311
         if (roleClass == null) {
 181  0
             return (Class<T>) Object.class;
 182  
         }
 183  125325
         return (Class<T>) roleClass;
 184  
     }
 185  
 
 186  
     private void attemptRoleLoad()
 187  
     {
 188  129250
         if ( roleClass == null && getRole() != null && getRealm() != null )
 189  
         {
 190  
             try
 191  
             {
 192  3698
                 roleClass = (Class<T>) getRealm().loadClass( getRole() );
 193  3689
                 Thread.currentThread();
 194  
             }
 195  11
             catch ( Throwable ignored )
 196  
             {
 197  11
                 Thread.currentThread();
 198  3689
             }
 199  
         }
 200  129258
     }
 201  
 
 202  
 
 203  
     /**
 204  
      * Sets the role of this component.
 205  
      *
 206  
      * @param role this component's role
 207  
      */
 208  
     public void setRole( String role )
 209  
     {
 210  2484
         this.role = role;
 211  
 
 212  
         // reload role class
 213  2484
         roleClass = null;
 214  2483
         attemptRoleLoad();
 215  2485
     }
 216  
 
 217  
     public void setRoleClass( Class<T> roleClass )
 218  
     {
 219  0
         this.roleClass = roleClass;
 220  
 
 221  0
         if (roleClass == null) {
 222  0
             role = null;
 223  
         } else {
 224  0
             role = roleClass.getName();
 225  
         }
 226  0
     }
 227  
 
 228  
     /**
 229  
      * Returns the role-hint of this component.
 230  
      *
 231  
      * @return the role-hint of this component
 232  
      */
 233  
     public String getRoleHint()
 234  
     {
 235  1524464
         return roleHint;
 236  
     }
 237  
 
 238  
     /**
 239  
      * Sets the role-hint of this component. Pasing null will set the hint to the default value.
 240  
      *
 241  
      * @param roleHint this component's role-hint
 242  
      */
 243  
     public void setRoleHint( String roleHint )
 244  
     {
 245  2448
         if ( ( roleHint == null ) || roleHint.trim().equals( "" ) )
 246  
         {
 247  824
             this.roleHint = PlexusConstants.PLEXUS_DEFAULT_HINT;
 248  
         }
 249  
         else
 250  
         {
 251  1624
             this.roleHint = roleHint;
 252  
         }
 253  2448
     }
 254  
 
 255  
     /**
 256  
      * Returns the implementation of this componet. Implementation is a string denoting a FQCN in normal Java
 257  
      * components, or some other name or file for other component factory implementations.
 258  
      *
 259  
      * @return the implementation of this componet's role.
 260  
      */
 261  
     public String getImplementation()
 262  
     {
 263  2771
         return implementation;
 264  
     }
 265  
 
 266  
     /**
 267  
      * Sets the implementation of this componet.
 268  
      *
 269  
      * @param implementation string denoting a FQCN in normal Java components, or some other name or file for other
 270  
      *        component factory implementations
 271  
      */
 272  
     public void setImplementation( String implementation )
 273  
     {
 274  61
         this.implementation = implementation;
 275  
 
 276  
         // reload implementation class
 277  61
         implementationClass = null;
 278  61
         attemptImplementationLoad();
 279  61
     }
 280  
 
 281  
     /**
 282  
      * Returns the implementation class of this componet, or null if the implementation class can not be loaded.
 283  
      *
 284  
      * @return the implementation of this componet's role.
 285  
      */
 286  
     public Class<? extends T> getImplementationClass()
 287  
     {
 288  254919
         attemptImplementationLoad();
 289  
 
 290  255080
         if (implementationClass == null) {
 291  3
             return (Class<T>) Object.class;
 292  
         }
 293  255253
         return (Class<T>)implementationClass;
 294  
     }
 295  
 
 296  
     private void attemptImplementationLoad()
 297  
     {
 298  256485
         if ( implementationClass == null && getImplementation() != null && getRealm() != null )
 299  
         {
 300  
             try
 301  
             {
 302  1343
                 implementationClass = (Class<? extends T>) getRealm().loadClass( getImplementation() );
 303  1339
                 Thread.currentThread();
 304  
             }
 305  4
             catch ( Throwable ignored )
 306  
             {
 307  4
                 Thread.currentThread();
 308  1339
             }
 309  
         }
 310  256428
     }
 311  
 
 312  
     public void setImplementationClass( Class<? extends T> implementationClass )
 313  
     {
 314  60
         this.implementationClass = implementationClass;
 315  60
         if (implementationClass == null) {
 316  0
             implementation = null;
 317  
         } else {
 318  60
             implementation = implementationClass.getName();
 319  
         }
 320  60
     }
 321  
 
 322  
     /**
 323  
      * Returns a specific point in a components's project timeline. i.e. version 1, or 2.1.4
 324  
      *
 325  
      * @return a specific point in a components's project timeline
 326  
      */
 327  
     public String getVersion()
 328  
     {
 329  0
         return version;
 330  
     }
 331  
 
 332  
     /**
 333  
      * Sets the point in a components's project development timeline
 334  
      *
 335  
      * @param version the components's version
 336  
      */
 337  
     public void setVersion( String version )
 338  
     {
 339  2359
         this.version = version;
 340  2359
     }
 341  
 
 342  
     /**
 343  
      * Returns the type of this component.
 344  
      *
 345  
      * @return the type of this component
 346  
      */
 347  
     public String getComponentType()
 348  
     {
 349  0
         return componentType;
 350  
     }
 351  
 
 352  
     /**
 353  
      * Sets this component's type.
 354  
      *
 355  
      * @param componentType the type to set
 356  
      */
 357  
     public void setComponentType( String componentType )
 358  
     {
 359  3455
         this.componentType = componentType;
 360  3456
     }
 361  
 
 362  
     /**
 363  
      * Returns the type of instantiation strategy for this component.
 364  
      *
 365  
      * @return the type of instantiation strategy for this component
 366  
      */
 367  
     public String getInstantiationStrategy()
 368  
     {
 369  210
         return instantiationStrategy;
 370  
     }
 371  
 
 372  
     /**
 373  
      * Returns configuration values defined for this component.
 374  
      *
 375  
      * @return configuration values defined for this component
 376  
      */
 377  
     public PlexusConfiguration getConfiguration()
 378  
     {
 379  249
         return configuration;
 380  
     }
 381  
 
 382  
     /**
 383  
      * Sets the configuration hierarchy for this component.
 384  
      *
 385  
      * @param configuration the configuration hierarchy to set
 386  
      */
 387  
     public void setConfiguration( PlexusConfiguration configuration )
 388  
     {
 389  2392
          this.configuration = configuration;
 390  2392
     }
 391  
 
 392  
     /**
 393  
      * Returns true if this component has a configuration.
 394  
      *
 395  
      * @return true if this component has a configuration
 396  
      */
 397  
     public boolean hasConfiguration()
 398  
     {
 399  1
         return configuration != null;
 400  
     }
 401  
 
 402  
     /**
 403  
      * Returns the lifecycle-handler for this component.
 404  
      *
 405  
      * @return the lifecycle-handler for this component
 406  
      */
 407  
     public String getLifecycleHandler()
 408  
     {
 409  210
         return lifecycleHandler;
 410  
     }
 411  
 
 412  
     /**
 413  
      * Sets the lifecycle-handler for this component. For example, "basic", "passive", "bootstrap".
 414  
      *
 415  
      * @param lifecycleHandler the lifecycle handler string to set
 416  
      */
 417  
     public void setLifecycleHandler( String lifecycleHandler )
 418  
     {
 419  2359
         this.lifecycleHandler = lifecycleHandler;
 420  2360
     }
 421  
 
 422  
     public String getComponentProfile()
 423  
     {
 424  2
         return componentProfile;
 425  
     }
 426  
 
 427  
     public void setComponentProfile( String componentProfile )
 428  
     {
 429  2360
         this.componentProfile = componentProfile;
 430  2360
     }
 431  
 
 432  
     /**
 433  
      * Add a project requirement to this component.
 434  
      *
 435  
      * @param requirement the requirement to add
 436  
      */
 437  
     public void addRequirement( ComponentRequirement requirement )
 438  
     {
 439  755
         this.requirements.add( requirement );
 440  755
     }
 441  
 
 442  
     /**
 443  
      * Add a project requirement to this component.
 444  
      *
 445  
      * @param requirement the requirement to add
 446  
      */
 447  
     public void addRequirement( ComponentRequirement... requirement )
 448  
     {
 449  0
         this.requirements.addAll( Arrays.asList( requirement ));
 450  0
     }
 451  
 
 452  
     /**
 453  
      * Adds a list of requirements to this component.
 454  
      *
 455  
      * @param requirements the requirements to add
 456  
      */
 457  
     public void addRequirements( List<ComponentRequirement> requirements )
 458  
     {
 459  0
         this.requirements.addAll( requirements );
 460  0
     }
 461  
 
 462  
     /**
 463  
      * Remove a project requirement from this component.
 464  
      *
 465  
      * @param requirement the requirement to remove
 466  
      */
 467  
     public void removeRequirement( ComponentRequirement... requirement )
 468  
     {
 469  0
         this.requirements.removeAll( Arrays.asList( requirement ));
 470  0
     }
 471  
 
 472  
     /**
 473  
      * Removes a list of requirements from this component.
 474  
      *
 475  
      * @param requirements the requirements to remove
 476  
      */
 477  
     public void removeRequirements( List<ComponentRequirement> requirements )
 478  
     {
 479  0
         this.requirements.removeAll( requirements );
 480  0
     }
 481  
 
 482  
     /**
 483  
      * Returns all project requirements of this component.
 484  
      *
 485  
      * @return all project requirements of this component
 486  
      */
 487  
     public List<ComponentRequirement> getRequirements()
 488  
     {
 489  2666
         return Collections.unmodifiableList( requirements );
 490  
     }
 491  
 
 492  
     /**
 493  
      * Returns an id of the factory used to create this component.
 494  
      *
 495  
      * @return an id of the factory used to create this component
 496  
      */
 497  
     public String getComponentFactory()
 498  
     {
 499  218
         return componentFactory;
 500  
     }
 501  
 
 502  
     /**
 503  
      * Sets the id of the factory to use to create this component. For example, "jruby" will use a JRuby factory.
 504  
      *
 505  
      * @param componentFactory
 506  
      */
 507  
     public void setComponentFactory( String componentFactory )
 508  
     {
 509  2361
         this.componentFactory = componentFactory;
 510  2361
     }
 511  
 
 512  
     /**
 513  
      * Returns the ID of the type of composer this component will use. For example, "setter" or "field" for the
 514  
      * different types of dependency injection.
 515  
      *
 516  
      * @return the ID of the type of composer this component will use
 517  
      */
 518  
     public String getComponentComposer()
 519  
     {
 520  0
         return componentComposer;
 521  
     }
 522  
 
 523  
     /**
 524  
      * Sets a representation of the composer this component uses.
 525  
      *
 526  
      * @param componentComposer string representation of the composer to use
 527  
      */
 528  
     public void setComponentComposer( String componentComposer )
 529  
     {
 530  2361
         this.componentComposer = componentComposer;
 531  2361
     }
 532  
 
 533  
     /**
 534  
      * Return a human-readable description of this component.
 535  
      *
 536  
      * @return a human-readable description of this component
 537  
      */
 538  
     public String getDescription()
 539  
     {
 540  0
         return description;
 541  
     }
 542  
 
 543  
     /**
 544  
      * Sets a description of this component for users to read.
 545  
      *
 546  
      * @param description a human-readable description of this component
 547  
      */
 548  
     public void setDescription( String description )
 549  
     {
 550  2359
         this.description = description;
 551  2359
     }
 552  
 
 553  
     /**
 554  
      * Sets the instantiation-strategy for this component. For example, "container".
 555  
      *
 556  
      * @param instantiationStrategy
 557  
      */
 558  
     public void setInstantiationStrategy( String instantiationStrategy )
 559  
     {
 560  2359
         this.instantiationStrategy = instantiationStrategy;
 561  2359
     }
 562  
 
 563  
     // ----------------------------------------------------------------------
 564  
     //
 565  
     // ----------------------------------------------------------------------
 566  
 
 567  
     /**
 568  
      * Returns true if this may be in an isolated classrealm.
 569  
      *
 570  
      * @return true if this may be in an isolated classrealm
 571  
      */
 572  
     public boolean isIsolatedRealm()
 573  
     {
 574  0
         return isolatedRealm;
 575  
     }
 576  
 
 577  
     /**
 578  
      * Sets the component set descriptor of components and dependencies for this component.
 579  
      *
 580  
      * @param componentSetDescriptor the component set descriptor of components and dependencies
 581  
      */
 582  
     public void setComponentSetDescriptor( ComponentSetDescriptor componentSetDescriptor )
 583  
     {
 584  1096
         this.componentSetDescriptor = componentSetDescriptor;
 585  1096
     }
 586  
 
 587  
     /**
 588  
      * Returns the component set descriptor.
 589  
      *
 590  
      * @return the component set descriptor
 591  
      */
 592  
     public ComponentSetDescriptor getComponentSetDescriptor()
 593  
     {
 594  0
         return componentSetDescriptor;
 595  
     }
 596  
 
 597  
     /**
 598  
      * Sets that this component may be in an isolated classrealm.
 599  
      *
 600  
      * @param isolatedRealm true if this component may be in an isolated classrealm
 601  
      */
 602  
     public void setIsolatedRealm( boolean isolatedRealm )
 603  
     {
 604  0
         this.isolatedRealm = isolatedRealm;
 605  0
     }
 606  
 
 607  
     /**
 608  
      * Returns the type of component configurator for this project. For example "basic" for normal, or "map-oriented"
 609  
      * for map oriented components.
 610  
      *
 611  
      * @return the type of component configurator for this project
 612  
      */
 613  
     public String getComponentConfigurator()
 614  
     {
 615  230
         return componentConfigurator;
 616  
     }
 617  
 
 618  
     /**
 619  
      * Sets the type of component configurator for this project.
 620  
      *
 621  
      * @param componentConfigurator
 622  
      */
 623  
     public void setComponentConfigurator( String componentConfigurator )
 624  
     {
 625  2361
         this.componentConfigurator = componentConfigurator;
 626  2361
     }
 627  
 
 628  
     /**
 629  
      * The ClassRealm that this component lives under.
 630  
      *
 631  
      * @return ClassRealm that this component lives under
 632  
      */
 633  
     public ClassRealm getRealm()
 634  
     {
 635  908247
         return realm;
 636  
     }
 637  
 
 638  
     /**
 639  
      * Set the ClassRealm that this component lives under.
 640  
      *
 641  
      * @param realm the ClassRealm that this component lives under
 642  
      */
 643  
     public void setRealm( ClassRealm realm )
 644  
     {
 645  1338
         this.realm = realm;
 646  
 
 647  
         // reload implementation class
 648  1338
         implementationClass = null;
 649  1338
         attemptImplementationLoad();
 650  
 
 651  
         // reload role class
 652  1338
         roleClass = null;
 653  1338
         attemptRoleLoad();
 654  1338
     }
 655  
 
 656  
     public String toString()
 657  
     {
 658  0
         return getClass().getName() + " [role: '" + getRole() + "', hint: '" + getRoleHint() + "', realm: "
 659  
             + ( realm == null ? "NULL" : "'" + realm + "'" ) + "]";
 660  
     }
 661  
 
 662  
     // Component identity established here!
 663  
     public boolean equals( Object other )
 664  
     {
 665  252509
         if ( this == other )
 666  
         {
 667  127142
             return true;
 668  
         }
 669  
 
 670  125782
         if ( !( other instanceof ComponentDescriptor ) )
 671  
         {
 672  0
             return false;
 673  
         }
 674  
 
 675  125948
         ComponentDescriptor<?> that = (ComponentDescriptor<?>) other;
 676  
 
 677  126032
         return eq( getRole(), that.getRole() ) && eq( getRoleHint(), that.getRoleHint() )
 678  
             && eq( getRealm(), that.getRealm() );
 679  
     }
 680  
 
 681  
     private static <T> boolean eq( T o1, T o2 )
 682  
     {
 683  377437
         return ( o1 != null ) ? o1.equals( o2 ) : o2 == null;
 684  
     }
 685  
 
 686  
     public int hashCode()
 687  
     {
 688  515440
         int hash = 17;
 689  
 
 690  515721
         hash = hash * 31 + hash( getRole() );
 691  516301
         hash = hash * 31 + hash( getRoleHint() );
 692  516379
         hash = hash * 31 + hash( getRealm() );
 693  
 
 694  516722
         return hash;
 695  
     }
 696  
 
 697  
     private static int hash( Object obj )
 698  
     {
 699  1546209
         return ( obj != null ) ? obj.hashCode() : 0;
 700  
     }
 701  
 
 702  
 }