001/* $Id: VariableSubstitutor.java 992060 2010-09-02 19:09:47Z simonetripodi $
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
019package org.apache.commons.digester.substitution;
020
021import org.apache.commons.digester.Substitutor;
022
023import 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 */
035public 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    @Override
083    public Attributes substitute(Attributes attributes) {
084        Attributes results = attributes;
085        if (attributesExpander != null) {
086            variableAttributes.init(attributes, attributesExpander);
087            results = variableAttributes;
088        }
089        return results;
090    }
091    
092    /**
093     * Substitutes for the body text.
094     * This method may substitute values into the body text of the
095     * elements that Digester parses.
096     *
097     * @param bodyText the body text (as passed to <code>Digester</code>)
098     * @return the body text to be passed to the <code>Rule</code> implementations
099     */
100    @Override
101    public String substitute(String bodyText) {
102        String result = bodyText;
103        if (bodyTextExpander != null) {
104            result = bodyTextExpander.expand(bodyText);
105        }
106        return result;
107    }
108}