View Javadoc

1   package org.apache.commons.digester3.substitution;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.xml.sax.Attributes;
23  
24  import java.util.ArrayList;
25  
26  /**
27   * Wrapper for an {@link Attributes} object which expands any "variables" referenced in the attribute value via
28   * ${foo} or similar. This is only done when something actually asks for the attribute value, thereby imposing no
29   * performance penalty if the attribute is not used.
30   * 
31   * @since 1.6
32   */
33  public class VariableAttributes
34      implements Attributes
35  {
36  
37      // list of mapped attributes.
38      private ArrayList<String> values = new ArrayList<String>( 10 );
39  
40      private Attributes attrs;
41  
42      private VariableExpander expander;
43  
44      // ------------------- Public Methods
45  
46      /**
47       * Specify which attributes class this object is a proxy for.
48       *
49       * @param attrs The attributes where variables have to be expanded.
50       * @param expander The variables expander instance.
51       */
52      public void init( Attributes attrs, VariableExpander expander )
53      {
54          this.attrs = attrs;
55          this.expander = expander;
56  
57          // I hope this doesn't release the memory for this array; for
58          // efficiency, this should just mark the array as being size 0.
59          values.clear();
60      }
61  
62      /**
63       * {@inheritDoc}
64       */
65      public String getValue( int index )
66      {
67          if ( index >= values.size() )
68          {
69              // Expand the values array with null elements, so the later
70              // call to set(index, s) works ok.
71              //
72              // Unfortunately, there is no easy way to set the size of
73              // an arraylist; we must repeatedly add null elements to it..
74              values.ensureCapacity( index + 1 );
75              for ( int i = values.size(); i <= index; ++i )
76              {
77                  values.add( null );
78              }
79          }
80  
81          String s = values.get( index );
82  
83          if ( s == null )
84          {
85              // we have never been asked for this value before.
86              // get the real attribute value and perform substitution
87              // on it.
88              s = attrs.getValue( index );
89              if ( s != null )
90              {
91                  s = expander.expand( s );
92                  values.set( index, s );
93              }
94          }
95  
96          return s;
97      }
98  
99      /**
100      * {@inheritDoc}
101      */
102     public String getValue( String qname )
103     {
104         int index = attrs.getIndex( qname );
105         if ( index == -1 )
106         {
107             return null;
108         }
109         return getValue( index );
110     }
111 
112     /**
113      * {@inheritDoc}
114      */
115     public String getValue( String uri, String localname )
116     {
117         int index = attrs.getIndex( uri, localname );
118         if ( index == -1 )
119         {
120             return null;
121         }
122         return getValue( index );
123     }
124 
125     // plain proxy methods follow : nothing interesting :-)
126     /**
127      * {@inheritDoc}
128      */
129     public int getIndex( String qname )
130     {
131         return attrs.getIndex( qname );
132     }
133 
134     /**
135      * {@inheritDoc}
136      */
137     public int getIndex( String uri, String localpart )
138     {
139         return attrs.getIndex( uri, localpart );
140     }
141 
142     /**
143      * {@inheritDoc}
144      */
145     public int getLength()
146     {
147         return attrs.getLength();
148     }
149 
150     /**
151      * {@inheritDoc}
152      */
153     public String getLocalName( int index )
154     {
155         return attrs.getLocalName( index );
156     }
157 
158     /**
159      * {@inheritDoc}
160      */
161     public String getQName( int index )
162     {
163         return attrs.getQName( index );
164     }
165 
166     /**
167      * {@inheritDoc}
168      */
169     public String getType( int index )
170     {
171         return attrs.getType( index );
172     }
173 
174     /**
175      * {@inheritDoc}
176      */
177     public String getType( String qname )
178     {
179         return attrs.getType( qname );
180     }
181 
182     /**
183      * {@inheritDoc}
184      */
185     public String getType( String uri, String localname )
186     {
187         return attrs.getType( uri, localname );
188     }
189 
190     /**
191      * {@inheritDoc}
192      */
193     public String getURI( int index )
194     {
195         return attrs.getURI( index );
196     }
197 
198 }