home | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Commons Digester example source code file (DigesterRuleParser.java)

This example Commons Digester source code file (DigesterRuleParser.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Commons Digester tags/keywords

abstractobjectcreationfactory, digesterruleparser, dom, io, net, network, object, object, override, override, patternrule, patternrule, patternstack, rule, rules, sax, setnestedpropertiesrule, string, string, util

The Commons Digester DigesterRuleParser.java source code

/* $Id: DigesterRuleParser.java 992060 2010-09-02 19:09:47Z simonetripodi $
 *
 * 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.
 */


package org.apache.commons.digester.xmlrules;


import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import java.util.StringTokenizer;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.digester.AbstractObjectCreationFactory;
import org.apache.commons.digester.BeanPropertySetterRule;
import org.apache.commons.digester.CallMethodRule;
import org.apache.commons.digester.CallParamRule;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.FactoryCreateRule;
import org.apache.commons.digester.NodeCreateRule;
import org.apache.commons.digester.ObjectCreateRule;
import org.apache.commons.digester.ObjectParamRule;
import org.apache.commons.digester.Rule;
import org.apache.commons.digester.RuleSetBase;
import org.apache.commons.digester.Rules;
import org.apache.commons.digester.SetNestedPropertiesRule;
import org.apache.commons.digester.SetNextRule;
import org.apache.commons.digester.SetPropertiesRule;
import org.apache.commons.digester.SetPropertyRule;
import org.apache.commons.digester.SetRootRule;
import org.apache.commons.digester.SetTopRule;
import org.w3c.dom.Node;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;


/**
 * This is a RuleSet that parses XML into Digester rules, and then
 * adds those rules to a 'target' Digester.
 *
 * @since 1.2
 */

public class DigesterRuleParser extends RuleSetBase {
    
    public static final String DIGESTER_PUBLIC_ID = "-//Jakarta Apache //DTD digester-rules XML V1.0//EN";
    
    /**
     * path to the DTD
     */
    private String digesterDtdUrl;
    
    /**
     * This is the digester to which we are adding the rules that we parse
     * from the Rules XML document.
     */
    protected Digester targetDigester;

    /** See {@link #setBasePath}. */
    protected String basePath = "";
    
    /**
     * A stack whose toString method returns a '/'-separated concatenation
     * of all the elements in the stack.
     */
    protected class PatternStack<E> extends Stack {

        private static final long serialVersionUID = 1L;

        @Override
        public String toString() {
            StringBuffer str = new StringBuffer();
            for (int i = 0; i < size(); i++) {
                String elem = get(i).toString();
                if (elem.length() > 0) {
                    if (str.length() > 0) {
                        str.append('/');
                    }
                    str.append(elem);
                }
            }
            return str.toString();
        }
    }
    
    /**
     * A stack used to maintain the current pattern. The Rules XML document
     * type allows nesting of patterns. If an element defines a matching
     * pattern, the resulting pattern is a concatenation of that pattern with
     * all the ancestor elements' patterns. Hence the need for a stack.
     */
    protected PatternStack<String> patternStack;
    
    /**
     * Used to detect circular includes
     */
    private Set<String> includedFiles = new HashSet();
    
    /**
     * Constructs a DigesterRuleParser. This object will be inoperable
     * until the target digester is set, via <code>setTarget(Digester)
     */
    public DigesterRuleParser() {
        patternStack = new PatternStack<String>();
    }
    
    /**
     * Constructs a rule set for converting XML digester rule descriptions
     * into Rule objects, and adding them to the given Digester
     * @param targetDigester the Digester to add the rules to
     */
    public DigesterRuleParser(Digester targetDigester) {
        this.targetDigester = targetDigester;
        patternStack = new PatternStack<String>();
    }
    
    /**
     * Constructs a rule set for parsing an XML digester rule file that
     * has been included within an outer XML digester rule file. In this
     * case, we must pass the pattern stack and the target digester
     * to the rule set, as well as the list of files that have already
     * been included, for cycle detection.
     * @param targetDigester the Digester to add the rules to
     * @param stack Stack containing the prefix pattern string to be prepended
     * to any pattern parsed by this rule set.
     */
    private DigesterRuleParser(Digester targetDigester,
                                PatternStack<String> stack, Set includedFiles) {
        this.targetDigester = targetDigester;
        patternStack = stack;
        this.includedFiles = includedFiles;
    }
    
    /**
     * Sets the digester into which to add the parsed rules
     * @param d the Digester to add the rules to
     */
    public void setTarget(Digester d) {
        targetDigester = d;
    }
    
    /**
     * Set a base pattern beneath which all the rules loaded by this
     * object will be registered. If this string is not empty, and does
     * not end in a "/", then one will be added.
     *
     * @since 1.6
     */
    public void setBasePath(String path) {
        if (path == null) {
            basePath = "";
        }
        else if ((path.length() > 0) && !path.endsWith("/")) {
            basePath = path + "/";
        } else {
            basePath = path;
        }
    }

    /**
     * Sets the location of the digester rules DTD. This is the DTD used
     * to validate the rules XML file.
     */
    public void setDigesterRulesDTD(String dtdURL) {
        digesterDtdUrl = dtdURL;
    }
    
    /**
     * Returns the location of the DTD used to validate the digester rules
     * XML document.
     */
    protected String getDigesterRulesDTD() {
        //ClassLoader classLoader = getClass().getClassLoader();
        //URL url = classLoader.getResource(DIGESTER_DTD_PATH);
        //return url.toString();
        return digesterDtdUrl;
    }
    
    /**
     * Adds a rule the the target digester. After a rule has been created by
     * parsing the XML, it is added to the digester by calling this method.
     * Typically, this method is called via reflection, when executing
     * a SetNextRule, from the Digester that is parsing the rules XML.
     * @param rule a Rule to add to the target digester.
     */
    public void add(Rule rule) {
        targetDigester.addRule(
            basePath + patternStack.toString(), rule);
    }
    
    
    /**
     * Add to the given digester the set of Rule instances used to parse an XML
     * document defining Digester rules. When the digester parses an XML file,
     * it will add the resulting rules & patterns to the 'target digester'
     * that was passed in this RuleSet's constructor.<P>
     * If you extend this class to support additional rules, your implementation
     * should of this method should call this implementation first: i.e.
     * <code>super.addRuleInstances(digester);
     */
    @Override
    public void addRuleInstances(Digester digester) {
        final String ruleClassName = Rule.class.getName();
        digester.register(DIGESTER_PUBLIC_ID, getDigesterRulesDTD());
        
        digester.addRule("*/pattern", new PatternRule("value"));
        
        digester.addRule("*/include", new IncludeRule());
        
        digester.addFactoryCreate("*/bean-property-setter-rule", new BeanPropertySetterRuleFactory());
        digester.addRule("*/bean-property-setter-rule", new PatternRule("pattern"));
        digester.addSetNext("*/bean-property-setter-rule", "add", ruleClassName);
        
        digester.addFactoryCreate("*/call-method-rule", new CallMethodRuleFactory());
        digester.addRule("*/call-method-rule", new PatternRule("pattern"));
        digester.addSetNext("*/call-method-rule", "add", ruleClassName);

        digester.addFactoryCreate("*/object-param-rule", new ObjectParamRuleFactory());
        digester.addRule("*/object-param-rule", new PatternRule("pattern"));
        digester.addSetNext("*/object-param-rule", "add", ruleClassName);
        
        digester.addFactoryCreate("*/call-param-rule", new CallParamRuleFactory());
        digester.addRule("*/call-param-rule", new PatternRule("pattern"));
        digester.addSetNext("*/call-param-rule", "add", ruleClassName);
        
        digester.addFactoryCreate("*/factory-create-rule", new FactoryCreateRuleFactory());
        digester.addRule("*/factory-create-rule", new PatternRule("pattern"));
        digester.addSetNext("*/factory-create-rule", "add", ruleClassName);
        
        digester.addFactoryCreate("*/object-create-rule", new ObjectCreateRuleFactory());
        digester.addRule("*/object-create-rule", new PatternRule("pattern"));
        digester.addSetNext("*/object-create-rule", "add", ruleClassName);
        
        digester.addFactoryCreate("*/node-create-rule", new NodeCreateRuleFactory());
        digester.addRule("*/node-create-rule", new PatternRule("pattern"));
        digester.addSetNext("*/node-create-rule", "add", ruleClassName);
        
        digester.addFactoryCreate("*/set-properties-rule", new SetPropertiesRuleFactory());
        digester.addRule("*/set-properties-rule", new PatternRule("pattern"));
        digester.addSetNext("*/set-properties-rule", "add", ruleClassName);
        
        digester.addRule("*/set-properties-rule/alias", new SetPropertiesAliasRule());
        
        digester.addFactoryCreate("*/set-property-rule", new SetPropertyRuleFactory());
        digester.addRule("*/set-property-rule", new PatternRule("pattern"));
        digester.addSetNext("*/set-property-rule", "add", ruleClassName);
        
        digester.addFactoryCreate("*/set-nested-properties-rule", new SetNestedPropertiesRuleFactory());
        digester.addRule("*/set-nested-properties-rule", new PatternRule("pattern"));
        digester.addSetNext("*/set-nested-properties-rule", "add", ruleClassName);
        
        digester.addRule("*/set-nested-properties-rule/alias", new SetNestedPropertiesAliasRule());
        
        digester.addFactoryCreate("*/set-top-rule", new SetTopRuleFactory());
        digester.addRule("*/set-top-rule", new PatternRule("pattern"));
        digester.addSetNext("*/set-top-rule", "add", ruleClassName);
        
        digester.addFactoryCreate("*/set-next-rule", new SetNextRuleFactory());
        digester.addRule("*/set-next-rule", new PatternRule("pattern"));
        digester.addSetNext("*/set-next-rule", "add", ruleClassName);
        digester.addFactoryCreate("*/set-root-rule", new SetRootRuleFactory());
        digester.addRule("*/set-root-rule", new PatternRule("pattern"));
        digester.addSetNext("*/set-root-rule", "add", ruleClassName);
    }
    
    
    /**
     * A rule for extracting the pattern matching strings from the rules XML.
     * In the digester-rules document type, a pattern can either be declared
     * in the 'value' attribute of a <pattern> element (in which case the pattern
     * applies to all rules elements contained within the <pattern> element),
     * or it can be declared in the optional 'pattern' attribute of a rule
     * element.
     */
    private class PatternRule extends Rule {
        
        private String attrName;
        private String pattern = null;
        
        /**
         * @param attrName The name of the attribute containing the pattern
         */
        public PatternRule(String attrName) {
            super();
            this.attrName = attrName;
        }
        
        /**
         * If a pattern is defined for the attribute, push it onto the
         * pattern stack.
         */
        @Override
        public void begin(Attributes attributes) {
            pattern = attributes.getValue(attrName);
            if (pattern != null) {
                patternStack.push(pattern);
            }
        }
        
        /**
         * If there was a pattern for this element, pop it off the pattern
         * stack.
         */
        @Override
        public void end() {
            if (pattern != null) {
                patternStack.pop();
            }
        }
    }
    
    /**
     * A rule for including one rules XML file within another. Included files
     * behave as if they are 'macro-expanded' within the includer. This means
     * that the values of the pattern stack are prefixed to every pattern
     * in the included rules. <p>This rule will detect 'circular' includes,
     * which would result in infinite recursion. It throws a
     * CircularIncludeException when a cycle is detected, which will terminate
     * the parse.
     */
    private class IncludeRule extends Rule {
        public IncludeRule() {
            super();
        }
        
        /**
         * To include a rules xml file, we instantiate another Digester, and
         * another DigesterRulesRuleSet. We pass the
         * pattern stack and the target Digester to the new rule set, and
         * tell the Digester to parse the file.
         */
        @Override
        public void begin(Attributes attributes) throws Exception {
            // The path attribute gives the URI to another digester rules xml file
            String fileName = attributes.getValue("path");
            if (fileName != null && fileName.length() > 0) {
                includeXMLRules(fileName);
            }
            
            // The class attribute gives the name of a class that implements
            // the DigesterRulesSource interface
            String className = attributes.getValue("class");
            if (className != null && className.length() > 0) {
                includeProgrammaticRules(className);
            }
        }
        
        /**
         * Creates another DigesterRuleParser, and uses it to extract the rules
         * out of the give XML file. The contents of the current pattern stack
         * will be prepended to all of the pattern strings parsed from the file.
         */
        private void includeXMLRules(String fileName)
                        throws IOException, SAXException, CircularIncludeException {
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
            if (cl == null) {
                cl = DigesterRuleParser.this.getClass().getClassLoader();
            }
            URL fileURL = cl.getResource(fileName);
            if (fileURL == null) {
                throw new FileNotFoundException("File \"" + fileName + "\" not found.");
            }
            fileName = fileURL.toExternalForm();
            if (includedFiles.add(fileName) == false) {
                // circular include detected
                throw new CircularIncludeException(fileName);
            }
            // parse the included xml file
            DigesterRuleParser includedSet =
                        new DigesterRuleParser(targetDigester, patternStack, includedFiles);
            includedSet.setDigesterRulesDTD(getDigesterRulesDTD());
            Digester digester = new Digester();
            digester.addRuleSet(includedSet);
            digester.push(DigesterRuleParser.this);
            digester.parse(fileName);
            includedFiles.remove(fileName);
        }
        
        /**
         * Creates an instance of the indicated class. The class must implement
         * the DigesterRulesSource interface. Passes the target digester to
         * that instance. The DigesterRulesSource instance is supposed to add
         * rules into the digester. The contents of the current pattern stack
         * will be automatically prepended to all of the pattern strings added
         * by the DigesterRulesSource instance.
         */
        private void includeProgrammaticRules(String className)
                        throws ClassNotFoundException, ClassCastException,
                        InstantiationException, IllegalAccessException {
            
            Class<?> cls = Class.forName(className);
            DigesterRulesSource rulesSource = (DigesterRulesSource) cls.newInstance();
            
            // wrap the digester's Rules object, to prepend pattern
            Rules digesterRules = targetDigester.getRules();
            Rules prefixWrapper =
                    new RulesPrefixAdapter(patternStack.toString(), digesterRules);
            
            targetDigester.setRules(prefixWrapper);
            try {
                rulesSource.getRules(targetDigester);
            } finally {
                // Put the unwrapped rules back
                targetDigester.setRules(digesterRules);
            }
        }
    }
    
    
    /**
     * Wraps a Rules object. Delegates all the Rules interface methods
     * to the underlying Rules object. Overrides the add method to prepend
     * a prefix to the pattern string.
     */
    private class RulesPrefixAdapter implements Rules {
        
        private Rules delegate;
        private String prefix;
        
        /**
         * @param patternPrefix the pattern string to prepend to the pattern
         * passed to the add method.
         * @param rules The wrapped Rules object. All of this class's methods
         * pass through to this object.
         */
        public RulesPrefixAdapter(String patternPrefix, Rules rules) {
            prefix = patternPrefix;
            delegate = rules;
        }
        
        /**
         * Register a new Rule instance matching a pattern which is constructed
         * by concatenating the pattern prefix with the given pattern.
         */
        public void add(String pattern, Rule rule) {
            StringBuffer buffer = new StringBuffer();
            buffer.append(prefix);
            if (!pattern.startsWith("/")) {
                buffer.append('/'); 
            }
            buffer.append(pattern);
            delegate.add(buffer.toString(), rule);
        }
        
        /**
         * This method passes through to the underlying Rules object.
         */
        public void clear() {
            delegate.clear();
        }
        
        /**
         * This method passes through to the underlying Rules object.
         */
        public Digester getDigester() {
            return delegate.getDigester();
        }
        
        /**
         * This method passes through to the underlying Rules object.
         */
        public String getNamespaceURI() {
            return delegate.getNamespaceURI();
        }
        
        /**
         * @deprecated Call match(namespaceURI,pattern) instead.
         */
        @Deprecated
        public List<Rule> match(String pattern) {
            return delegate.match(pattern);
        }
        
        /**
         * This method passes through to the underlying Rules object.
         */
        public List<Rule> match(String namespaceURI, String pattern) {
            return delegate.match(namespaceURI, pattern);
        }
        
        /**
         * This method passes through to the underlying Rules object.
         */
        public List<Rule> rules() {
            return delegate.rules();
        }
        
        /**
         * This method passes through to the underlying Rules object.
         */
        public void setDigester(Digester digester) {
            delegate.setDigester(digester);
        }
        
        /**
         * This method passes through to the underlying Rules object.
         */
        public void setNamespaceURI(String namespaceURI) {
            delegate.setNamespaceURI(namespaceURI);
        }
    }
    
    
    ///////////////////////////////////////////////////////////////////////
    // Classes beyond this point are ObjectCreationFactory implementations,
    // used to create Rule objects and initialize them from SAX attributes.
    ///////////////////////////////////////////////////////////////////////
    
    /**
     * Factory for creating a BeanPropertySetterRule.
     */
    private class BeanPropertySetterRuleFactory extends AbstractObjectCreationFactory {
        @Override
        public Object createObject(Attributes attributes) throws Exception {
            Rule beanPropertySetterRule = null;
            String propertyname = attributes.getValue("propertyname");
                
            if (propertyname == null) {
                // call the setter method corresponding to the element name.
                beanPropertySetterRule = new BeanPropertySetterRule();
            } else {
                beanPropertySetterRule = new BeanPropertySetterRule(propertyname);
            }
            
            return beanPropertySetterRule;
        }
        
    }

    /**
     * Factory for creating a CallMethodRule.
     */
    protected class CallMethodRuleFactory extends AbstractObjectCreationFactory {
        @Override
        public Object createObject(Attributes attributes) {
            Rule callMethodRule = null;
            String methodName = attributes.getValue("methodname");

            // Select which element is to be the target. Default to zero,
            // ie the top object on the stack.
            int targetOffset = 0;
            String targetOffsetStr = attributes.getValue("targetoffset");
            if (targetOffsetStr != null) {
                targetOffset = Integer.parseInt(targetOffsetStr);
            }

            if (attributes.getValue("paramcount") == null) {
                // call against empty method
                callMethodRule = new CallMethodRule(targetOffset, methodName);
            
            } else {
                int paramCount = Integer.parseInt(attributes.getValue("paramcount"));
                
                String paramTypesAttr = attributes.getValue("paramtypes");
                if (paramTypesAttr == null || paramTypesAttr.length() == 0) {
                    callMethodRule = new CallMethodRule(targetOffset, methodName, paramCount);
                } else {
                    String[] paramTypes = getParamTypes(paramTypesAttr);
                    callMethodRule = new CallMethodRule(
                        targetOffset, methodName, paramCount, paramTypes);
                }
            }
            return callMethodRule;
        }

        /**
         * Process the comma separated list of paramTypes
         * into an array of String class names
         */
        private String[] getParamTypes(String paramTypes) {
            String[] paramTypesArray;
            if( paramTypes != null ) {
                ArrayList<String> paramTypesList = new ArrayList();
                StringTokenizer tokens = new StringTokenizer(
                        paramTypes, " \t\n\r,");
                while (tokens.hasMoreTokens()) {
                    paramTypesList.add(tokens.nextToken());
                }
                paramTypesArray = paramTypesList.toArray(new String[0]);
            } else {
                paramTypesArray = new String[0];
            }
            return paramTypesArray;
        }
    }
    
    /**
     * Factory for creating a CallParamRule.
     */
    protected class CallParamRuleFactory extends AbstractObjectCreationFactory {
    
        @Override
        public Object createObject(Attributes attributes) {
            // create callparamrule
            int paramIndex = Integer.parseInt(attributes.getValue("paramnumber"));
            String attributeName = attributes.getValue("attrname");
            String fromStack = attributes.getValue("from-stack");
            String stackIndex = attributes.getValue("stack-index");
            Rule callParamRule = null;

            if (attributeName == null) {
                if (stackIndex != null) {                    
                    callParamRule = new CallParamRule(
                        paramIndex, Integer.parseInt(stackIndex));                
                } else if (fromStack != null) {                
                    callParamRule = new CallParamRule(
                        paramIndex, Boolean.valueOf(fromStack).booleanValue());                
                } else {
                    callParamRule = new CallParamRule(paramIndex);     
                }
            } else {
                if (fromStack == null) {
                    callParamRule = new CallParamRule(paramIndex, attributeName);                    
                } else {
                    // specifying both from-stack and attribute name is not allowed
                    throw new RuntimeException(
                        "Attributes from-stack and attrname cannot both be present.");
                }
            }
            return callParamRule;
        }
    }
    
    /**
     * Factory for creating a ObjectParamRule
     */
    protected class ObjectParamRuleFactory extends AbstractObjectCreationFactory {
        @Override
        public Object createObject(Attributes attributes) throws Exception {
            // create callparamrule
            int paramIndex = Integer.parseInt(attributes.getValue("paramnumber"));
            String attributeName = attributes.getValue("attrname");
            String type = attributes.getValue("type");
            String value = attributes.getValue("value");

            Rule objectParamRule = null;

            // type name is requried
            if (type == null) {
                throw new RuntimeException("Attribute 'type' is required.");
            }

            // create object instance
            Object param = null;
            Class<?> clazz = Class.forName(type);
            if (value == null) {
                param = clazz.newInstance();
            } else {
                param = ConvertUtils.convert(value, clazz);
            }

            if (attributeName == null) {
                objectParamRule = new ObjectParamRule(paramIndex, param);
            } else {
                objectParamRule = new ObjectParamRule(paramIndex, attributeName, param);
            }
            return objectParamRule;
        }
     }
    
        /**
         * Factory for creating a NodeCreateRule
         */
    protected class NodeCreateRuleFactory extends AbstractObjectCreationFactory {

        @Override
        public Object createObject(Attributes attributes) throws Exception {

            String nodeType = attributes.getValue("type");
            if (nodeType == null || "".equals(nodeType)) {

                // uses Node.ELEMENT_NODE
                return new NodeCreateRule();
            } else if ("element".equals(nodeType)) {

                return new NodeCreateRule(Node.ELEMENT_NODE);
            } else if ("fragment".equals(nodeType)) {

                return new NodeCreateRule(Node.DOCUMENT_FRAGMENT_NODE);
            } else {

                throw new RuntimeException(
                        "Unrecognized node type: "
                                + nodeType
                                + ".  This attribute is optional or can have a value of element|fragment.");
            }
        }
    }    
    
    /**
     * Factory for creating a FactoryCreateRule
     */
    protected class FactoryCreateRuleFactory extends AbstractObjectCreationFactory {
        @Override
        public Object createObject(Attributes attributes) {
            String className = attributes.getValue("classname");
            String attrName = attributes.getValue("attrname");
            boolean ignoreExceptions = 
                "true".equalsIgnoreCase(attributes.getValue("ignore-exceptions"));
            return (attrName == null || attrName.length() == 0) ?
                new FactoryCreateRule( className, ignoreExceptions) :
                new FactoryCreateRule( className, attrName, ignoreExceptions);
        }
    }
    
    /**
     * Factory for creating a ObjectCreateRule
     */
    protected class ObjectCreateRuleFactory extends AbstractObjectCreationFactory {
        @Override
        public Object createObject(Attributes attributes) {
            String className = attributes.getValue("classname");
            String attrName = attributes.getValue("attrname");
            return (attrName == null || attrName.length() == 0) ?
                new ObjectCreateRule( className) :
                new ObjectCreateRule( className, attrName);
        }
    }
    
    /**
     * Factory for creating a SetPropertiesRule
     */
    protected class SetPropertiesRuleFactory extends AbstractObjectCreationFactory {
        @Override
        public Object createObject(Attributes attributes) {
                return new SetPropertiesRule();
        }
    }
    
    /**
     * Factory for creating a SetPropertyRule
     */
    protected class SetPropertyRuleFactory extends AbstractObjectCreationFactory {
        @Override
        public Object createObject(Attributes attributes) {
            String name = attributes.getValue("name");
            String value = attributes.getValue("value");
            return new SetPropertyRule( name, value);
        }
    }
    
    /**
     * Factory for creating a SetNestedPropertiesRule
     */
    protected class SetNestedPropertiesRuleFactory extends AbstractObjectCreationFactory {
        @Override
        public Object createObject(Attributes attributes) {
           boolean allowUnknownChildElements = 
                "true".equalsIgnoreCase(attributes.getValue("allow-unknown-child-elements"));
                SetNestedPropertiesRule snpr = new SetNestedPropertiesRule();
                snpr.setAllowUnknownChildElements( allowUnknownChildElements );
                return snpr;
        }
    }
    
    /**
     * Factory for creating a SetTopRuleFactory
     */
    protected class SetTopRuleFactory extends AbstractObjectCreationFactory {
        @Override
        public Object createObject(Attributes attributes) {
            String methodName = attributes.getValue("methodname");
            String paramType = attributes.getValue("paramtype");
            return (paramType == null || paramType.length() == 0) ?
                new SetTopRule( methodName) :
                new SetTopRule( methodName, paramType);
        }
    }
    
    /**
     * Factory for creating a SetNextRuleFactory
     */
    protected class SetNextRuleFactory extends AbstractObjectCreationFactory {
        @Override
        public Object createObject(Attributes attributes) {
            String methodName = attributes.getValue("methodname");
            String paramType = attributes.getValue("paramtype");
            return (paramType == null || paramType.length() == 0) ?
                new SetNextRule( methodName) :
                new SetNextRule( methodName, paramType);
        }
    }
    
    /**
     * Factory for creating a SetRootRuleFactory
     */
    protected class SetRootRuleFactory extends AbstractObjectCreationFactory {
        @Override
        public Object createObject(Attributes attributes) {
            String methodName = attributes.getValue("methodname");
            String paramType = attributes.getValue("paramtype");
            return (paramType == null || paramType.length() == 0) ?
                new SetRootRule( methodName) :
                new SetRootRule( methodName, paramType);
        }
    }
    
    /**
     * A rule for adding a attribute-property alias to the custom alias mappings of
     * the containing SetPropertiesRule rule.
     */
    protected class SetPropertiesAliasRule extends Rule {
        
        /**
         * <p>Base constructor.

*/ public SetPropertiesAliasRule() { super(); } /** * Add the alias to the SetPropertiesRule object created by the * enclosing <set-properties-rule> tag. */ @Override public void begin(Attributes attributes) { String attrName = attributes.getValue("attr-name"); String propName = attributes.getValue("prop-name"); SetPropertiesRule rule = (SetPropertiesRule) digester.peek(); rule.addAlias(attrName, propName); } } /** * A rule for adding a attribute-property alias to the custom alias mappings of * the containing SetNestedPropertiesRule rule. */ protected class SetNestedPropertiesAliasRule extends Rule { /** * <p>Base constructor.

*/ public SetNestedPropertiesAliasRule() { super(); } /** * Add the alias to the SetNestedPropertiesRule object created by the * enclosing <set-nested-properties-rule> tag. */ @Override public void begin(Attributes attributes) { String attrName = attributes.getValue("attr-name"); String propName = attributes.getValue("prop-name"); SetNestedPropertiesRule rule = (SetNestedPropertiesRule) digester.peek(); rule.addAlias(attrName, propName); } } }

Other Commons Digester examples (source code examples)

Here is a short list of links related to this Commons Digester DigesterRuleParser.java source code file:



my book on functional programming

 

new blog posts

 

Copyright 1998-2019 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.