Search code examples
javaxml-parsingapache-commons-digester

Parse into Properties with default values using Commons Digester


<properties>
   <property name="p1">v1</property>
   <property name="p2">v2</property>
</properties>

I want to parse this into a Properties object with {"p1"="v1", "p2"="v2"}. I was able to do this much using commons digester.

forPattern("properties").createObject()
        .ofType(Properties.class);
forPattern("properties/property")
        .callMethod("put").withParamCount(2)
        .withParamTypes(Object.class, Object.class).then()
        .callParam().fromAttribute("name").ofIndex(0).then()
        .callParam().ofIndex(1);

Additionally I also wanted to pass a defaults Properties object that I have. ie instead of new Properties(), I need to do new Properties(defaults) to create the Properties instance. I am aware of .usingConstructor(Properties.class).then() but did not find a way to pass an existing Properties object as an argument.

I am using v3.3.2. Any help is greatly appreciated


Solution

  • Well I figured out this can be done using the FactoryCreateRule

    class PropertiesFactory extends AbstractObjectCreationFactory<Properties> {
    
        Properties defaultProperties;
    
        public PropertiesFactory(Properties defaultProperties) {
            super();
            this.defaultProperties = defaultProperties;
        }
    
        @Override
        public Properties createObject(Attributes attributes) throws Exception {
            return new Properties(defaultProperties);
        }
    
    }
    
    ...
    ...
    
    forPattern("properties").factoryCreate()
            .usingFactory(new PropertiesFactory(defaultProperties));
    forPattern("properties/property")
            .callMethod("put").withParamCount(2)
            .withParamTypes(Object.class, Object.class).then()
            .callParam().fromAttribute("name").ofIndex(0).then()
            .callParam().ofIndex(1);