Automatically inject ScmProvider implementations

git-svn-id: https://svn.apache.org/repos/asf/continuum/branches/builder@654275 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/continuum-base/continuum-scm/pom.xml b/continuum-base/continuum-scm/pom.xml
index e00d512..e5632c9 100644
--- a/continuum-base/continuum-scm/pom.xml
+++ b/continuum-base/continuum-scm/pom.xml
@@ -26,9 +26,13 @@
       <groupId>org.springframework</groupId>
       <artifactId>spring-context</artifactId>
       <version>${spring.version}</version>
-      <scope>test</scope>
     </dependency>
     <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-spring</artifactId>
+      <scope>test</scope>
+    </dependency>    
+    <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-simple</artifactId>
       <version>1.5.0</version>
diff --git a/continuum-base/continuum-scm/src/main/java/org/apache/continuum/scm/manager/spring/ScmProviderFactoryBean.java b/continuum-base/continuum-scm/src/main/java/org/apache/continuum/scm/manager/spring/ScmProviderFactoryBean.java
new file mode 100644
index 0000000..84f8abc
--- /dev/null
+++ b/continuum-base/continuum-scm/src/main/java/org/apache/continuum/scm/manager/spring/ScmProviderFactoryBean.java
@@ -0,0 +1,66 @@
+package org.apache.continuum.scm.manager.spring;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.maven.scm.provider.ScmProvider;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanFactoryUtils;
+import org.springframework.beans.factory.BeanInitializationException;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+/**
+ * <p>
+ * Factory bean to inject all beans of type {@link ScmProvider}
+ * </p>
+ * <p>
+ * <code>&lt;bean id="scmProviders" class="org.apache.continuum.scm.manager.spring.ScmManagerFactoryBean"/>
+ </code>
+ * </p>
+ * 
+ * @author Carlos Sanchez <carlos@apache.org>
+ */
+public class ScmProviderFactoryBean
+    implements FactoryBean, ApplicationContextAware
+{
+    private ApplicationContext applicationContext;
+
+    public Object getObject()
+        throws Exception
+    {
+        Map<String, ScmProvider> providers = new HashMap<String, ScmProvider>();
+        Map<String, ScmProvider> beans =
+            BeanFactoryUtils.beansOfTypeIncludingAncestors( applicationContext, ScmProvider.class );
+        for ( ScmProvider provider : beans.values() )
+        {
+            if ( providers.containsKey( provider.getScmType() ) )
+            {
+                throw new BeanInitializationException(
+                                                       "There are to ScmProvider beans in the appllication context for Scm type " +
+                                                           provider.getScmType() +
+                                                           ". Probably two conflicting scm implementations are present in the classpath." );
+            }
+            providers.put( provider.getScmType(), provider );
+        }
+        return providers;
+    }
+
+    public Class getObjectType()
+    {
+        return Map.class;
+    }
+
+    public boolean isSingleton()
+    {
+        return true;
+    }
+
+    public void setApplicationContext( ApplicationContext applicationContext )
+        throws BeansException
+    {
+        this.applicationContext = applicationContext;
+    }
+
+}
diff --git a/continuum-base/continuum-scm/src/test/java/org/apache/continuum/scm/manager/ScmManagerTest.java b/continuum-base/continuum-scm/src/test/java/org/apache/continuum/scm/manager/ScmManagerTest.java
index 3aa79d3..8bef9ca 100644
--- a/continuum-base/continuum-scm/src/test/java/org/apache/continuum/scm/manager/ScmManagerTest.java
+++ b/continuum-base/continuum-scm/src/test/java/org/apache/continuum/scm/manager/ScmManagerTest.java
@@ -19,12 +19,12 @@
  * under the License.
  */
 
-import org.apache.maven.scm.manager.NoSuchScmProviderException;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
-
 import junit.framework.TestCase;
 
+import org.apache.maven.scm.manager.NoSuchScmProviderException;
+import org.codehaus.plexus.spring.PlexusClassPathXmlApplicationContext;
+import org.springframework.context.ApplicationContext;
+
 /**
  * @todo replace with a spring integration test
  */
@@ -38,7 +38,8 @@
     public void setUp()
     {
         context =
-            new ClassPathXmlApplicationContext( new String[] { "classpath*:META-INF/spring-context.xml",
+            new PlexusClassPathXmlApplicationContext( new String[] { "classpath*:META-INF/spring-context.xml",
+                "classpath*:META-INF/plexus/components.xml",
                 "classpath*:" + getClass().getName().replace( '.', '/' ) + ".xml" } );
         manager = (ScmManager) context.getBean( "scmManager" );
     }
@@ -47,6 +48,6 @@
         throws NoSuchScmProviderException
     {
         manager.getScmLogger().info( "Hello, World" );
-        assertNotNull( manager.getProviderByType( "svnexe" ) );
+        assertNotNull( manager.getProviderByType( "svn" ) );
     }
 }
diff --git a/continuum-base/continuum-scm/src/test/resources/org/apache/continuum/scm/manager/ScmManagerTest.xml b/continuum-base/continuum-scm/src/test/resources/org/apache/continuum/scm/manager/ScmManagerTest.xml
index 782680d..0b946d3 100644
--- a/continuum-base/continuum-scm/src/test/resources/org/apache/continuum/scm/manager/ScmManagerTest.xml
+++ b/continuum-base/continuum-scm/src/test/resources/org/apache/continuum/scm/manager/ScmManagerTest.xml
@@ -6,15 +6,9 @@
 
   <bean id="scmManager"
     class="org.apache.continuum.scm.manager.ScmManager">
-    <!--  TODO: better way to add the providers without having to redeclare all this? -->
     <property name="scmLogger" ref="scmLogger" />
     <property name="scmProviders">
-      <map>
-        <entry key="svnexe">
-          <bean
-            class="org.apache.maven.scm.provider.svn.svnexe.SvnExeScmProvider" />
-        </entry>
-      </map>
+      <bean class="org.apache.continuum.scm.manager.spring.ScmProviderFactoryBean"/>
     </property>
   </bean>
 </beans>