    001    /* $Id: VariableAttributes.java 729129 2008-12-23 21:27:42Z rahul $
    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
    020    package org.apache.commons.digester.substitution;
    021
    022    import org.xml.sax.Attributes;
    023
    024    import java.util.ArrayList;
    025
    026
    027    /**
    028     * <p>Wrapper for an org.xml.sax.Attributes object which expands any
    029     * "variables" referenced in the attribute value via ${foo} or similar.
    030     * This is only done when something actually asks for the attribute value,
    031     * thereby imposing no performance penalty if the attribute is not used.</p>
    032     *
    033     * @since 1.6
    034     */
    035
    036    public class VariableAttributes implements Attributes {
    037
    038        // list of mapped attributes.
    039        private ArrayList<String> values = new ArrayList<String>(10);
    040
    041        private Attributes attrs;
    042        private VariableExpander expander;
    043
    044        // ------------------- Public Methods
    045
    046        /**
    047         * Specify which attributes class this object is a proxy for.
    048         */
    049        public void init(Attributes attrs, VariableExpander expander) {
    050            this.attrs = attrs;
    051            this.expander = expander;
    052
    053            // I hope this doesn't release the memory for this array; for
    054            // efficiency, this should just mark the array as being size 0.
    055            values.clear();
    056        }
    057
    058        public String getValue(int index) {
    059            if (index >= values.size()) {
    060                // Expand the values array with null elements, so the later
    061                // call to set(index, s) works ok.
    062                //
    063                // Unfortunately, there is no easy way to set the size of
    064                // an arraylist; we must repeatedly add null elements to it..
    065                values.ensureCapacity(index+1);
    066                for(int i = values.size(); i<= index; ++i) {
    067                    values.add(null);
    068                }
    069            }
    070
    071            String s = values.get(index);
    072
    073            if (s == null) {
    074                // we have never been asked for this value before.
    075                // get the real attribute value and perform substitution
    076                // on it.
    077                s = attrs.getValue(index);
    078                if (s != null) {
    079                    s = expander.expand(s);
    080                    values.set(index, s);
    081                }
    082            }
    083
    084            return s;
    085        }
    086
    087        public String getValue(String qname) {
    088            int index = attrs.getIndex(qname);
    089            if (index == -1) {
    090                return null;
    091            }
    092            return getValue(index);
    093        }
    094
    095        public String getValue(String uri, String localname) {
    096            int index = attrs.getIndex(uri, localname);
    097            if (index == -1) {
    098                return null;
    099            }
    100            return getValue(index);
    101        }
    102
    103        // plain proxy methods follow : nothing interesting :-)
    104        public int getIndex(String qname) {
    105            return attrs.getIndex(qname);
    106        }
    107
    108        public int getIndex(String uri, String localpart) {
    109            return attrs.getIndex(uri, localpart);
    110        }
    111
    112        public int getLength() {
    113            return attrs.getLength();
    114        }
    115
    116        public String getLocalName(int index) {
    117            return attrs.getLocalName(index);
    118        }
    119
    120        public String getQName(int index) {
    121            return attrs.getQName(index);
    122        }
    123
    124        public String getType(int index) {
    125            return attrs.getType(index);
    126        }
    127
    128        public String getType(String qname) {
    129            return attrs.getType(qname);
    130        }
    131
    132        public String getType(String uri, String localname) {
    133            return attrs.getType(uri, localname);
    134        }
    135
    136        public String getURI(int index) {
    137            return attrs.getURI(index);
    138        }
    139
    140    }