KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > filters > ReplaceTokens


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18 package org.apache.tools.ant.filters;
19
20 import java.io.FileInputStream JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.Reader JavaDoc;
23 import java.util.Enumeration JavaDoc;
24 import java.util.Hashtable JavaDoc;
25 import java.util.Properties JavaDoc;
26 import org.apache.tools.ant.BuildException;
27 import org.apache.tools.ant.types.Parameter;
28 import org.apache.tools.ant.util.FileUtils;
29
30 /**
31  * Replaces tokens in the original input with user-supplied values.
32  *
33  * Example:
34  *
35  * <pre>&lt;replacetokens begintoken=&quot;#&quot; endtoken=&quot;#&quot;&gt;
36  * &lt;token key=&quot;DATE&quot; value=&quot;${TODAY}&quot;/&gt;
37  * &lt;/replacetokens&gt;</pre>
38  *
39  * Or:
40  *
41  * <pre>&lt;filterreader classname="org.apache.tools.ant.filters.ReplaceTokens"&gt;
42  * &lt;param type="tokenchar" name="begintoken" value="#"/&gt;
43  * &lt;param type="tokenchar" name="endtoken" value="#"/&gt;
44  * &lt;param type="token" name="DATE" value="${TODAY}"/&gt;
45  * &lt;/filterreader&gt;</pre>
46  *
47  */

