001 package org.apache.commons.digester3.substitution; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022 import org.xml.sax.Attributes; 023 024 import java.util.ArrayList; 025 026 /** 027 * Wrapper for an {@link Attributes} object which expands any "variables" referenced in the attribute value via 028 * ${foo} or similar. This is only done when something actually asks for the attribute value, thereby imposing no 029 * performance penalty if the attribute is not used. 030 * 031 * @since 1.6 032 */ 033 public class VariableAttributes 034 implements Attributes 035 { 036 037 // list of mapped attributes. 038 private ArrayList<String> values = new ArrayList<String>( 10 ); 039 040 private Attributes attrs; 041 042 private VariableExpander expander; 043 044 // ------------------- Public Methods 045 046 /** 047 * Specify which attributes class this object is a proxy for. 048 * 049 * @param attrs The attributes where variables have to be expanded. 050 * @param expander The variables expander instance. 051 */ 052 public void init( Attributes attrs, VariableExpander expander ) 053 { 054 this.attrs = attrs; 055 this.expander = expander; 056 057 // I hope this doesn't release the memory for this array; for 058 // efficiency, this should just mark the array as being size 0. 059 values.clear(); 060 } 061 062 /** 063 * {@inheritDoc} 064 */ 065 public String getValue( int index ) 066 { 067 if ( index >= values.size() ) 068 { 069 // Expand the values array with null elements, so the later 070 // call to set(index, s) works ok. 071 // 072 // Unfortunately, there is no easy way to set the size of 073 // an arraylist; we must repeatedly add null elements to it.. 074 values.ensureCapacity( index + 1 ); 075 for ( int i = values.size(); i <= index; ++i ) 076 { 077 values.add( null ); 078 } 079 } 080 081 String s = values.get( index ); 082 083 if ( s == null ) 084 { 085 // we have never been asked for this value before. 086 // get the real attribute value and perform substitution 087 // on it. 088 s = attrs.getValue( index ); 089 if ( s != null ) 090 { 091 s = expander.expand( s ); 092 values.set( index, s ); 093 } 094 } 095 096 return s; 097 } 098 099 /** 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 }