]> source.dussan.org Git - archiva.git/commitdiff
support for plexus requirements without field-name
authorNicolas De Loof <nicolas@apache.org>
Tue, 26 Feb 2008 13:04:26 +0000 (13:04 +0000)
committerNicolas De Loof <nicolas@apache.org>
Tue, 26 Feb 2008 13:04:26 +0000 (13:04 +0000)
debug logging
archiva-policies converted to use PlexusInSpringTestCase for tests

git-svn-id: https://svn.apache.org/repos/asf/maven/archiva/branches@631207 13f79535-47bb-0310-9956-ffa450edef68

18 files changed:
springy/archiva-base/archiva-policies/src/test/java/org/apache/maven/archiva/policies/CachedFailuresPolicyTest.java
springy/archiva-base/archiva-policies/src/test/java/org/apache/maven/archiva/policies/ChecksumPolicyTest.java
springy/archiva-base/archiva-policies/src/test/java/org/apache/maven/archiva/policies/ReleasePolicyTest.java
springy/archiva-base/archiva-policies/src/test/java/org/apache/maven/archiva/policies/SnapshotsPolicyTest.java
springy/archiva-base/archiva-policies/src/test/resources/org/apache/maven/archiva/policies/CachedFailuresPolicyTest-context.xml
springy/archiva-base/archiva-policies/src/test/resources/org/apache/maven/archiva/policies/ChecksumPolicyTest-context.xml [new file with mode: 0644]
springy/archiva-base/archiva-policies/src/test/resources/org/apache/maven/archiva/policies/ReleasePolicyTest-context.xml [new file with mode: 0644]
springy/archiva-base/archiva-policies/src/test/resources/org/apache/maven/archiva/policies/SnapshotsPolicyTest-context.xml [new file with mode: 0644]
springy/plexus-spring/pom.xml
springy/plexus-spring/src/main/java/org/codehaus/plexus/spring/PlexusBeanDefinitionDocumentReader.java
springy/plexus-spring/src/main/java/org/codehaus/plexus/spring/PlexusClassPathXmlApplicationContext.java
springy/plexus-spring/src/main/java/org/codehaus/plexus/spring/PlexusComponentFactoryBean.java
springy/plexus-spring/src/main/java/org/codehaus/plexus/spring/PlexusContainerAdapter.java
springy/plexus-spring/src/main/java/org/codehaus/plexus/spring/PlexusNamespaceHandler.java
springy/plexus-spring/src/main/java/org/codehaus/plexus/spring/PlexusToSpringUtils.java
springy/plexus-spring/src/main/resources/org/codehaus/plexus/spring/PlexusBeanDefinitionDocumentReader.xsl
springy/plexus-spring/src/main/resources/plexus.xsd
springy/plexus-spring/src/test/resources/components.xml

index 6266a3e6d111fd3a7d10adb1838ad9b98668c0c9..c7083d93d9a60790bd616dc7d64a5680fdaf67d7 100644 (file)
@@ -23,10 +23,7 @@ import java.io.File;
 import java.util.Properties;
 
 import org.apache.maven.archiva.policies.urlcache.UrlFailureCache;
-import org.codehaus.plexus.PlexusTestCase;
-import org.codehaus.plexus.spring.PlexusClassPathXmlApplicationContext;
 import org.codehaus.plexus.spring.PlexusInSpringTestCase;
-import org.springframework.context.ConfigurableApplicationContext;
 
 /**
  * CachedFailuresPolicyTest
index a1d83d36f71350c04cadadee229b5f68d1c203df..31a1d3c4caf1fc58d5d00a5fd5926ca0b3d92b28 100644 (file)
@@ -19,22 +19,22 @@ package org.apache.maven.archiva.policies;
  * under the License.
  */
 
-import org.codehaus.plexus.PlexusTestCase;
-import org.codehaus.plexus.util.FileUtils;
-
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
 import java.util.Properties;
 
+import org.codehaus.plexus.spring.PlexusInSpringTestCase;
+import org.codehaus.plexus.util.FileUtils;
+
 /**
- * ChecksumPolicyTest 
+ * ChecksumPolicyTest
  *
  * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
  * @version $Id$
  */
 public class ChecksumPolicyTest
