001    /* $Id: VariableSubstitutor.java 471661 2006-11-06 08:09:25Z skitching $
002     *
003     * Licensed to the Apache Software Foundation (ASF) under one or more
004     * contributor license agreements.  See the NOTICE file distributed with
005     * this work for additional information regarding copyright ownership.
006     * The ASF licenses this file to You under the Apache License, Version 2.0
007     * (the "License"); you may not use this file except in compliance with
008     * the License.  You may obtain a copy of the License at
009     * 
010     *      http://www.apache.org/licenses/LICENSE-2.0
011     * 
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */ 
018    
019    package org.apache.commons.digester.substitution;
020    
021    import org.apache.commons.digester.Substitutor;
022    
023    import org.xml.sax.Attributes;
024    
025    /**
026     * Substitutor implementation that support variable replacement
027     * for both attributes and body text.
028     * The actual expansion of variables into text is delegated to {@link VariableExpander}
029     * implementations.
030     * Supports setting an expander just for body text or just for attributes.
031     * Also supported is setting no expanders for body text and for attributes. 
032     *
033     * @since 1.6
034     */
035    public class VariableSubstitutor extends Substitutor {
036    
037        /** 
038         * The expander to be used to expand variables in the attributes.
039         * Null when no expansion should be performed.
040         */
041        private VariableExpander attributesExpander;
042        
043        /** 
044         * Attributes implementation that (lazily) performs variable substitution.
045         * Will be lazily created when needed then reused.
046         */
047        private VariableAttributes variableAttributes;
048        
049        /** 
050         * The expander to be used to expand variables in the body text.
051         * Null when no expansion should be performed.
052         */
053        private VariableExpander bodyTextExpander;
054        
055        /**
056         * Constructs a Substitutor which uses the same VariableExpander for both
057         * body text and attibutes.
058         * @param expander VariableExpander implementation, 
059         * null if no substitutions are to be performed
060         */
061        public VariableSubstitutor(VariableExpander expander) {
062            this(expander, expander);
063        }
064        
065        /**
066         * Constructs a Substitutor.
067         * @param attributesExpander VariableExpander implementation to be used for attributes, 
068         * null if no attribute substitutions are to be performed
069         * @param bodyTextExpander VariableExpander implementation to be used for bodyTextExpander, 
070         * null if no attribute substitutions are to be performed     
071         */
072        public VariableSubstitutor(VariableExpander attributesExpander, VariableExpander bodyTextExpander) {
073            this.attributesExpander = attributesExpander;
074            this.bodyTextExpander = bodyTextExpander;
075            variableAttributes = new VariableAttributes();
076        }    
077    
078        /**
079         * Substitutes the attributes (before they are passed to the 
080         * <code>Rule</code> implementations's)
081         */
082        public Attributes substitute(Attributes attributes) {
083            Attributes results = attributes;
084            if (attributesExpander != null) {
085                variableAttributes.init(attributes, attributesExpander);
086                results = variableAttributes;
087            }
088            return results;
089        }
090        
091        /**
092         * Substitutes for the body text.
093         * This method may substitute values into the body text of the
094         * elements that Digester parses.
095         *
096         * @param bodyText the body text (as passed to <code>Digester</code>)
097         * @return the body text to be passed to the <code>Rule</code> implementations
098         */
099        public String substitute(String bodyText) {
100            String result = bodyText;
101            if (bodyTextExpander != null) {
102                result = bodyTextExpander.expand(bodyText);
103            }
104            return result;
105        }
106    }