package org.codehaus.plexus.spring;\r
\r
-\r
/*\r
* Licensed to the Apache Software Foundation (ASF) under one\r
* or more contributor license agreements. See the NOTICE file\r
import javax.xml.transform.dom.DOMSource;\r
import javax.xml.transform.stream.StreamSource;\r
\r
+import org.dom4j.io.DOMReader;\r
+import org.dom4j.io.OutputFormat;\r
+import org.dom4j.io.XMLWriter;\r
import org.springframework.beans.factory.BeanDefinitionStoreException;\r
import org.springframework.beans.factory.xml.BeanDefinitionDocumentReader;\r
import org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader;\r
public void registerBeanDefinitions( Document doc, XmlReaderContext readerContext )\r
{\r
doc = convertPlexusDescriptorToSpringBeans( doc );\r
+ if ( Boolean.getBoolean( "spring-plexus.debug" ) )\r
+ {\r
+ try\r
+ {\r
+ XMLWriter writer = new XMLWriter( System.out, OutputFormat.createPrettyPrint() );\r
+ writer.write( new DOMReader().read( doc ) );\r
+ }\r
+ catch ( Exception e )\r
+ {\r
+ // ignored\r
+ }\r
+ }\r
+\r
super.registerBeanDefinitions( doc, readerContext );\r
}\r
\r
protected Document convertPlexusDescriptorToSpringBeans( Document doc )\r
{\r
- if ( ! "component-set".equals( doc.getDocumentElement().getNodeName() ) )\r
+ if ( !"component-set".equals( doc.getDocumentElement().getNodeName() ) )\r
{\r
return doc;\r
}\r
}\r
catch ( Exception e )\r
{\r
- throw new BeanDefinitionStoreException( "Failed to translate plexus component descriptor to Spring XML context", e );\r
+ throw new BeanDefinitionStoreException(\r
+ "Failed to translate plexus component descriptor to Spring XML context", e );\r
}\r
}\r
}\r
*/\r
\r
import java.lang.reflect.Field;\r
+import java.util.ArrayList;\r
import java.util.Collection;\r
import java.util.HashMap;\r
import java.util.Iterator;\r
import java.util.Map;\r
\r
import org.codehaus.plexus.PlexusConstants;\r
+import org.codehaus.plexus.context.Context;\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.springframework.beans.BeansException;\r
* <ul>\r
* <li>Support for direct field injection or "requirements"</li>\r
* <li>Support for LogEnabled, Initializable and Disposable plexus interfaces</li>\r
- * <li>Support for plexus.requirement to get a Map<role-hint, component> for a role\r
+ * <li>Support for plexus.requirement to get a Map<role-hint, component> for a\r
+ * role\r
* </ul>\r
- * If not set, the beanFActory will auto-detect the loggerManager to use by searching for the adequate bean in the\r
- * spring context.\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
*\r
* @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>\r
*/\r
public class PlexusComponentFactoryBean\r
implements FactoryBean, BeanFactoryAware, DisposableBean\r
{\r
-\r
private static final char HINT = '#';\r
\r
private Class role;\r
\r
private ListableBeanFactory beanFactory;\r
\r
+ private Context contextWrapper;\r
+\r
private LoggerManager loggerManager;\r
\r
private TypeConverter typeConverter = new SimpleTypeConverter();\r
throw new BeanCreationException( "Plexus poolable instanciation-strategy is not supported" );\r
}\r
\r
+ // Spring MAY cache the object built by this factory if getSingleton()\r
+ // returns true,\r
+ // but can also requires us to ensure unicity.\r
if ( "singleton".equals( instanciationStrategy ) && !instances.isEmpty() )\r
{\r
return instances.get( 0 );\r
public void doWith( Field field )\r
throws IllegalArgumentException, IllegalAccessException\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 components for the role\r
- Map map = new HashMap();\r
- String mask = beanName + HINT;\r
- String[] beans = beanFactory.getBeanDefinitionNames();\r
- for ( int i = 0; i < beans.length; i++ )\r
- {\r
- String name = beans[i];\r
- if ( name.startsWith( mask ) )\r
- {\r
- map.put( name.substring( mask.length() ), beanFactory.getBean( name ) );\r
- }\r
- }\r
- if ( beanFactory.containsBean( beanName ) )\r
- {\r
- map.put( PlexusConstants.PLEXUS_DEFAULT_HINT, beanFactory.getBean( beanName ) );\r
- }\r
- dependency = map;\r
- }\r
- else if ( Collection.class.isAssignableFrom( field.getType() ) )\r
- {\r
- List list = new LinkedList();\r
- String mask = beanName + HINT;\r
- String[] beans = beanFactory.getBeanDefinitionNames();\r
- for ( int i = 0; i < beans.length; i++ )\r
- {\r
- String name = beans[i];\r
- if ( name.startsWith( mask ) )\r
- {\r
- list.add( beanFactory.getBean( name ) );\r
- }\r
- }\r
- if ( beanFactory.containsBean( beanName ) )\r
- {\r
- list.add( beanFactory.getBean( beanName ) );\r
- }\r
- dependency = list;\r
- }\r
- else\r
- {\r
- dependency = beanFactory.getBean( beanName );\r
- }\r
- }\r
+ Object dependency = resolveRequirement( field );\r
if ( dependency != null )\r
{\r
- dependency = typeConverter.convertIfNecessary( dependency, field.getType() );\r
ReflectionUtils.makeAccessible( field );\r
ReflectionUtils.setField( field, component, dependency );\r
}\r
}, ReflectionUtils.COPYABLE_FIELDS );\r
}\r
\r
-\r
if ( component instanceof LogEnabled )\r
{\r
( (LogEnabled) component ).enableLogging( getLoggerManager().getLoggerForComponent( role.getName() ) );\r
}\r
\r
+ if (component instanceof Contextualizable )\r
+ {\r
+ ((Contextualizable) component).contextualize( contextWrapper );\r
+ }\r
+\r
if ( component instanceof Initializable )\r
{\r
( (Initializable) component ).initialize();\r
return "per-lookup".equals( instanciationStrategy );\r
}\r
\r
- private LoggerManager getLoggerManager()\r
+ /**\r
+ * Retrieve the loggerManager instance to be used for LogEnabled components\r
+ * @return\r
+ */\r
+ protected LoggerManager getLoggerManager()\r
{\r
if ( loggerManager == null )\r
{\r
else\r
{\r
throw new BeanInitializationException(\r
- "You must explicitly set a LoggerManager or define a unique one in bean context" );\r
+ "You must explicitly set a LoggerManager or define a unique one in bean context" );\r
}\r
}\r
return loggerManager;\r
*/\r
public void setInstanciationStrategy( String instanciationStrategy )\r
{\r
- if (instanciationStrategy.length() == 0)\r
+ if ( instanciationStrategy.length() == 0 )\r
{\r
instanciationStrategy = "singleton";\r
}\r
this.typeConverter = typeConverter;\r
}\r
\r
+ /**\r
+ * Create a Map of all available implementation of the expected role\r
+ * @param beanName\r
+ * @return Map<role-hint, component>\r
+ */\r
+ protected Map getRoleMap( String beanName )\r
+ {\r
+ Map map = new HashMap();\r
+ String mask = beanName + HINT;\r
+ String[] beans = beanFactory.getBeanDefinitionNames();\r
+ for ( int i = 0; i < beans.length; i++ )\r
+ {\r
+ String name = beans[i];\r
+ if ( name.startsWith( mask ) )\r
+ {\r
+ map.put( name.substring( mask.length() ), beanFactory.getBean( name ) );\r
+ }\r
+ }\r
+ if ( beanFactory.containsBean( beanName ) )\r
+ {\r
+ map.put( PlexusConstants.PLEXUS_DEFAULT_HINT, beanFactory.getBean( beanName ) );\r
+ }\r
+ return map;\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 = getRoleMap( beanName );\r
+ }\r
+ else if ( Collection.class.isAssignableFrom( field.getType() ) )\r
+ {\r
+ dependency = new ArrayList( getRoleMap( beanName ).values() );\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
}\r