48 public final class ReplaceTokens
49     extends BaseParamFilterReader
50     implements ChainableReader {
51     /** Default "begin token" character. */
52     private static final char DEFAULT_BEGIN_TOKEN = '@';
53
54     /** Default "end token" character. */
55     private static final char DEFAULT_END_TOKEN = '@';
56
57     /** Data to be used before reading from stream again */
58     private String JavaDoc queuedData = null;
59
60     /** replacement test from a token */
61     private String JavaDoc replaceData = null;
62
63     /** Index into replacement data */
64     private int replaceIndex = -1;
65
66     /** Index into queue data */
67     private int queueIndex = -1;
68
69     /** Hashtable to hold the replacee-replacer pairs (String to String). */
70     private Hashtable JavaDoc hash = new Hashtable JavaDoc();
71
72     /** Character marking the beginning of a token. */
73     private char beginToken = DEFAULT_BEGIN_TOKEN;
74
75     /** Character marking the end of a token. */
76     private char endToken = DEFAULT_END_TOKEN;
77
78     /**
79      * Constructor for "dummy" instances.
80      *
81      * @see BaseFilterReader#BaseFilterReader()
82      */

83     public ReplaceTokens() {
84         super();
85     }
86
87     /**
88      * Creates a new filtered reader.
89      *
90      * @param in A Reader object providing the underlying stream.
91      * Must not be <code>null</code>.
92      */

93     public ReplaceTokens(final Reader JavaDoc in) {
94         super(in);
95     }
96
97     private int getNextChar() throws IOException JavaDoc {
98         if (queueIndex != -1) {
99             final int ch = queuedData.charAt(queueIndex++);
100             if (queueIndex >= queuedData.length()) {
101                 queueIndex = -1;
102             }
103             return ch;
104         }
105
106         return in.read();
107     }
108
109     /**
110      * Returns the next character in the filtered stream, replacing tokens
111      * from the original stream.
112      *
113      * @return the next character in the resulting stream, or -1
114      * if the end of the resulting stream has been reached
115      *
116      * @exception IOException if the underlying stream throws an IOException
117      * during reading
118      */

119     public int read() throws IOException JavaDoc {
120         if (!getInitialized()) {
121             initialize();
122             setInitialized(true);
123         }
124
125         if (replaceIndex != -1) {
126             final int ch = replaceData.charAt(replaceIndex++);
127             if (replaceIndex >= replaceData.length()) {
128                 replaceIndex = -1;
129             }
130             return ch;
131         }
132
133         int ch = getNextChar();
134
135         if (ch == beginToken) {
136             final StringBuffer JavaDoc key = new StringBuffer JavaDoc("");
137             do {
138                 ch = getNextChar();
139                 if (ch != -1) {
140                     key.append((char) ch);
141                 } else {
142                     break;
143                 }
144             } while (ch != endToken);
145
146             if (ch == -1) {
147                 if (queuedData == null || queueIndex == -1) {
148                     queuedData = key.toString();
149                 } else {
150                     queuedData
151                         = key.toString() + queuedData.substring(queueIndex);
152                 }
153                 queueIndex = 0;
154                 return beginToken;
155             } else {
156                 key.setLength(key.length() - 1);
157
158                 final String JavaDoc replaceWith = (String JavaDoc) hash.get(key.toString());
159                 if (replaceWith != null) {
160                     if (replaceWith.length() > 0) {
161                         replaceData = replaceWith;
162                         replaceIndex = 0;
163                     }
164                     return read();
165                 } else {
166                     String JavaDoc newData = key.toString() + endToken;
167                     if (queuedData == null || queueIndex == -1) {
168                         queuedData = newData;
169                     } else {
170                         queuedData = newData + queuedData.substring(queueIndex);
171                     }
172                     queueIndex = 0;
173                     return beginToken;
174                 }
175             }
176         }
177         return ch;
178     }
179
180     /**
181      * Sets the "begin token" character.
182      *
183      * @param beginToken the character used to denote the beginning of a token
184      */

185     public void setBeginToken(final char beginToken) {
186         this.beginToken = beginToken;
187     }
188
189     /**
190      * Returns the "begin token" character.
191      *
192      * @return the character used to denote the beginning of a token
193      */

194     private char getBeginToken() {
195         return beginToken;
196     }
197
198     /**
199      * Sets the "end token" character.
200      *
201      * @param endToken the character used to denote the end of a token
202      */

203     public void setEndToken(final char endToken) {
204         this.endToken = endToken;
205     }
206
207     /**
208      * Returns the "end token" character.
209      *
210      * @return the character used to denote the end of a token
211      */

212     private char getEndToken() {
213         return endToken;
214     }
215
216     /**
217      * Adds a token element to the map of tokens to replace.
218      *
219      * @param token The token to add to the map of replacements.
220      * Must not be <code>null</code>.
221      */

222     public void addConfiguredToken(final Token token) {
223         hash.put(token.getKey(), token.getValue());
224     }
225
226     /**
227      * Returns properties from a specified properties file.
228      *
229      * @param fileName The file to load properties from.
230      */

231     private Properties JavaDoc getPropertiesFromFile (String JavaDoc fileName) {
232         FileInputStream JavaDoc in = null;
233         Properties JavaDoc props = new Properties JavaDoc();
234         try {
235             in = new FileInputStream JavaDoc(fileName);
236             props.load(in);
237         } catch (IOException JavaDoc ioe) {
238             ioe.printStackTrace();
239         } finally {
240             FileUtils.close(in);
241         }
242
243         return props;
244     }
245
246     /**
247      * Sets the map of tokens to replace.
248      *
249      * @param hash A map (String->String) of token keys to replacement
250      * values. Must not be <code>null</code>.
251      */

252     private void setTokens(final Hashtable JavaDoc hash) {
253         this.hash = hash;
254     }
255
256     /**
257      * Returns the map of tokens which will be replaced.
258      *
259      * @return a map (String->String) of token keys to replacement
260      * values
261      */

262     private Hashtable JavaDoc getTokens() {
263         return hash;
264     }
265
266     /**
267      * Creates a new ReplaceTokens using the passed in
268      * Reader for instantiation.
269      *
270      * @param rdr A Reader object providing the underlying stream.
271      * Must not be <code>null</code>.
272      *
273      * @return a new filter based on this configuration, but filtering
274      * the specified reader
275      */

276     public Reader JavaDoc chain(final Reader JavaDoc rdr) {
277         ReplaceTokens newFilter = new ReplaceTokens(rdr);
278         newFilter.setBeginToken(getBeginToken());
279         newFilter.setEndToken(getEndToken());
280         newFilter.setTokens(getTokens());
281         newFilter.setInitialized(true);
282         return newFilter;
283     }
284
285     /**
286      * Initializes tokens and loads the replacee-replacer hashtable.
287      */

288     private void initialize() {
289         Parameter[] params = getParameters();
290         if (params != null) {
291             for (int i = 0; i < params.length; i++) {
292                 if (params[i] != null) {
293                     final String JavaDoc type = params[i].getType();
294                     if ("tokenchar".equals(type)) {
295                         final String JavaDoc name = params[i].getName();
296                         String JavaDoc value = params[i].getValue();
297                         if ("begintoken".equals(name)) {
298                             if (value.length() == 0) {
299                                 throw new BuildException("Begin token cannot "
300                                     + "be empty");
301                             }
302                             beginToken = params[i].getValue().charAt(0);
303                         } else if ("endtoken".equals(name)) {
304                             if (value.length() == 0) {
305                                 throw new BuildException("End token cannot "
306                                     + "be empty");
307                             }
308                             endToken = params[i].getValue().charAt(0);
309                         }
310                     } else if ("token".equals(type)) {
311                         final String JavaDoc name = params[i].getName();
312                         final String JavaDoc value = params[i].getValue();
313                         hash.put(name, value);
314                     } else if ("propertiesfile".equals(type)) {
315                         Properties JavaDoc props = getPropertiesFromFile(params[i].getValue());
316                         for (Enumeration JavaDoc e = props.keys(); e.hasMoreElements();) {
317                             String JavaDoc key = (String JavaDoc) e.nextElement();
318                             String JavaDoc value = props.getProperty(key);
319                             hash.put(key, value);
320                         }
321                     }
322                 }
323             }
324         }
325     }
326
327     /**
328      * Holds a token
329      */

330     public static class Token {
331
332         /** Token key */
333         private String JavaDoc key;
334
335         /** Token value */
336         private String JavaDoc value;
337
338         /**
339          * Sets the token key
340          *
341          * @param key The key for this token. Must not be <code>null</code>.
342          */

343         public final void setKey(String JavaDoc key) {
344             this.key = key;
345         }
346
347         /**
348          * Sets the token value
349          *
350          * @param value The value for this token. Must not be <code>null</code>.
351          */

352         public final void setValue(String JavaDoc value) {
353             this.value = value;
354         }
355
356         /**
357          * Returns the key for this token.
358          *
359          * @return the key for this token
360          */

361         public final String JavaDoc getKey() {
362             return key;
363         }
364
365         /**
366          * Returns the value for this token.
367          *
368          * @return the value for this token
369          */

370         public final String JavaDoc getValue() {
371             return value;
372         }
373     }
374 }
375
Popular Tags