Coverage Report - org.codehaus.plexus.component.collections.AbstractComponentCollection
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractComponentCollection
79 %
35/44
71 %
20/28
3,286
 
 1  
 package org.codehaus.plexus.component.collections;
 2  
 
 3  
 import org.codehaus.plexus.MutablePlexusContainer;
 4  
 import org.codehaus.plexus.classworlds.ClassWorld;
 5  
 import org.codehaus.plexus.classworlds.realm.ClassRealm;
 6  
 import org.codehaus.plexus.component.repository.ComponentDescriptor;
 7  
 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
 8  
 import org.codehaus.plexus.logging.Logger;
 9  
 
 10  
 import java.util.Collection;
 11  
 import java.util.HashMap;
 12  
 import java.util.HashSet;
 13  
 import java.util.List;
 14  
 import java.util.Map;
 15  
 
 16  
 /*
 17  
  * Copyright 2001-2006 Codehaus Foundation.
 18  
  *
 19  
  * Licensed under the Apache License, Version 2.0 (the "License");
 20  
  * you may not use this file except in compliance with the License.
 21  
  * You may obtain a copy of the License at
 22  
  *
 23  
  *      http://www.apache.org/licenses/LICENSE-2.0
 24  
  *
 25  
  * Unless required by applicable law or agreed to in writing, software
 26  
  * distributed under the License is distributed on an "AS IS" BASIS,
 27  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 28  
  * See the License for the specific language governing permissions and
 29  
  * limitations under the License.
 30  
  */
 31  
 
 32  
 /** @author Jason van Zyl */
 33  
 
 34  
 // We need to have the collection notified when a new implementation of a given role has
 35  
 // been added to the container. We probably need some options so that we know when new
 36  
 // component descriptors have been added to the system, and an option to keep the collection
 37  
 // up-to-date when new implementations are added.
 38  
 //
 39  
 // NOTE: This includes component additions, but also component purges from the
 40  
 // container, as when a component realm is disposed
 41  
 // (and PlexusContainer.removeComponentRealm(..) is called).
 42  
 public abstract class AbstractComponentCollection<T>
 43  
 {
 44  
     /** The reference to the PlexusContainer */
 45  
     protected MutablePlexusContainer container;
 46  
 
 47  
     /** The type of the components held by this collection*/
 48  
     protected final Class<T> componentType;
 49  
 
 50  
     /** The role of the components we are holding in this Collection. */
 51  
     protected String role;
 52  
 
 53  
     /** The role hint of the components we are holding in this Collection. */
 54  
     protected List<String> roleHints;
 55  
 
 56  
     /** The component that requires this collection of components */
 57  
     protected String hostComponent;
 58  
 
 59  
     /** Used to log errors in the component lookup process. */
 60  
     protected Logger logger;
 61  
 
 62  
     private ClassLoader tccl;
 63  
     private Collection<ClassRealm> realms;
 64  
 
 65  
     private Map<String, ComponentDescriptor<T>> componentDescriptorMap;
 66  
     private final ClassWorld world;
 67  
 
 68  
     public AbstractComponentCollection( final MutablePlexusContainer container,
 69  
                                         final Class<T> componentType,
 70  
                                         final String role,
 71  
                                         final List<String> roleHints,
 72  
                                         final String hostComponent )
 73  14
     {
 74  14
         this.container = container;
 75  
 
 76  14
         this.componentType = componentType;
 77  
 
 78  14
         this.role = role;
 79  
 
 80  14
         this.roleHints = roleHints;
 81  
 
 82  14
         this.hostComponent = hostComponent;
 83  
 
 84  14
         logger = container.getLoggerManager().getLoggerForComponent( role );
 85  
 
 86  14
         world = container.getContainerRealm().getWorld();
 87  14
     }
 88  
 
 89  
     private boolean realmsHaveChanged()
 90  
     {
 91  253044
         return ( tccl != Thread.currentThread().getContextClassLoader() ) ||
 92  
                ( realms == null ) || ( !realms.equals( world.getRealms() ) );
 93  
     }
 94  
 
 95  
     protected synchronized Map<String, ComponentDescriptor<T>> getComponentDescriptorMap()
 96  
     {
 97  125430
         checkUpdate();
 98  
 
 99  125384
         return componentDescriptorMap;
 100  
     }
 101  
 
 102  
     @SuppressWarnings( "unchecked" )
 103  
     protected boolean checkUpdate()
 104  
     {
 105  252956
         if ( componentDescriptorMap != null && !realmsHaveChanged() )
 106  
         {
 107  0
             return false;
 108  
         }
 109  
 
 110  254207
         tccl = Thread.currentThread().getContextClassLoader();
 111  254228
         Collection fromWorld = world.getRealms();
 112  254653
         if ( fromWorld == null || fromWorld.isEmpty() )
 113  
         {
 114  0
             realms = null;
 115  
         }
 116  
         else
 117  
         {
 118  254653
             realms = new HashSet<ClassRealm>( fromWorld );
 119  
         }
 120  
 
 121  254417
         Map<String, ComponentDescriptor<T>> componentMap = container.getComponentDescriptorMap( componentType, role );
 122  252723
         Map<String, ComponentDescriptor<T>> newComponentDescriptors =
 123  
             new HashMap<String, ComponentDescriptor<T>>( componentMap.size() * 2 );
 124  
 
 125  253131
         if ( roleHints != null && !roleHints.isEmpty() )
 126  
         {
 127  8
             for ( String roleHint : roleHints )
 128  
             {
 129  11
                 ComponentDescriptor<T> componentDescriptor = componentMap.get( roleHint );
 130  11
                 if ( componentDescriptor != null )
 131  
                 {
 132  11
                     newComponentDescriptors.put( roleHint, componentDescriptor );
 133  
                 }
 134  11
             }
 135  
         }
 136  
         else
 137  
         {
 138  253000
             newComponentDescriptors.putAll( componentMap );
 139  
         }
 140  
 
 141  252471
         if ( componentDescriptorMap == null || !newComponentDescriptors.equals( componentDescriptorMap ) )
 142  
         {
 143  125728
             componentDescriptorMap = newComponentDescriptors;
 144  
 
 145  125751
             return true;
 146  
         }
 147  
 
 148  126935
         return false;
 149  
     }
 150  
 
 151  
     protected T lookup( ComponentDescriptor<T> componentDescriptor )
 152  
     {
 153  125860
         T component = null;
 154  
 
 155  
         try
 156  
         {
 157  125773
             if ( componentDescriptor != null )
 158  
             {
 159  125423
                 component = container.lookup( componentDescriptor );
 160  
             }
 161  
         }
 162  0
         catch ( ComponentLookupException e )
 163  
         {
 164  0
             logger.debug( "Failed to lookup a member of active collection with role: " + role + " and role-hint: "
 165  
                 + componentDescriptor.getRoleHint(), e );
 166  126629
         }
 167  
 
 168  126628
         return component;
 169  
     }
 170  
 
 171  
     public synchronized void clear()
 172  
     {
 173  0
         releaseAllCallback();
 174  
 
 175  0
         componentDescriptorMap = null;
 176  
 
 177  0
         tccl = null;
 178  0
         realms = null;
 179  0
     }
 180  
 
 181  
     protected abstract void releaseAllCallback();
 182  
 
 183  
 }