While creating import services I want some configuration mechanism for (not just) BatchProcessor. I like Alfresco’s *-config-custom.xml files (aka Spring framework XMLConfigService), so I did simple custom config service.

Anyone, who customized Alfresco, knows format of this file (web-client-config-custom.xml). I put that structure to new file – mis-config-custom.xml:

<alfresco-config>
    <config evaluator="string-compare" condition="imports">
        <processor>
            <worker-threads-num>3</worker-threads-num>
            <batch-size-num>6</batch-size-num>
            <split-transactions>false</split-transactions>
            <logging-interval>1000</logging-interval>
        </processor>
        <token>
            <time-refresh>1000</time-refresh>
            <time-expiration>20000</time-expiration>
        </token>
    </config>
</alfresco-config>

Please note those constants are just for ilustration purposes now, more on them in scripting series. My MisConfigService extends org.springframework.extensions.config.xml.XMLConfigService, but uses nothing from that class (except init method in bootstrap), I just added some statics inside to keep things together:

public class MisConfigService extends XMLConfigService {
    public MisConfigService(ConfigSource configSource) {
        super(configSource);
    }

    public static String getChildValue(Config config, String elementId, String childName, String defaultValue) {
        ConfigElement myConfig = config.getConfigElement(elementId);
        String result = myConfig.getChildValue(childName);

        return (result==null ? defaultValue : result);
    }

    public static Integer getChildValue(Config config, String elementId, String childName, Integer defaultValue) {
        Integer result = defaultValue;
        try {
            String number = getChildValue(config, elementId, childName, defaultValue.toString());
            result = Integer.parseInt(number);
        } finally { /* O:-) */ }
        return result;
    }

        . . .
}

To instantiate this service just add bean definition with UrlConfigSource(-s), which defines path to custom xml configuration:

<bean id="misConfigService" class="cz.mis.service.MisConfigService" init-method="init">
    <constructor-arg>
        <bean class="org.springframework.extensions.config.source.UrlConfigSource">
            <constructor-arg>
                <list>
                    <value>classpath:alfresco/extension/mis-config-custom.xml</value>
                </list>
            </constructor-arg>
        </bean>
    </constructor-arg>
</bean>

Now it’s possible to access those properties in code like this:

org.springframework.extensions.config.Config config = configService.getConfig(imports");
Boolean splitTransactions = MisConfigService.getChildValue(config, "processor", "split-transactions", false);

It’s also possible to access attributes of nodes in that config:

ConfigElement myConfig = config.getConfigElement("config-element");
for(ConfigElement child : myConfig.getChildren()) {
    // child.getAttributes()
    // child.getName()
    // child.getValue()
}

That’s all! And now for something completely different! I also spent some time trying to get properties files working and putting those properties into Spring configurations. There’s nice solved thread in Alfresco forums. Prefix helps:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath*:alfresco/extension/mis-settings.properties</value>
        </list>
    </property>
    <property name="ignoreResourceNotFound" value="true" />
    <property name="placeholderPrefix" value="${mis:" />
    <property name="placeholderSuffix" value="}" />
</bean>

<!-- and I can use stuff from properties file with prefix -->
<bean class="foo.bar.Example">
    <property name="fooAttribute">
        <value>${mis:some.sample.property}</value>
    </property>
</bean>