diff --git a/config/alfresco/repository.properties b/config/alfresco/repository.properties index 748bf0b852..ed9c7d8924 100644 --- a/config/alfresco/repository.properties +++ b/config/alfresco/repository.properties @@ -355,4 +355,13 @@ imap.config.server.mountPoints.value.AlfrescoIMAP.modeName=MIXED # Activity feed max size and max age (eg. 44640 mins = 31 days) activities.feed.max.size=100 -activities.feed.max.age.mins=44640 \ No newline at end of file +activities.feed.max.age.mins=44640 + +# Subsystem unit test values. Will not have any effect on production servers +subsystems.test.beanProp.default.longProperty=123456789123456789 +subsystems.test.beanProp.default.anotherStringProperty=Global Default +subsystems.test.beanProp=inst1,inst2,inst3 +subsystems.test.beanProp.value.inst2.boolProperty=true +subsystems.test.beanProp.value.inst3.anotherStringProperty=Global Instance Default +subsystems.test.simpleProp2=true +subsystems.test.simpleProp3=Global Default3 \ No newline at end of file diff --git a/source/java/org/alfresco/repo/management/subsystems/ChildApplicationContextFactory.java b/source/java/org/alfresco/repo/management/subsystems/ChildApplicationContextFactory.java index 7c48354f69..371ea72874 100644 --- a/source/java/org/alfresco/repo/management/subsystems/ChildApplicationContextFactory.java +++ b/source/java/org/alfresco/repo/management/subsystems/ChildApplicationContextFactory.java @@ -83,14 +83,15 @@ import org.springframework.core.io.support.ResourcePatternResolver; *

* Composite property settings are best controlled either through a JMX console (Enterprise edition only) or * /alfresco-global.properties in the classpath (the replacement to /alfresco/extension/custom-repository.properties). - * For example, suppose "imap.server.mountPoints" was registered as a composite property of type {@link RepositoryPathConfigBean}. - * You can then use the property to configure a list of {@link RepositoryPathConfigBean}s. First you specify in the property's - * value a list of zero or more 'instance names'. Each name must be unique within the property. + * For example, suppose "imap.server.mountPoints" was registered as a composite property of type + * {@link RepositoryPathConfigBean}. You can then use the property to configure a list of + * {@link RepositoryPathConfigBean}s. First you specify in the property's value a list of zero or more 'instance names'. + * Each name must be unique within the property. *

* imap.server.mountPoints=Repository_virtual,Repository_archive *

- * Then, by magic you have two separate instances of {@link RepositoryPathConfigBean} whose properties you can address through an - * extended set of properties prefixed by "imap.server.mountPoints". + * Then, by magic you have two separate instances of {@link RepositoryPathConfigBean} whose properties you can address + * through an extended set of properties prefixed by "imap.server.mountPoints". *

* To set a property on one of the instances, you append ".value.<instance name>.<bean property name>" to the * parent property name. For example: @@ -109,6 +110,7 @@ import org.springframework.core.io.support.ResourcePatternResolver; *

* In order to actually utilize this configurable list of beans in your child application context, you simply need to * declare a {@link ListFactoryBean} whose ID is the same name as the property. For example: + * *

  * <bean id="imap.server.mountPoints" class="org.springframework.beans.factory.config.ListFactoryBean">
  *    <property name="sourceList">
@@ -251,9 +253,14 @@ public class ChildApplicationContextFactory extends AbstractPropertyBackedBean i
     @Override
     public void afterPropertiesSet() throws Exception
     {
+        List idList = getId();
+        if (idList.isEmpty())
+        {
+            throw new IllegalStateException("Invalid ID");
+        }
         if (getTypeName() == null)
         {
-            setTypeName(getId().get(0));
+            setTypeName(idList.get(0));
         }
 
         // Load the property defaults
@@ -268,12 +275,12 @@ public class ChildApplicationContextFactory extends AbstractPropertyBackedBean i
         super.afterPropertiesSet();
 
         // Apply any property overrides from the extension classpath and also allow system properties and JNDI to
-        // override
+        // override. We use the type name and last component of the ID in the path
         JndiPropertiesFactoryBean overrideFactory = new JndiPropertiesFactoryBean();
         overrideFactory.setSystemPropertiesMode(PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_OVERRIDE);
         overrideFactory.setLocations(getParent().getResources(
                 ChildApplicationContextFactory.EXTENSION_CLASSPATH_PREFIX + getCategory() + '/' + getTypeName() + '/'
-                        + getId() + '/' + ChildApplicationContextFactory.PROPERTIES_SUFFIX));
+                        + idList.get(idList.size() - 1) + '/' + ChildApplicationContextFactory.PROPERTIES_SUFFIX));
         overrideFactory.setProperties(this.properties);
         overrideFactory.afterPropertiesSet();
         this.properties = (Properties) overrideFactory.getObject();
