Author: nicolas
Date: Fri Feb 22 01:45:35 2008
New Revision: 630130
URL: http://svn.apache.org/viewvc?rev=630130&view=rev
Log:
- add support for LogEnabled plexus lifecycle interface via a BeanPostProcessor
- add support for plexus Map<role-hint, component> injection of all "beans with
role xx" via a custom FactoryBean
- fix destroy-method
Added:
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/BeansOfTypeFactoryBean.java
(with props)
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusLogEnabledBeanPostProcessor.java
(with props)
Modified:
maven/archiva/branches/springy/archiva-base/archiva-common/pom.xml
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusBeanDefinitionDocumentReader.java
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusClassPathXmlApplicationContext.java
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusToSpringUtils.java
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/resources/org/apache/maven/archiva/common/spring/plexus2spring.xsl
Modified: maven/archiva/branches/springy/archiva-base/archiva-common/pom.xml
URL:
http://svn.apache.org/viewvc/maven/archiva/branches/springy/archiva-base/archiva-common/pom.xml?rev=630130&r1=630129&r2=630130&view=diff
==============================================================================
--- maven/archiva/branches/springy/archiva-base/archiva-common/pom.xml
(original)
+++ maven/archiva/branches/springy/archiva-base/archiva-common/pom.xml Fri Feb
22 01:45:35 2008
@@ -48,6 +48,10 @@
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-slf4j-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-container-default</artifactId>
</dependency>
<!-- TODO: temporary spring dependencies for migration -->
Added:
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/BeansOfTypeFactoryBean.java
URL:
http://svn.apache.org/viewvc/maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/BeansOfTypeFactoryBean.java?rev=630130&view=auto
==============================================================================
---
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/BeansOfTypeFactoryBean.java
(added)
+++
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/BeansOfTypeFactoryBean.java
Fri Feb 22 01:45:35 2008
@@ -0,0 +1,102 @@
+package org.apache.maven.archiva.common.spring;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.ListableBeanFactory;
+import org.springframework.beans.factory.config.AbstractFactoryBean;
+
+/**
+ * XPathFunction to convert plexus property-name to Spring propertyName.
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Nicolas De Loof</a>
+ * @since 1.1
+ */
+public class BeansOfTypeFactoryBean
+ extends AbstractFactoryBean
+ implements InitializingBean
+{
+ private Class type;
+
+ private Map<String, Object> beansOfType;
+
+ /**
+ * [EMAIL PROTECTED]
+ * @see
org.springframework.beans.factory.config.AbstractFactoryBean#afterPropertiesSet()
+ */
+ @Override
+ public void afterPropertiesSet()
+ throws Exception
+ {
+ beansOfType = new HashMap<String, Object>();
+ Map beans = ((ListableBeanFactory) getBeanFactory()).getBeansOfType(
type );
+ for ( Iterator iterator = beans.entrySet().iterator();
iterator.hasNext(); )
+ {
+ Map.Entry entry = (Map.Entry) iterator.next();
+ beansOfType.put( getRoleHint( (String) entry.getKey() ),
entry.getValue() );
+ }
+ }
+
+ /**
+ * @param key
+ * @return
+ */
+ private String getRoleHint( String key )
+ {
+ int i =key.indexOf( '#' );
+ if (i >= 0 )
+ {
+ return key.substring( i + 1 );
+ }
+ return key;
+ }
+
+ /**
+ * [EMAIL PROTECTED]
+ * @see
org.springframework.beans.factory.config.AbstractFactoryBean#createInstance()
+ */
+ @Override
+ protected Object createInstance()
+ throws Exception
+ {
+ return beansOfType;
+ }
+
+ /**
+ * [EMAIL PROTECTED]
+ * @see
org.springframework.beans.factory.config.AbstractFactoryBean#getObjectType()
+ */
+ @Override
+ public Class getObjectType()
+ {
+ return Map.class;
+ }
+
+ public void setType( Class type )
+ {
+ this.type = type;
+ }
+
+
+}
Propchange:
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/BeansOfTypeFactoryBean.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/BeansOfTypeFactoryBean.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange:
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/BeansOfTypeFactoryBean.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified:
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusBeanDefinitionDocumentReader.java
URL:
http://svn.apache.org/viewvc/maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusBeanDefinitionDocumentReader.java?rev=630130&r1=630129&r2=630130&view=diff
==============================================================================
---
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusBeanDefinitionDocumentReader.java
(original)
+++
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusBeanDefinitionDocumentReader.java
Fri Feb 22 01:45:35 2008
@@ -50,7 +50,7 @@
super.registerBeanDefinitions( doc, readerContext );
}
- protected Document convertPlexusDescriptorToSpringBeans( Document doc )
+ public Document convertPlexusDescriptorToSpringBeans( Document doc )
{
if ( ! "component-set".equals( doc.getDocumentElement().getNodeName()
) )
{
Modified:
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusClassPathXmlApplicationContext.java
URL:
http://svn.apache.org/viewvc/maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusClassPathXmlApplicationContext.java?rev=630130&r1=630129&r2=630130&view=diff
==============================================================================
---
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusClassPathXmlApplicationContext.java
(original)
+++
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusClassPathXmlApplicationContext.java
Fri Feb 22 01:45:35 2008
@@ -22,6 +22,7 @@
import java.io.IOException;
import org.springframework.beans.BeansException;
+import
org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@@ -85,9 +86,13 @@
super( configLocations );
}
-
/**
- * [EMAIL PROTECTED]
+ * Register a custom BeanDefinitionDocumentReader to convert plexus
+ * descriptors to spring bean context format.
+ * <p>
+ * Implementation note : validation must be disabled as plexus descriptors
+ * don't use DTD / XML schemas [EMAIL PROTECTED]
+ *
* @see
org.springframework.context.support.AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.xml.XmlBeanDefinitionReader)
*/
@Override
@@ -97,6 +102,36 @@
reader.setDocumentReaderClass(
PlexusBeanDefinitionDocumentReader.class );
reader.setValidationMode( XmlBeanDefinitionReader.VALIDATION_NONE );
super.loadBeanDefinitions( reader );
+
+ }
+
+ /**
+ * Post-process the beanFactory to adapt plexus concepts to spring :
+ * <ul>
+ * <li>register a beanPostPorcessor to support LogEnabled interface in
+ * spring context
+ * </ul>
+ * [EMAIL PROTECTED]
+ *
+ * @see
org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory(org.springframework.beans.factory.config.ConfigurableListableBeanFactory)
+ */
+ @Override
+ protected void prepareBeanFactory( ConfigurableListableBeanFactory
beanFactory )
+ {
+ super.prepareBeanFactory( beanFactory );
+
+ if ( logger.isDebugEnabled() )
+ {
+ String[] beans = getBeanFactory().getBeanDefinitionNames();
+ logger.debug( "registered beans :" );
+ for ( int i = 0; i < beans.length; i++ )
+ {
+ logger.debug( beans[i] );
+ }
+ }
+
+ // Register a bean post-processor to handle plexus Logger injection
+ getBeanFactory().addBeanPostProcessor( new
PlexusLogEnabledBeanPostProcessor() );
}
}
Added:
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusLogEnabledBeanPostProcessor.java
URL:
http://svn.apache.org/viewvc/maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusLogEnabledBeanPostProcessor.java?rev=630130&view=auto
==============================================================================
---
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusLogEnabledBeanPostProcessor.java
(added)
+++
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusLogEnabledBeanPostProcessor.java
Fri Feb 22 01:45:35 2008
@@ -0,0 +1,86 @@
+package org.apache.maven.archiva.common.spring;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.codehaus.plexus.logging.LogEnabled;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.logging.LoggerManager;
+import org.codehaus.plexus.logging.console.ConsoleLogger;
+import org.codehaus.plexus.logging.slf4j.Slf4jLogger;
+import org.codehaus.plexus.logging.slf4j.Slf4jLoggerManager;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+
+/**
+ * A Spring bean postPorcessor to apply Plexu LogEnabled lifecycle interface
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Nicolas De Loof</a>
+ * @since 1.1
+ */
+public class PlexusLogEnabledBeanPostProcessor
+ implements BeanPostProcessor, InitializingBean
+{
+ private LoggerManager loggerManager = new Slf4jLoggerManager();
+
+ /**
+ * [EMAIL PROTECTED]
+ * @see
org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
+ */
+ public void afterPropertiesSet()
+ throws Exception
+ {
+ if ( loggerManager instanceof Initializable )
+ {
+ ( (Initializable) loggerManager ).initialize();
+ }
+ }
+
+ /**
+ * [EMAIL PROTECTED]
+ * @see
org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object,
java.lang.String)
+ */
+ public Object postProcessAfterInitialization( Object bean, String beanName
)
+ throws BeansException
+ {
+ return bean;
+ }
+
+ /**
+ * [EMAIL PROTECTED]
+ * @see
org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object,
java.lang.String)
+ */
+ public Object postProcessBeforeInitialization( Object bean, String
beanName )
+ throws BeansException
+ {
+ if ( bean instanceof LogEnabled )
+ {
+ ( (LogEnabled) bean ).enableLogging(
loggerManager.getLoggerForComponent( beanName ) );
+ }
+ return bean;
+ }
+
+ protected void setLoggerManager( LoggerManager loggerManager )
+ {
+ this.loggerManager = loggerManager;
+ }
+
+}
Propchange:
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusLogEnabledBeanPostProcessor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusLogEnabledBeanPostProcessor.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange:
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusLogEnabledBeanPostProcessor.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified:
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusToSpringUtils.java
URL:
http://svn.apache.org/viewvc/maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusToSpringUtils.java?rev=630130&r1=630129&r2=630130&view=diff
==============================================================================
---
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusToSpringUtils.java
(original)
+++
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/spring/PlexusToSpringUtils.java
Fri Feb 22 01:45:35 2008
@@ -19,9 +19,12 @@
* under the License.
*/
+import java.lang.reflect.Field;
+import java.util.Map;
import java.util.StringTokenizer;
import org.apache.commons.lang.ClassUtils;
+import org.codehaus.plexus.logging.LogEnabled;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Disposable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
@@ -81,6 +84,20 @@
return initializable;
}
+ public static boolean isLogEnabled( String className )
+ {
+ boolean logEnabled = false;
+ try
+ {
+ logEnabled = LogEnabled.class.isAssignableFrom(
ClassUtils.getClass( className ) );
+ }
+ catch ( ClassNotFoundException e )
+ {
+ // ignored
+ }
+ return logEnabled;
+ }
+
public static boolean isDisposable( String className )
{
boolean disposable = false;
@@ -93,4 +110,22 @@
// ignored
}
return disposable;
- }}
+ }
+
+ public static boolean isMap( String className, String property )
+ {
+ boolean map = false;
+ try
+ {
+ Class clazz = ClassUtils.getClass( className );
+ Field f = clazz.getDeclaredField( property );
+ map = Map.class.isAssignableFrom( f.getType() );
+ }
+ catch ( Exception e )
+ {
+ // ignored
+ }
+ return map;
+ }
+
+}
Modified:
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/resources/org/apache/maven/archiva/common/spring/plexus2spring.xsl
URL:
http://svn.apache.org/viewvc/maven/archiva/branches/springy/archiva-base/archiva-common/src/main/resources/org/apache/maven/archiva/common/spring/plexus2spring.xsl?rev=630130&r1=630129&r2=630130&view=diff
==============================================================================
---
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/resources/org/apache/maven/archiva/common/spring/plexus2spring.xsl
(original)
+++
maven/archiva/branches/springy/archiva-base/archiva-common/src/main/resources/org/apache/maven/archiva/common/spring/plexus2spring.xsl
Fri Feb 22 01:45:35 2008
@@ -57,7 +57,7 @@
<xsl:attribute name="init-method">initialize</xsl:attribute>
</xsl:if>
<xsl:if test="plexus:isDisposable( implementation/text() )">
- <xsl:attribute name="init-method">dispose</xsl:attribute>
+ <xsl:attribute name="destroy-method">dispose</xsl:attribute>
</xsl:if>
<xsl:for-each select="requirements/requirement">
<property>
@@ -91,6 +91,25 @@
</bean>
<!--
+ Plexus can inject all implementations of an interface as a Map
+
+ -->
+ <xsl:for-each select="requirements/requirement">
+ <xsl:if test="plexus:isMap( ../../implementation, field-name )">
+ <bean
class="org.apache.maven.archiva.common.spring.BeansOfTypeFactoryBean">
+ <xsl:attribute name="id">
+ <xsl:value-of select="plexus:toSpringId( role )" />
+ </xsl:attribute>
+ <property name="type">
+ <xsl:attribute name="value">
+ <xsl:value-of select="role" />
+ </xsl:attribute>
+ </property>
+ </bean>
+ </xsl:if>
+ </xsl:for-each>
+
+ <!--
Plexus convention is to use interface FQN as bean ID
Spring convention is to use interface simpleName as bean ID
To allow smooth migration, we define same bean with both IDs using an
alias
@@ -118,7 +137,23 @@
</xsl:choose>
</xsl:attribute>
</alias>
+
+ <!--
+ Plexus "default" role-hint is used to get the component when no hint is
specified.
+ This translates to spring context to a bean alias without '#role-hint'
suffix
+ -->
+ <xsl:if test="role-hint/text() = 'default'">
+ <alias>
+ <xsl:attribute name="alias">
+ <xsl:value-of select="plexus:toSpringId( role )" />
+ </xsl:attribute>
+ <xsl:attribute name="name">
+ <xsl:value-of select="concat( role, '#', role-hint )" />
+ </xsl:attribute>
+ </alias>
+ </xsl:if>
</xsl:for-each>
+
</beans>
</xsl:template>