source: release-kits/lirk3/resources/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/filters/ReplaceTokens.java@ 14982

Last change on this file since 14982 was 14982, checked in by oranfry, 16 years ago

initial import of LiRK3

File size: 10.5 KB
Line 
1/*
2 * Copyright 2002-2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17package org.apache.tools.ant.filters;
18
19import java.io.IOException;
20import java.io.Reader;
21import java.util.Hashtable;
22import org.apache.tools.ant.types.Parameter;
23import org.apache.tools.ant.BuildException;
24
25/**
26 * Replaces tokens in the original input with user-supplied values.
27 *
28 * Example:
29 *
30 * <pre>&lt;replacetokens begintoken=&quot;#&quot; endtoken=&quot;#&quot;&gt;
31 * &lt;token key=&quot;DATE&quot; value=&quot;${TODAY}&quot;/&gt;
32 * &lt;/replacetokens&gt;</pre>
33 *
34 * Or:
35 *
36 * <pre>&lt;filterreader classname="org.apache.tools.ant.filters.ReplaceTokens"&gt;
37 * &lt;param type="tokenchar" name="begintoken" value="#"/&gt;
38 * &lt;param type="tokenchar" name="endtoken" value="#"/&gt;
39 * &lt;param type="token" name="DATE" value="${TODAY}"/&gt;
40 * &lt;/filterreader&gt;</pre>
41 *
42 */
43public final class ReplaceTokens
44 extends BaseParamFilterReader
45 implements ChainableReader {
46 /** Default "begin token" character. */
47 private static final char DEFAULT_BEGIN_TOKEN = '@';
48
49 /** Default "end token" character. */
50 private static final char DEFAULT_END_TOKEN = '@';
51
52 /** Data to be used before reading from stream again */
53 private String queuedData = null;
54
55 /** replacement test from a token */
56 private String replaceData = null;
57
58 /** Index into replacement data */
59 private int replaceIndex = -1;
60
61 /** Index into queue data */
62 private int queueIndex = -1;
63
64 /** Hashtable to hold the replacee-replacer pairs (String to String). */
65 private Hashtable hash = new Hashtable();
66
67 /** Character marking the beginning of a token. */
68 private char beginToken = DEFAULT_BEGIN_TOKEN;
69
70 /** Character marking the end of a token. */
71 private char endToken = DEFAULT_END_TOKEN;
72
73 /**
74 * Constructor for "dummy" instances.
75 *
76 * @see BaseFilterReader#BaseFilterReader()
77 */
78 public ReplaceTokens() {
79 super();
80 }
81
82 /**
83 * Creates a new filtered reader.
84 *
85 * @param in A Reader object providing the underlying stream.
86 * Must not be <code>null</code>.
87 */
88 public ReplaceTokens(final Reader in) {
89 super(in);
90 }
91
92 private int getNextChar() throws IOException {
93 if (queueIndex != -1) {
94 final int ch = queuedData.charAt(queueIndex++);
95 if (queueIndex >= queuedData.length()) {
96 queueIndex = -1;
97 }
98 return ch;
99 }
100
101 return in.read();
102 }
103
104 /**
105 * Returns the next character in the filtered stream, replacing tokens
106 * from the original stream.
107 *
108 * @return the next character in the resulting stream, or -1
109 * if the end of the resulting stream has been reached
110 *
111 * @exception IOException if the underlying stream throws an IOException
112 * during reading
113 */
114 public final int read() throws IOException {
115 if (!getInitialized()) {
116 initialize();
117 setInitialized(true);
118 }
119
120 if (replaceIndex != -1) {
121 final int ch = replaceData.charAt(replaceIndex++);
122 if (replaceIndex >= replaceData.length()) {
123 replaceIndex = -1;
124 }
125 return ch;
126 }
127
128 int ch = getNextChar();
129
130 if (ch == beginToken) {
131 final StringBuffer key = new StringBuffer("");
132 do {
133 ch = getNextChar();
134 if (ch != -1) {
135 key.append((char) ch);
136 } else {
137 break;
138 }
139 } while (ch != endToken);
140
141 if (ch == -1) {
142 if (queuedData == null || queueIndex == -1) {
143 queuedData = key.toString();
144 } else {
145 queuedData
146 = key.toString() + queuedData.substring(queueIndex);
147 }
148 queueIndex = 0;
149 return beginToken;
150 } else {
151 key.setLength(key.length() - 1);
152
153 final String replaceWith = (String) hash.get(key.toString());
154 if (replaceWith != null) {
155 if (replaceWith.length() > 0) {
156 replaceData = replaceWith;
157 replaceIndex = 0;
158 }
159 return read();
160 } else {
161 String newData = key.toString() + endToken;
162 if (queuedData == null || queueIndex == -1) {
163 queuedData = newData;
164 } else {
165 queuedData = newData + queuedData.substring(queueIndex);
166 }
167 queueIndex = 0;
168 return beginToken;
169 }
170 }
171 }
172 return ch;
173 }
174
175 /**
176 * Sets the "begin token" character.
177 *
178 * @param beginToken the character used to denote the beginning of a token
179 */
180 public final void setBeginToken(final char beginToken) {
181 this.beginToken = beginToken;
182 }
183
184 /**
185 * Returns the "begin token" character.
186 *
187 * @return the character used to denote the beginning of a token
188 */
189 private final char getBeginToken() {
190 return beginToken;
191 }
192
193 /**
194 * Sets the "end token" character.
195 *
196 * @param endToken the character used to denote the end of a token
197 */
198 public final void setEndToken(final char endToken) {
199 this.endToken = endToken;
200 }
201
202 /**
203 * Returns the "end token" character.
204 *
205 * @return the character used to denote the end of a token
206 */
207 private final char getEndToken() {
208 return endToken;
209 }
210
211 /**
212 * Adds a token element to the map of tokens to replace.
213 *
214 * @param token The token to add to the map of replacements.
215 * Must not be <code>null</code>.
216 */
217 public final void addConfiguredToken(final Token token) {
218 hash.put(token.getKey(), token.getValue());
219 }
220
221 /**
222 * Sets the map of tokens to replace.
223 *
224 * @param hash A map (String->String) of token keys to replacement
225 * values. Must not be <code>null</code>.
226 */
227 private void setTokens(final Hashtable hash) {
228 this.hash = hash;
229 }
230
231 /**
232 * Returns the map of tokens which will be replaced.
233 *
234 * @return a map (String->String) of token keys to replacement
235 * values
236 */
237 private final Hashtable getTokens() {
238 return hash;
239 }
240
241 /**
242 * Creates a new ReplaceTokens using the passed in
243 * Reader for instantiation.
244 *
245 * @param rdr A Reader object providing the underlying stream.
246 * Must not be <code>null</code>.
247 *
248 * @return a new filter based on this configuration, but filtering
249 * the specified reader
250 */
251 public final Reader chain(final Reader rdr) {
252 ReplaceTokens newFilter = new ReplaceTokens(rdr);
253 newFilter.setBeginToken(getBeginToken());
254 newFilter.setEndToken(getEndToken());
255 newFilter.setTokens(getTokens());
256 newFilter.setInitialized(true);
257 return newFilter;
258 }
259
260 /**
261 * Initializes tokens and loads the replacee-replacer hashtable.
262 */
263 private final void initialize() {
264 Parameter[] params = getParameters();
265 if (params != null) {
266 for (int i = 0; i < params.length; i++) {
267 if (params[i] != null) {
268 final String type = params[i].getType();
269 if ("tokenchar".equals(type)) {
270 final String name = params[i].getName();
271 String value = params[i].getValue();
272 if ("begintoken".equals(name)) {
273 if (value.length() == 0) {
274 throw new BuildException("Begin token cannot "
275 + "be empty");
276 }
277 beginToken = params[i].getValue().charAt(0);
278 } else if ("endtoken".equals(name)) {
279 if (value.length() == 0) {
280 throw new BuildException("End token cannot "
281 + "be empty");
282 }
283 endToken = params[i].getValue().charAt(0);
284 }
285 } else if ("token".equals(type)) {
286 final String name = params[i].getName();
287 final String value = params[i].getValue();
288 hash.put(name, value);
289 }
290 }
291 }
292 }
293 }
294
295 /**
296 * Holds a token
297 */
298 public static class Token {
299
300 /** Token key */
301 private String key;
302
303 /** Token value */
304 private String value;
305
306 /**
307 * Sets the token key
308 *
309 * @param key The key for this token. Must not be <code>null</code>.
310 */
311 public final void setKey(String key) {
312 this.key = key;
313 }
314
315 /**
316 * Sets the token value
317 *
318 * @param value The value for this token. Must not be <code>null</code>.
319 */
320 public final void setValue(String value) {
321 this.value = value;
322 }
323
324 /**
325 * Returns the key for this token.
326 *
327 * @return the key for this token
328 */
329 public final String getKey() {
330 return key;
331 }
332
333 /**
334 * Returns the value for this token.
335 *
336 * @return the value for this token
337 */
338 public final String getValue() {
339 return value;
340 }
341 }
342}
Note: See TracBrowser for help on using the repository browser.