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
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    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}