-    extends PlexusTestCase
+    extends PlexusInSpringTestCase
 {
     private static final String GOOD = "good";
 
@@ -166,7 +166,7 @@ public class ChecksumPolicyTest
         Properties request = createRequest();
 
         boolean actualResult;
-        
+
         try
         {
             policy.applyPolicy( ChecksumPolicy.FAIL, request, localFile );
@@ -195,7 +195,7 @@ public class ChecksumPolicyTest
         Properties request = createRequest();
 
         boolean actualResult;
-        
+
         try
         {
             policy.applyPolicy( ChecksumPolicy.FIX, request, localFile );
@@ -205,7 +205,7 @@ public class ChecksumPolicyTest
         {
             actualResult = false;
         }
-        
+
         assertEquals( createMessage( ChecksumPolicy.FIX, md5State, sha1State ), expectedResult, actualResult );
 
         // End result should be legitimate SHA1 and MD5 files.
index 3ede659be9c87492be2a908786849b862337ba89..5948dcbe7f316573db3b823608903fd18b7799f0 100644 (file)
@@ -20,19 +20,20 @@ package org.apache.maven.archiva.policies;
  */
 
 import org.codehaus.plexus.PlexusTestCase;
+import org.codehaus.plexus.spring.PlexusInSpringTestCase;
 import org.codehaus.plexus.util.FileUtils;
 
 import java.io.File;
 import java.util.Properties;
 
 /**
- * ReleasePolicyTest 
+ * ReleasePolicyTest
  *
  * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
  * @version $Id$
  */
 public class ReleasePolicyTest
-    extends PlexusTestCase
+    extends PlexusInSpringTestCase
 {
     private static final String PATH_VERSION_METADATA = "org/apache/archiva/archiva-testable/1.0-SNAPSHOT/maven-metadata.xml";
 
index 0879a7ea8705c0ac3c7539472af0852644676131..65d837d67b42b0791bec00524dd5db5027d19ffa 100644 (file)
@@ -19,12 +19,12 @@ package org.apache.maven.archiva.policies;
  * under the License.
  */
 
-import org.codehaus.plexus.PlexusTestCase;
-import org.codehaus.plexus.util.FileUtils;
-
 import java.io.File;
 import java.util.Properties;
 
+import org.codehaus.plexus.spring.PlexusInSpringTestCase;
+import org.codehaus.plexus.util.FileUtils;
+
 /**
  * SnapshotsPolicyTest 
  *
@@ -32,7 +32,7 @@ import java.util.Properties;
  * @version $Id$
  */
 public class SnapshotsPolicyTest
-    extends PlexusTestCase
+    extends PlexusInSpringTestCase
 {
     private static final String PATH_VERSION_METADATA = "org/apache/archiva/archiva-testable/1.0-SNAPSHOT/maven-metadata.xml";
 
index c7cd821c742a8f31cc15eb069baa981cd7c131ec..6b9cb384cc3c4799ffae2d5ed216fe6bb3ed9283 100644 (file)
@@ -4,6 +4,8 @@
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
+  <bean id="plexusContainer" class="org.codehaus.plexus.spring.PlexusContainerAdapter"/>
+
   <bean id="loggerManager" class="org.codehaus.plexus.logging.console.ConsoleLoggerManager"
        init-method="initialize"/>
 
@@ -11,4 +13,5 @@
     <!-- collaborators and configuration for this bean go here -->
     <constructor-arg ref="cache#url-failures-cache" type="org.codehaus.plexus.cache.Cache"/>
   </bean>
+
 </beans>
\ No newline at end of file
diff --git a/springy/archiva-base/archiva-policies/src/test/resources/org/apache/maven/archiva/policies/ChecksumPolicyTest-context.xml b/springy/archiva-base/archiva-policies/src/test/resources/org/apache/maven/archiva/policies/ChecksumPolicyTest-context.xml
new file mode 100644 (file)
index 0000000..5add86c
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+  <bean id="plexusContainer" class="org.codehaus.plexus.spring.PlexusContainerAdapter"/>
+
+  <bean id="loggerManager" class="org.codehaus.plexus.logging.console.ConsoleLoggerManager"
+       init-method="initialize"/>
+
+  <bean id="urlFailureCache" class="org.apache.maven.archiva.policies.urlcache.DefaultUrlFailureCache">
+    <!-- collaborators and configuration for this bean go here -->
+    <constructor-arg ref="cache#url-failures-cache" type="org.codehaus.plexus.cache.Cache"/>
+  </bean>
+</beans>
\ No newline at end of file
diff --git a/springy/archiva-base/archiva-policies/src/test/resources/org/apache/maven/archiva/policies/ReleasePolicyTest-context.xml b/springy/archiva-base/archiva-policies/src/test/resources/org/apache/maven/archiva/policies/ReleasePolicyTest-context.xml
new file mode 100644 (file)
index 0000000..5add86c
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+  <bean id="plexusContainer" class="org.codehaus.plexus.spring.PlexusContainerAdapter"/>
+
+  <bean id="loggerManager" class="org.codehaus.plexus.logging.console.ConsoleLoggerManager"
+       init-method="initialize"/>
+
+  <bean id="urlFailureCache" class="org.apache.maven.archiva.policies.urlcache.DefaultUrlFailureCache">
+    <!-- collaborators and configuration for this bean go here -->
+    <constructor-arg ref="cache#url-failures-cache" type="org.codehaus.plexus.cache.Cache"/>
+  </bean>
+</beans>
\ No newline at end of file
diff --git a/springy/archiva-base/archiva-policies/src/test/resources/org/apache/maven/archiva/policies/SnapshotsPolicyTest-context.xml b/springy/archiva-base/archiva-policies/src/test/resources/org/apache/maven/archiva/policies/SnapshotsPolicyTest-context.xml
new file mode 100644 (file)
index 0000000..5add86c
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+  <bean id="plexusContainer" class="org.codehaus.plexus.spring.PlexusContainerAdapter"/>
+
+  <bean id="loggerManager" class="org.codehaus.plexus.logging.console.ConsoleLoggerManager"
+       init-method="initialize"/>
+
+  <bean id="urlFailureCache" class="org.apache.maven.archiva.policies.urlcache.DefaultUrlFailureCache">
+    <!-- collaborators and configuration for this bean go here -->
+    <constructor-arg ref="cache#url-failures-cache" type="org.codehaus.plexus.cache.Cache"/>
+  </bean>
+</beans>
\ No newline at end of file
index 0a26b34926af2137db4d2c2f09b3b965f411e9a4..24fc7b3420ebc264faa2ac52c250e7eef893bcac 100644 (file)
       <version>1.0-alpha-22</version>\r
     </dependency>\r
     <dependency>\r
-      <groupId>org.codehaus.plexus</groupId>\r
-      <artifactId>plexus-container-default</artifactId>\r
-      <version>1.0-alpha-22</version>\r
-    </dependency>\r
-    <dependency>\r
+      <!-- only required to debug XSLT result -->\r
       <groupId>dom4j</groupId>\r
       <artifactId>dom4j</artifactId>\r
       <version>1.6.1</version>\r
index 08653851618af530e6625025aaeef5b6f4d56330..cac48637db88b38fad3424824a7de6f053c8adcf 100644 (file)
@@ -84,6 +84,7 @@ public class PlexusBeanDefinitionDocumentReader
             Transformer t = tf.newTransformer( xsltSource );\r
             t.transform( xmlSource, transResult );\r
 \r
+            logger.debug( doc.getDocumentURI() + " successfully translated to spring");\r
             return (Document) transResult.getNode();\r
         }\r
         catch ( Exception e )\r
index cdba35d1bfc5ae37d126ea5abf0f5a012290b678..a8d7cb34fdf3927c16fdb104db227e9dc8cd6a36 100644 (file)
@@ -30,16 +30,12 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
  * A custom ClassPathXmlApplicationContext to support plexus\r
  * <tr>components.xml</tt> descriptors in Spring, with no changes required\r
  * to neither plexus nor spring beans.\r
- * \r
+ *\r
  * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>\r
  */\r
 public class PlexusClassPathXmlApplicationContext\r
     extends ClassPathXmlApplicationContext\r
 {\r
-\r
-    // TODO enable Field injection...\r
-    // @see http://forum.springframework.org/showthread.php?t=50181\r
-\r
     public PlexusClassPathXmlApplicationContext( String path, Class clazz )\r
         throws BeansException\r
     {\r
@@ -90,12 +86,13 @@ public class PlexusClassPathXmlApplicationContext
 \r
     /**\r
      * {@inheritDoc}\r
-     * \r
+     *\r
      * @see org.springframework.context.support.AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.xml.XmlBeanDefinitionReader)\r
      */\r
     protected void loadBeanDefinitions( XmlBeanDefinitionReader reader )\r
         throws BeansException, IOException\r
     {\r
+        logger.info( "Registering plexus to spring XML translation" );\r
         reader.setDocumentReaderClass( PlexusBeanDefinitionDocumentReader.class );\r
         reader.setValidationMode( XmlBeanDefinitionReader.VALIDATION_NONE );\r
         super.loadBeanDefinitions( reader );\r
index 6e6494fc0156d102826ea1f1ac9cdd634f186e94..65dc595a1d86b475580428524c19d9fa0ee35f22 100644 (file)
@@ -26,13 +26,17 @@ import java.util.LinkedList;
 import java.util.List;\r
 import java.util.Map;\r
 \r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
 import org.codehaus.plexus.PlexusContainer;\r
 import org.codehaus.plexus.context.Context;\r
+import org.codehaus.plexus.context.ContextException;\r
 import org.codehaus.plexus.logging.LogEnabled;\r
 import org.codehaus.plexus.logging.LoggerManager;\r
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;\r
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Disposable;\r
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;\r
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;\r
 import org.springframework.beans.BeansException;\r
 import org.springframework.beans.SimpleTypeConverter;\r
 import org.springframework.beans.TypeConverter;\r
@@ -42,7 +46,10 @@ import org.springframework.beans.factory.BeanFactoryAware;
 import org.springframework.beans.factory.BeanInitializationException;\r
 import org.springframework.beans.factory.DisposableBean;\r
 import org.springframework.beans.factory.FactoryBean;\r
+import org.springframework.beans.factory.InitializingBean;\r
 import org.springframework.beans.factory.ListableBeanFactory;\r
+import org.springframework.beans.factory.config.AbstractFactoryBean;\r
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;\r
 import org.springframework.beans.factory.config.RuntimeBeanReference;\r
 import org.springframework.util.ReflectionUtils;\r
 \r
@@ -56,35 +63,50 @@ import org.springframework.util.ReflectionUtils;
  * </ul>\r
  * If not set, the beanFActory will auto-detect the loggerManager to use by\r
  * searching for the adequate bean in the spring context.\r
+ * <p>\r
  *\r
  * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>\r
  */\r
 public class PlexusComponentFactoryBean\r
     implements FactoryBean, BeanFactoryAware, DisposableBean\r
 {\r
+    /** Logger available to subclasses */\r
+    protected final Log logger = LogFactory.getLog( getClass() );\r
+\r
+    /** The beanFactory */\r
+    private BeanFactory beanFactory;\r
+\r
     /**\r
      * @todo isn't there a constant for this in plexus ?\r
      */\r
     private static final String SINGLETON = "singleton";\r
 \r
+    /** The plexus component role */\r
     private Class role;\r
 \r
+    /** The plexus component implementation class */\r
     private Class implementation;\r
 \r
-    private String instanciationStrategy = SINGLETON;\r
+    /** The plexus component instantiation strategy */\r
+    private String instantiationStrategy = SINGLETON;\r
 \r
+    /** The plexus component requirements and configurations */\r
     private Map requirements;\r
 \r
-    private ListableBeanFactory beanFactory;\r
-\r
-    private LoggerManager loggerManager;\r
-\r
-    private TypeConverter typeConverter = new SimpleTypeConverter();\r
-\r
+    /** The plexus component created by this FactoryBean */\r
     private List instances = new LinkedList();\r
 \r
-    private Context context;\r
+    /** Optional plexus loggerManager */\r
+    private static LoggerManager loggerManager;\r
+\r
+    /** Optional plexus context */\r
+    private static Context context;\r
 \r
+    /**\r
+     * {@inheritDoc}\r
+     *\r
+     * @see org.springframework.beans.factory.config.AbstractFactoryBean#destroy()\r
+     */\r
     public void destroy()\r
         throws Exception\r
     {\r
@@ -92,26 +114,37 @@ public class PlexusComponentFactoryBean
         {\r
             for ( Iterator iterator = instances.iterator(); iterator.hasNext(); )\r
             {\r
-                Object component = (Object) iterator.next();\r
-                if ( component instanceof Disposable )\r
+                Object isntance = iterator.next();\r
+                if ( isntance instanceof Disposable )\r
                 {\r
-                    ( (Disposable) component ).dispose();\r
-\r
+                    ( (Disposable) isntance ).dispose();\r
                 }\r
             }\r
         }\r
     }\r
 \r
+    /**\r
+     * {@inheritDoc}\r
+     * @see org.springframework.beans.factory.FactoryBean#getObject()\r
+     */\r
     public Object getObject()\r
         throws Exception\r
     {\r
-        // Spring MAY cache the object built by this factory if getSingleton()\r
-        // returns true, but can also requires us to ensure unicity.\r
-        if ( SINGLETON.equals( instanciationStrategy ) && !instances.isEmpty() )\r
+        if ( isSingleton() && !instances.isEmpty())\r
         {\r
             return instances.get( 0 );\r
         }\r
+        return createInstance();\r
+    }\r
 \r
+    /**\r
+     * Create the plexus component instance. Inject dependencies declared as\r
+     * requirements using direct field injection\r
+     */\r
+    public Object createInstance()\r
+        throws Exception\r
+    {\r
+        logger.debug( "Creating plexus component " + implementation );\r
         final Object component = implementation.newInstance();\r
         synchronized ( instances )\r
         {\r
@@ -119,40 +152,120 @@ public class PlexusComponentFactoryBean
         }\r
         if ( requirements != null )\r
         {\r
-            ReflectionUtils.doWithFields( implementation, new ReflectionUtils.FieldCallback()\r
+            for ( Iterator iterator = requirements.entrySet().iterator(); iterator.hasNext(); )\r
             {\r
-                public void doWith( Field field )\r
-                    throws IllegalArgumentException, IllegalAccessException\r
+                Map.Entry requirement = (Map.Entry) iterator.next();\r
+                String fieldName = (String) requirement.getKey();\r
+\r
+                if ( fieldName.startsWith( "#" ) )\r
                 {\r
-                    Object dependency = resolveRequirement( field );\r
-                    if ( dependency != null )\r
+                    // implicit field injection : the field name was no\r
+                    // specified in the plexus descriptor as only one filed\r
+                    // matches Dependency type\r
+\r
+                    RuntimeBeanReference ref = (RuntimeBeanReference) requirement.getValue();\r
+                    Object dependency = beanFactory.getBean( ref.getBeanName() );\r
+\r
+                    Field[] fields = implementation.getDeclaredFields();\r
+                    for ( int i = 0; i < fields.length; i++ )\r
                     {\r
-                        ReflectionUtils.makeAccessible( field );\r
-                        ReflectionUtils.setField( field, component, dependency );\r
+                        Field field = fields[i];\r
+                        if ( ReflectionUtils.COPYABLE_FIELDS.matches( field )\r
+                            && field.getType().isAssignableFrom( dependency.getClass() ) )\r
+                        {\r
+                            if ( logger.isTraceEnabled() )\r
+                            {\r
+                                logger.trace( "Injecting dependency " + dependency + " into field " + field.getName() );\r
+                            }\r
+                            ReflectionUtils.makeAccessible( field );\r
+                            ReflectionUtils.setField( field, component, dependency );\r
+                        }\r
                     }\r
                 }\r
-            }, ReflectionUtils.COPYABLE_FIELDS );\r
+                else\r
+                {\r
+                    // explicit field injection\r
+                    Field field;\r
+                    try\r
+                    {\r
+                        fieldName = PlexusToSpringUtils.toCamelCase( fieldName );\r
+                        field = implementation.getDeclaredField( fieldName );\r
+                    }\r
+                    catch ( NoSuchFieldException e )\r
+                    {\r
+                        logger.warn( "No field " + fieldName + " on implementation class " + implementation );\r
+                        continue;\r
+                    }\r
+                    Object dependency = resolveRequirement( field, requirement.getValue() );\r
+                    if ( logger.isTraceEnabled() )\r
+                    {\r
+                        logger.trace( "Injecting dependency " + dependency + " into field " + field.getName() );\r
+                    }\r
+                    ReflectionUtils.makeAccessible( field );\r
+                    ReflectionUtils.setField( field, component, dependency );\r
+                }\r
+            }\r
         }\r
 \r
+        handlePlexusLifecycle( component );\r
+\r
+        return component;\r
+    }\r
+\r
+    private void handlePlexusLifecycle( final Object component )\r
+        throws ContextException, InitializationException\r
+    {\r
         if ( component instanceof LogEnabled )\r
         {\r
             ( (LogEnabled) component ).enableLogging( getLoggerManager().getLoggerForComponent( role.getName() ) );\r
         }\r
 \r
-        if (component instanceof Contextualizable )\r
+        if ( component instanceof Contextualizable )\r
         {\r
-            // VERRY limiter support for Contextualizable\r
-            ((Contextualizable) component).contextualize( getContext() );\r
+            // VERRY limited support for Contextualizable\r
+            ( (Contextualizable) component ).contextualize( getContext() );\r
         }\r
 \r
+        // TODO add support for Startable, Stopable -> LifeCycle ?\r
+\r
         if ( component instanceof Initializable )\r
         {\r
             ( (Initializable) component ).initialize();\r
         }\r
+    }\r
 \r
-        // TODO add support for Startable, Stopable -> LifeCycle ?\r
+    /**\r
+     * Resolve the requirement that this field exposes in the component\r
+     *\r
+     * @param field\r
+     * @return\r
+     */\r
+    protected Object resolveRequirement( Field field, Object requirement )\r
+    {\r
+        if ( requirement instanceof RuntimeBeanReference )\r
+        {\r
+            String beanName = ( (RuntimeBeanReference) requirement ).getBeanName();\r
+            if ( Map.class.isAssignableFrom( field.getType() ) )\r
+            {\r
+                // component ask plexus for a Map of all available\r
+                // components for the role\r
+                requirement = PlexusToSpringUtils.lookupMap( beanName, getListableBeanFactory() );\r
+            }\r
+            else if ( Collection.class.isAssignableFrom( field.getType() ) )\r
+            {\r
+                requirement = PlexusToSpringUtils.LookupList( beanName, getListableBeanFactory() );\r
+            }\r
+            else\r
+            {\r
+                requirement = beanFactory.getBean( beanName );\r
+            }\r
+        }\r
+        if ( requirement != null )\r
+        {\r
+            requirement = getBeanTypeConverter().convertIfNecessary( requirement, field.getType() );\r
+        }\r
+        return requirement;\r
 \r
-        return component;\r
     }\r
 \r
     public Class getObjectType()\r
@@ -162,7 +275,7 @@ public class PlexusComponentFactoryBean
 \r
     public boolean isSingleton()\r
     {\r
-        return SINGLETON.equals( instanciationStrategy );\r
+        return SINGLETON.equals( instantiationStrategy );\r
     }\r
 \r
     /**\r
@@ -170,7 +283,7 @@ public class PlexusComponentFactoryBean
      */\r
     protected Context getContext()\r
     {\r
-        if (context == null)\r
+        if ( context == null )\r
         {\r
             PlexusContainer container = (PlexusContainer) beanFactory.getBean( "plexusContainer" );\r
             context = container.getContext();\r
@@ -178,8 +291,21 @@ public class PlexusComponentFactoryBean
         return context;\r
     }\r
 \r
+    protected TypeConverter getBeanTypeConverter()\r
+    {\r
+        if ( beanFactory instanceof ConfigurableBeanFactory )\r
+        {\r
+            return ( (ConfigurableBeanFactory) beanFactory ).getTypeConverter();\r
+        }\r
+        else\r
+        {\r
+            return new SimpleTypeConverter();\r
+        }\r
+    }\r
+\r
     /**\r
      * Retrieve the loggerManager instance to be used for LogEnabled components\r
+     *\r
      * @return\r
      */\r
     protected LoggerManager getLoggerManager()\r
@@ -190,24 +316,29 @@ public class PlexusComponentFactoryBean
             {\r
                 loggerManager = (LoggerManager) beanFactory.getBean( "loggerManager" );\r
             }\r
-            Map loggers = beanFactory.getBeansOfType( LoggerManager.class );\r
-            if ( loggers.size() == 1 )\r
-            {\r
-                loggerManager = (LoggerManager) loggers.values().iterator().next();\r
-            }\r
             else\r
             {\r
-                throw new BeanInitializationException(\r
-                    "You must explicitly set a LoggerManager or define a unique one in bean context" );\r
+                Map loggers = getListableBeanFactory().getBeansOfType( LoggerManager.class );\r
+                if ( loggers.size() == 1 )\r
+                {\r
+                    loggerManager = (LoggerManager) loggers.values().iterator().next();\r
+                }\r
             }\r
         }\r
+        if ( loggerManager == null )\r
+        {\r
+            throw new BeanCreationException( "A LoggerManager instance must be set in the applicationContext" );\r
+        }\r
         return loggerManager;\r
     }\r
 \r
-    public void setBeanFactory( BeanFactory beanFactory )\r
-        throws BeansException\r
+    private ListableBeanFactory getListableBeanFactory()\r
     {\r
-        this.beanFactory = (ListableBeanFactory) beanFactory;\r
+        if ( beanFactory instanceof ListableBeanFactory )\r
+        {\r
+            return (ListableBeanFactory) beanFactory;\r
+        }\r
+        throw new BeanInitializationException( "A ListableBeanFactory is required by the PlexusComponentFactoryBean" );\r
     }\r
 \r
     /**\r
@@ -215,7 +346,7 @@ public class PlexusComponentFactoryBean
      */\r
     public void setLoggerManager( LoggerManager loggerManager )\r
     {\r
-        this.loggerManager = loggerManager;\r
+        PlexusComponentFactoryBean.loggerManager = loggerManager;\r
     }\r
 \r
     /**\r
@@ -247,7 +378,7 @@ public class PlexusComponentFactoryBean
         {\r
             throw new BeanCreationException( "Plexus poolable instanciation-strategy is not supported" );\r
         }\r
-        this.instanciationStrategy = instanciationStrategy;\r
+        this.instantiationStrategy = instanciationStrategy;\r
     }\r
 \r
     /**\r
@@ -258,49 +389,14 @@ public class PlexusComponentFactoryBean
         this.requirements = requirements;\r
     }\r
 \r
-    protected void setTypeConverter( TypeConverter typeConverter )\r
+    public void setContext( Context context )\r
     {\r
-        this.typeConverter = typeConverter;\r
+        PlexusComponentFactoryBean.context = context;\r
     }\r
 \r
-\r
-    /**\r
-     * Resolve the requirement that this field exposes in the component\r
-     * @param field\r
-     * @return\r
-     */\r
-    protected Object resolveRequirement( Field field )\r
-    {\r
-        Object dependency =  requirements.get( field.getName() );\r
-        if ( dependency instanceof RuntimeBeanReference )\r
-        {\r
-            String beanName = ( (RuntimeBeanReference) dependency ).getBeanName();\r
-            if ( Map.class.isAssignableFrom( field.getType() ) )\r
-            {\r
-                // component ask plexus for a Map of all available\r
-                // components for the role\r
-                dependency = PlexusToSpringUtils.lookupMap( beanName, beanFactory );\r
-            }\r
-            else if ( Collection.class.isAssignableFrom( field.getType() ) )\r
-            {\r
-                dependency = PlexusToSpringUtils.LookupList( beanName, beanFactory );\r
-            }\r
-            else\r
-            {\r
-                dependency = beanFactory.getBean( beanName );\r
-            }\r
-        }\r
-        if (dependency != null)\r
-        {\r
-            dependency = typeConverter.convertIfNecessary( dependency, field.getType() );\r
-        }\r
-        return dependency;\r
-\r
-    }\r
-\r
-    protected void setContext( Context context )\r
+    public void setBeanFactory( BeanFactory beanFactory )\r
     {\r
-        this.context = context;\r
+        this.beanFactory = beanFactory;\r
     }\r
 \r
 }\r
index f75efefde4ad4dceedd2d46d5a7786b684ab30d7..7f45c444ddd7e2681103f9d6349eeeb064bcff34 100644 (file)
@@ -34,7 +34,7 @@ import org.codehaus.plexus.component.repository.exception.ComponentLifecycleExce
 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
 import org.codehaus.plexus.component.repository.exception.ComponentRepositoryException;
 import org.codehaus.plexus.context.Context;
-import org.codehaus.plexus.context.DefaultContext;
+import org.codehaus.plexus.context.ContextException;
 import org.codehaus.plexus.logging.Logger;
 import org.codehaus.plexus.logging.LoggerManager;
 import org.springframework.beans.BeansException;
@@ -50,7 +50,7 @@ import org.springframework.context.ApplicationContextAware;
 public class PlexusContainerAdapter
     implements PlexusContainer, ApplicationContextAware, InitializingBean
 {
-    private Context context = new DefaultContext();
+    private Context context = new SimpleContext();
 
     private ApplicationContext applicationContext;
 
@@ -62,7 +62,7 @@ public class PlexusContainerAdapter
     public void afterPropertiesSet()
         throws Exception
     {
-        context.put( "plexus", this );
+        context = new SimpleContext();
     }
 
     /**
@@ -653,5 +653,67 @@ public class PlexusContainerAdapter
         this.applicationContext = applicationContext;
     }
 
+    private class SimpleContext implements Context
+    {
+        /** the plexus container key in the context */
+        private static final String PLEXUS = "plexus";
+
+        /**
+         * {@inheritDoc}
+         * @see org.codehaus.plexus.context.Context#contains(java.lang.Object)
+         */
+        public boolean contains( Object key )
+        {
+            return PLEXUS.equals( key );
+        }
+
+        /**
+         * {@inheritDoc}
+         * @see org.codehaus.plexus.context.Context#get(java.lang.Object)
+         */
+        public Object get( Object key )
+            throws ContextException
+        {
+            return PLEXUS.equals( key ) ? PlexusContainerAdapter.this : null;
+        }
+
+        /**
+         * {@inheritDoc}
+         * @see org.codehaus.plexus.context.Context#getContextData()
+         */
+        public Map getContextData()
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * {@inheritDoc}
+         * @see org.codehaus.plexus.context.Context#hide(java.lang.Object)
+         */
+        public void hide( Object key )
+            throws IllegalStateException
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * {@inheritDoc}
+         * @see org.codehaus.plexus.context.Context#makeReadOnly()
+         */
+        public void makeReadOnly()
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * {@inheritDoc}
+         * @see org.codehaus.plexus.context.Context#put(java.lang.Object, java.lang.Object)
+         */
+        public void put( Object key, Object value )
+            throws IllegalStateException
+        {
+            throw new UnsupportedOperationException();
+        }
 
+    }
 }
index 4fce66574fa6875f66ec4b220ef5dea0832e2b31..65e5b64e8945e3c78d13a43d7346171ab6a0fe8c 100644 (file)
@@ -37,8 +37,8 @@ import org.springframework.util.xml.DomUtils;
 import org.w3c.dom.Element;\r
 \r
 /**\r
- * A spring namespace handler to support plexus components creation and direct field-injection in a spring\r
- * XmlApplicationContext.\r
+ * A spring namespace handler to support plexus components creation and direct\r
+ * field-injection in a spring XmlApplicationContext.\r
  *\r
  * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>\r
  * @since 1.1\r
@@ -64,15 +64,17 @@ public class PlexusNamespaceHandler
     }\r
 \r
     /**\r
-     * BeanDefinitionParser for &lt;plexus:component&gt;. Register a bean definition for a PlexusComponentFactoryBean\r
-     * with all nested requirement / configuration injected using direct field injection.\r
+     * BeanDefinitionParser for &lt;plexus:component&gt;. Register a bean\r
+     * definition for a PlexusComponentFactoryBean with all nested requirement /\r
+     * configuration injected using direct field injection.\r
      * <p>\r
-     * Also register an alias for the Plexus component using spring conventions (interface class simple name + "#"\r
-     * role-hint)\r
+     * Also register an alias for the Plexus component using spring conventions\r
+     * (interface class simple name + "#" role-hint)\r
      */\r
     private class PlexusComponentBeanDefinitionParser\r
         extends AbstractSingleBeanDefinitionParser\r
     {\r
+        private int count;\r
 \r
         protected void doParse( Element element, BeanDefinitionBuilder builder )\r
         {\r
@@ -87,10 +89,12 @@ public class PlexusNamespaceHandler
             for ( Iterator iterator = requirements.iterator(); iterator.hasNext(); )\r
             {\r
                 Element child = (Element) iterator.next();\r
-                String name = child.getAttribute( "name" );\r
-                if (name.length() == 0)\r
+                String name = child.getAttribute( "field-name" );\r
+                if ( name.length() == 0 )\r
                 {\r
-                    throw new ApplicationContextException( "No field name for plexus requirement on " + implementation );\r
+                    // Plexus doesn't require to specify the field-name if only\r
+                    // one field matches the injected type\r
+                    name = "#" + count++;\r
                 }\r
                 String role = child.getAttribute( "role" );\r
                 String roleHint = child.getAttribute( "role-hint" );\r
index bf65ab2d5a4be5250396c0e01ee3e6f7f8cebd9b..366ce1ce55661af65902b5c1bb6ae4994788e075 100644 (file)
@@ -55,7 +55,7 @@ public class PlexusToSpringUtils
         StringBuilder camelCase = new StringBuilder();\r
         boolean first = true;\r
 \r
-        StringTokenizer tokenizer = new StringTokenizer( string.toLowerCase(), "-" );\r
+        StringTokenizer tokenizer = new StringTokenizer( string, "-" );\r
         while ( tokenizer.hasMoreTokens() )\r
         {\r
             String token = tokenizer.nextToken();\r
index d766a0f47b9b9233ba7e6487ac8de9854515e1e2..2605bfe51782ca851b7fdac63f4d8fafae962364 100644 (file)
@@ -34,7 +34,8 @@
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
        xmlns:plexus="http://plexus.codehaus.org/spring"\r
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
-                           http://plexus.codehaus.org/spring http://plexus.codehaus.org/schemas/spring-1.0.xsd">\r
+                           http://plexus.codehaus.org/spring http://plexus.codehaus.org/schemas/spring-1.0.xsd"\r
+       default-lazy-init="true">\r
   <xsl:for-each select="components/component">\r
 \r
     <plexus:component>\r
@@ -56,7 +57,7 @@
       </xsl:if>\r
       <xsl:for-each select="requirements/requirement">\r
         <plexus:requirement>\r
-          <xsl:attribute name="name">\r
+          <xsl:attribute name="field-name">\r
             <xsl:value-of select="field-name" />\r
           </xsl:attribute>\r
           <xsl:attribute name="role">\r
index 694228c0829f6ff1461c4620d19e6a3009178d26..2c40f643d1e8d6730af47087306a626b699cbb8e 100644 (file)
@@ -8,7 +8,7 @@ elementFormDefault="qualified" attributeFormDefault="unqualified">
           <xsd:sequence>\r
             <xsd:element name="requirement" minOccurs="0">\r
               <xsd:complexType>\r
-                          <xsd:attribute name="name" type="xsd:string" use="required"/>\r
+                          <xsd:attribute name="field-name" type="xsd:string" use="optional"/>\r
                           <xsd:attribute name="role" type="xsd:string" use="required"/>\r
                           <xsd:attribute name="role-hint" type="xsd:string" use="optional"/>\r
               </xsd:complexType>\r
index 32d190cb123cb4fca61e46463c18087ad38e7ac1..bdc9a362c24d5bf9e930bc092206dfc584571981 100644 (file)
@@ -6,7 +6,6 @@
       <implementation>org.codehaus.plexus.spring.PlexusBeanImpl</implementation>\r
       <requirements>\r
        <requirement>\r
-               <field-name>bean</field-name>\r
                <role>springBean</role>\r
        </requirement>\r
       </requirements>\r
@@ -37,6 +36,6 @@
                <role>org.codehaus.plexus.spring.PlexusBean</role>\r
        </requirement>\r
       </requirements>\r
-    </component>    \r
+    </component>\r
   </components>\r
 </component-set>\r