Coverage Report - org.codehaus.plexus.component.repository.ComponentDescriptor
 
Classes in this File Line Coverage Branch Coverage Complexity
ComponentDescriptor
77 %
111/144
43 %
21/48
1,473
 
 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: ComponentDescriptor.java 8155 2009-04-26 01:22:53Z jvanzyl $
 35  
  */
 36  
 public class ComponentDescriptor<T>
 37  
 {
 38  187
     private String alias = null;
 39  
 
 40  187
     private String role = null;
 41  
 
 42  
     private Class<? extends T> roleClass;
 43  
 
 44  187
     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  187
     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  9
     {
 95  9
     }
 96  
 
 97  
     public ComponentDescriptor( Class<T> implementationClass, ClassRealm realm )
 98  178
     {
 99  178
         this.implementationClass = implementationClass;
 100  178
         this.implementation = implementationClass.getName();
 101  178
         this.realm = realm;
 102  178
     }
 103  
 
 104  
     /**
 105  
      * The location this information came from (descriptor file URI).
 106  
      */
 107  
     public void setSource( String source )
 108  
     {
 109  177
         this.source = source;
 110  177
     }
 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  0
         StringBuilder key = new StringBuilder();
 128  
 
 129  0
         key.append( "role: '" ).append( role ).append( "'" );
 130  
 
 131  0
         key.append( ", implementation: '" ).append( implementation ).append( "'" );
 132  
 
 133  0
         if ( roleHint != null )
 134  
         {
 135  0
             key.append( ", role hint: '" ).append( roleHint ).append( "'" );
 136  
         }
 137  
 
 138  0
         if ( alias != null )
 139  
         {
 140  0
             key.append( ", alias: '" ).append( alias ).append( "'" );
 141  
         }
 142  
 
 143  0
         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  1
         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  180
         this.alias = alias;
 164  180
     }
 165  
 
 166  
     /**
 167  
      * Returns the role of this component.
 168  
      *
 169  
      * @return the role of this component
 170  
      */
 171  
     public String getRole()
 172  
     {
 173  762
         return role;
 174  
     }
 175  
 
 176  
     public Class<? extends T> getRoleClass()
 177  
     {
 178  0
         attemptRoleLoad();
 179  
 
 180  0
         if (roleClass == null) {
 181  0
             return (Class<T>) Object.class;
 182  
         }
 183  0
         return (Class<T>)roleClass;
 184  
     }
 185  
 
 186  
     private void attemptRoleLoad()
 187  
     {
 188  193
         if ( roleClass == null && role != null && realm != null )
 189  
         {
 190  
             try
 191  
             {
 192  184
                 roleClass = (Class<? extends T>) realm.loadClass( role );
 193  180
                 Thread.currentThread();
 194  
             }
 195  4
             catch ( Throwable ignored )
 196  
             {
 197  4
                 Thread.currentThread();
 198  180
             }
 199  
         }
 200  193
     }
 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  187
         this.role = role;
 211  
 
 212  
         // reload role class
 213  187
         roleClass = null;
 214  187
         attemptRoleLoad();
 215  187
     }
 216  
 
 217  
     public void setRoleClass( Class<? extends 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  767
         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  187
         if ( ( roleHint == null ) || roleHint.trim().equals( "" ) )
 246  
         {
 247  73
             this.roleHint = PlexusConstants.PLEXUS_DEFAULT_HINT;
 248  
         }
 249  
         else
 250  
         {
 251  114
             this.roleHint = roleHint;
 252  
         }
 253  187
     }
 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  1
         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  6
         this.implementation = implementation;
 275  
 
 276  
         // reload implementation class
 277  6
         implementationClass = null;
 278  6
         attemptImplementationLoad();
 279  6
     }
 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  9
         attemptImplementationLoad();
 289  
 
 290  9
         if (implementationClass == null) {
 291  0
             return (Class<T>) Object.class;
 292  
         }
 293  9
         return implementationClass;
 294  
     }
 295  
 
 296  
     private void attemptImplementationLoad()
 297  
     {
 298  21
         if ( implementationClass == null && implementation != null && realm != null )
 299  
         {
 300  
             try
 301  
             {
 302  6
                 implementationClass = (Class<? extends T>) realm.loadClass( implementation );
 303  6
                 Thread.currentThread();
 304  
             }
 305  0
             catch ( Throwable ignored )
 306  
             {
 307  0
                 Thread.currentThread();
 308  6
             }
 309  
         }
 310  21
     }
 311  
 
 312  
     public void setImplementationClass( Class<? extends T> implementationClass )
 313  
     {
 314  3
         this.implementationClass = implementationClass;
 315  3
         if (implementationClass == null) {
 316  0
             implementation = null;
 317  
         } else {
 318  3
             implementation = implementationClass.getName();
 319  
         }
 320  3
     }
 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  1
         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  180
         this.version = version;
 340  180
     }
 341  
 
 342  
     /**
 343  
      * Returns the type of this component.
 344  
      *
 345  
      * @return the type of this component
 346  
      */
 347  
     public String getComponentType()
 348  
     {
 349  2
         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  356
         this.componentType = componentType;
 360  356
     }
 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  4
         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  7
         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  180
          this.configuration = configuration;
 390  180
     }
 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  4
         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  180
         this.lifecycleHandler = lifecycleHandler;
 420  180
     }
 421  
 
 422  
     public String getComponentProfile()
 423  
     {
 424  1
         return componentProfile;
 425  
     }
 426  
 
 427  
     public void setComponentProfile( String componentProfile )
 428  
     {
 429  179
         this.componentProfile = componentProfile;
 430  179
     }
 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  123
         this.requirements.add( requirement );
 440  123
     }
 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  189
         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  6
         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  180
         this.componentFactory = componentFactory;
 510  180
     }
 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  1
         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  179
         this.componentComposer = componentComposer;
 531  179
     }
 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  1
         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  180
         this.description = description;
 551  180
     }
 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  180
         this.instantiationStrategy = instantiationStrategy;
 561  180
     }
 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  1
         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  177
         this.componentSetDescriptor = componentSetDescriptor;
 585  177
     }
 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  23
         this.isolatedRealm = isolatedRealm;
 605  23
     }
 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  4
         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  179
         this.componentConfigurator = componentConfigurator;
 626  179
     }
 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  378
         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  6
         this.realm = realm;
 646  
 
 647  
         // reload implementation class
 648  6
         implementationClass = null;
 649  6
         attemptImplementationLoad();
 650  
 
 651  
         // reload role class
 652  6
         roleClass = null;
 653  6
         attemptRoleLoad();
 654  6
     }
 655  
 
 656  
     // Component identity established here!
 657  
     public boolean equals( Object other )
 658  
     {
 659  6
         if ( !( other instanceof ComponentDescriptor ) )
 660  
         {
 661  0
             return false;
 662  
         }
 663  
         else
 664  
         {
 665  6
             ComponentDescriptor<?> otherDescriptor = (ComponentDescriptor<?>) other;
 666  
 
 667  6
             boolean isEqual = true;
 668  
 
 669  6
             String role = getRole();
 670  6
             String otherRole = otherDescriptor.getRole();
 671  
 
 672  6
             isEqual = isEqual && ( ( role.equals( otherRole ) ) || role.equals( otherRole ) );
 673  
 
 674  6
             String roleHint = getRoleHint();
 675  6
             String otherRoleHint = otherDescriptor.getRoleHint();
 676  
 
 677  6
             isEqual = isEqual && ( ( roleHint.equals( otherRoleHint ) ) || roleHint.equals( otherRoleHint ) );
 678  
 
 679  6
             return isEqual;
 680  
         }
 681  
     }
 682  
 
 683  
     public String toString()
 684  
     {
 685  0
         return getClass().getName() + " [role: '" + getRole() + "', hint: '" + getRoleHint() + "', realm: "
 686  
             + ( realm == null ? "NULL" : "'" + realm + "'" ) + "]";
 687  
     }
 688  
 
 689  
     public int hashCode()
 690  
     {
 691  379
         int result = getRole().hashCode() + 1;
 692  
 
 693  379
         String hint = getRoleHint();
 694  
 
 695  379
         if ( hint != null )
 696  
         {
 697  379
             result += hint.hashCode();
 698  
         }
 699  
 
 700  379
         return result;
 701  
     }
 702  
 }