@@ -530,7 +537,7 @@ public class ChildApplicationContextFactory extends AbstractPropertyBackedBean i
                 ChildApplicationContextFactory.CLASSPATH_PREFIX + getCategory() + '/' + getTypeName()
                         + ChildApplicationContextFactory.CONTEXT_SUFFIX,
                 ChildApplicationContextFactory.EXTENSION_CLASSPATH_PREFIX + getCategory() + '/' + getTypeName() + '/'
-                        + getId() + '/' + ChildApplicationContextFactory.CONTEXT_SUFFIX
+                        + getId().get(getId().size() - 1) + '/' + ChildApplicationContextFactory.CONTEXT_SUFFIX
             }, false, ChildApplicationContextFactory.this.getParent());
 
             // Add a property placeholder configurer, with the subsystem-scoped default properties
diff --git a/source/java/org/alfresco/repo/management/subsystems/test/SubsystemsTest.java b/source/java/org/alfresco/repo/management/subsystems/test/SubsystemsTest.java
new file mode 100644
index 0000000000..05d871aaa4
--- /dev/null
+++ b/source/java/org/alfresco/repo/management/subsystems/test/SubsystemsTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2005-2009 Alfresco Software Limited.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ * As a special exception to the terms and conditions of version 2.0 of 
+ * the GPL, you may redistribute this Program in connection with Free/Libre 
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's 
+ * FLOSS exception.  You should have received a copy of the text describing 
+ * the FLOSS exception, and it is also available here: 
+ * http://www.alfresco.com/legal/licensing"
+ */
+package org.alfresco.repo.management.subsystems.test;
+
+import org.alfresco.repo.management.subsystems.ApplicationContextFactory;
+import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
+import org.alfresco.util.ApplicationContextHelper;
+import org.alfresco.util.BaseSpringTest;
+import org.springframework.context.ConfigurableApplicationContext;
+
+/**
+ * Ensures the following features of subsystems are working:
+ * 
+ * 
+ * @see ChildApplicationContextFactory
+ * @author dward
+ */
+public class SubsystemsTest extends BaseSpringTest
+{
+
+    /*
+     * (non-Javadoc)
+     * @see org.alfresco.util.BaseSpringTest#getConfigLocations()
+     */
+    @Override
+    protected String[] getConfigLocations()
+    {
+        return new String[]
+        {
+            ApplicationContextHelper.CONFIG_LOCATIONS[0], "classpath:subsystem-test-context.xml"
+        };
+    }
+
+    /**
+     * Test subsystems.
+     * 
+     * @throws Exception
+     *             the exception
+     */
+    public void testSubsystems() throws Exception
+    {
+        ApplicationContextFactory subsystem = (ApplicationContextFactory) getApplicationContext().getBean(
+                "testsubsystem");
+        ConfigurableApplicationContext childContext = (ConfigurableApplicationContext) subsystem
+                .getApplicationContext();
+        assertTrue("Subsystem not started", childContext.isActive());
+        TestService testService = (TestService) childContext.getBean("testService");
+        // Make sure subsystem defaults work
+        assertEquals("Subsystem Default1", testService.getSimpleProp1());
+        // Make sure global property overrides work
+        assertEquals(true, testService.getSimpleProp2().booleanValue());
+        // Make sure extension classpath property overrides work
+        assertEquals("Instance Override3", testService.getSimpleProp3());
+        // Make sure extension classpath Spring overrides work
+        assertEquals("An extra bean I changed", childContext.getBean("anotherBean"));
+        // Make sure composite properties and their defaults work
+        TestBean[] testBeans = testService.getTestBeans();
+        assertNotNull("Composite property not set", testBeans);
+        assertEquals(3, testBeans.length);
+        assertEquals("inst1", testBeans[0].getId());
+        assertEquals(false, testBeans[0].isBoolProperty());
+        assertEquals(123456789123456789L, testBeans[0].getLongProperty());
+        assertEquals("Global Default", testBeans[0].getAnotherStringProperty());
+        assertEquals("inst2", testBeans[1].getId());
+        assertEquals(true, testBeans[1].isBoolProperty());
+        assertEquals(123456789123456789L, testBeans[1].getLongProperty());
+        assertEquals("Global Default", testBeans[1].getAnotherStringProperty());
+        assertEquals("inst3", testBeans[2].getId());
+        assertEquals(false, testBeans[2].isBoolProperty());
+        assertEquals(123456789123456789L, testBeans[2].getLongProperty());
+        assertEquals("Global Instance Default", testBeans[2].getAnotherStringProperty());
+    }
+
+}
diff --git a/source/java/org/alfresco/repo/management/subsystems/test/TestBean.java b/source/java/org/alfresco/repo/management/subsystems/test/TestBean.java
new file mode 100644
index 0000000000..25f2754980
--- /dev/null
+++ b/source/java/org/alfresco/repo/management/subsystems/test/TestBean.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2005-2009 Alfresco Software Limited.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ * As a special exception to the terms and conditions of version 2.0 of 
+ * the GPL, you may redistribute this Program in connection with Free/Libre 
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's 
+ * FLOSS exception.  You should have received a copy of the text describing 
+ * the FLOSS exception, and it is also available here: 
+ * http://www.alfresco.com/legal/licensing"
+ */
+package org.alfresco.repo.management.subsystems.test;
+
+import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
+import org.springframework.beans.factory.BeanNameAware;
+
+/**
+ * A bean to test out 'composite property' features.
+ * 
+ * @see ChildApplicationContextFactory
+ */
+public class TestBean implements BeanNameAware
+{
+    private String id;
+    private long longProperty;
+    private boolean boolProperty;
+    private String anotherStringProperty;
+
+    /*
+     * (non-Javadoc)
+     * @see org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang.String)
+     */
+    public void setBeanName(String name)
+    {
+        this.id = name;
+    }
+
+    public String getId()
+    {
+        return this.id;
+    }
+
+    public long getLongProperty()
+    {
+        return this.longProperty;
+    }
+
+    public void setLongProperty(long longProperty)
+    {
+        this.longProperty = longProperty;
+    }
+
+    public boolean isBoolProperty()
+    {
+        return this.boolProperty;
+    }
+
+    public void setBoolProperty(boolean boolProperty)
+    {
+        this.boolProperty = boolProperty;
+    }
+
+    public String getAnotherStringProperty()
+    {
+        return this.anotherStringProperty;
+    }
+
+    public void setAnotherStringProperty(String anotherStringProperty)
+    {
+        this.anotherStringProperty = anotherStringProperty;
+    }
+}
diff --git a/source/java/org/alfresco/repo/management/subsystems/test/TestService.java b/source/java/org/alfresco/repo/management/subsystems/test/TestService.java
new file mode 100644
index 0000000000..b4e9e3b8d6
--- /dev/null
+++ b/source/java/org/alfresco/repo/management/subsystems/test/TestService.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2005-2009 Alfresco Software Limited.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ * As a special exception to the terms and conditions of version 2.0 of 
+ * the GPL, you may redistribute this Program in connection with Free/Libre 
+ * and Open Source Software ("FLOSS") applications as described in Alfresco's 
+ * FLOSS exception.  You should have received a copy of the text describing 
+ * the FLOSS exception, and it is also available here: 
+ * http://www.alfresco.com/legal/licensing"
+ */
+package org.alfresco.repo.management.subsystems.test;
+
+import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
+
+/**
+ * A class to test out subsystem property setting.
+ * 
+ * @see ChildApplicationContextFactory
+ */
+public class TestService
+{
+    private TestBean[] testBeans;
+
+    private String simpleProp1;
+    private Boolean simpleProp2;
+    private String simpleProp3;
+
+    public TestBean[] getTestBeans()
+    {
+        return this.testBeans;
+    }
+
+    public void setTestBeans(TestBean[] testBeans)
+    {
+        this.testBeans = testBeans;
+    }
+
+    public String getSimpleProp1()
+    {
+        return this.simpleProp1;
+    }
+
+    public void setSimpleProp1(String simpleProp1)
+    {
+        this.simpleProp1 = simpleProp1;
+    }
+
+    public Boolean getSimpleProp2()
+    {
+        return this.simpleProp2;
+    }
+
+    public void setSimpleProp2(Boolean simpleProp2)
+    {
+        this.simpleProp2 = simpleProp2;
+    }
+
+    public String getSimpleProp3()
+    {
+        return this.simpleProp3;
+    }
+
+    public void setSimpleProp3(String simpleProp3)
+    {
+        this.simpleProp3 = simpleProp3;
+    }
+}
diff --git a/source/test-resources/alfresco/extension/subsystems/testsubsystem/testType/default/mytest-context.xml b/source/test-resources/alfresco/extension/subsystems/testsubsystem/testType/default/mytest-context.xml
new file mode 100644
index 0000000000..c97a4113f4
--- /dev/null
+++ b/source/test-resources/alfresco/extension/subsystems/testsubsystem/testType/default/mytest-context.xml
@@ -0,0 +1,12 @@
+
+
+
+
+   
+   
+      
+         An extra bean I changed
+      
+   
+
+
\ No newline at end of file
diff --git a/source/test-resources/alfresco/extension/subsystems/testsubsystem/testType/default/testProps.properties b/source/test-resources/alfresco/extension/subsystems/testsubsystem/testType/default/testProps.properties
new file mode 100644
index 0000000000..d0c0a41af1
--- /dev/null
+++ b/source/test-resources/alfresco/extension/subsystems/testsubsystem/testType/default/testProps.properties
@@ -0,0 +1 @@
+subsystems.test.simpleProp3=Instance Override3
\ No newline at end of file
diff --git a/source/test-resources/alfresco/subsystems/testsubsystem/testType/mytest-context.xml b/source/test-resources/alfresco/subsystems/testsubsystem/testType/mytest-context.xml
new file mode 100644
index 0000000000..05b87993e0
--- /dev/null
+++ b/source/test-resources/alfresco/subsystems/testsubsystem/testType/mytest-context.xml
@@ -0,0 +1,39 @@
+
+
+
+
+	
+	    
+        
+            ${subsystems.test.simpleProp1}
+        
+	    
+        
+            ${subsystems.test.simpleProp2}
+        
+		
+        
+            ${subsystems.test.simpleProp3}
+        
+        
+            
+        
+	
+
+    
+    
+        
+    
+	
+   
+      
+         An extra bean
+      
+   
+	
+
\ No newline at end of file
diff --git a/source/test-resources/alfresco/subsystems/testsubsystem/testType/testProps.properties b/source/test-resources/alfresco/subsystems/testsubsystem/testType/testProps.properties
new file mode 100644
index 0000000000..6d5c7d029f
--- /dev/null
+++ b/source/test-resources/alfresco/subsystems/testsubsystem/testType/testProps.properties
@@ -0,0 +1,3 @@
+subsystems.test.simpleProp1=Subsystem Default1
+subsystems.test.simpleProp2=false
+subsystems.test.simpleProp3=Subsystem Default3
\ No newline at end of file
diff --git a/source/test-resources/subsystem-test-context.xml b/source/test-resources/subsystem-test-context.xml
new file mode 100644
index 0000000000..91d12f9f28
--- /dev/null
+++ b/source/test-resources/subsystem-test-context.xml
@@ -0,0 +1,21 @@
+
+
+
+
+    
+        
+            true
+        
+        
+            testType
+        
+        
+            
+               
+                   org.alfresco.repo.management.subsystems.test.TestBean
+               
+            
+        
+    
+
+
\ No newline at end of file