Source Code Cross Referenced for Replace.java in  » Build » ANT » org » apache » tools » ant » taskdefs » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Build » ANT » org.apache.tools.ant.taskdefs 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
003:         *  contributor license agreements.  See the NOTICE file distributed with
004:         *  this work for additional information regarding copyright ownership.
005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
006:         *  (the "License"); you may not use this file except in compliance with
007:         *  the License.  You may obtain a copy of the License at
008:         *
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         *  Unless required by applicable law or agreed to in writing, software
012:         *  distributed under the License is distributed on an "AS IS" BASIS,
013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         *  See the License for the specific language governing permissions and
015:         *  limitations under the License.
016:         *
017:         */
018:
019:        package org.apache.tools.ant.taskdefs;
020:
021:        import java.io.BufferedReader;
022:        import java.io.BufferedWriter;
023:        import java.io.File;
024:        import java.io.FileInputStream;
025:        import java.io.FileNotFoundException;
026:        import java.io.FileOutputStream;
027:        import java.io.FileReader;
028:        import java.io.FileWriter;
029:        import java.io.IOException;
030:        import java.io.InputStreamReader;
031:        import java.io.OutputStreamWriter;
032:        import java.io.Reader;
033:        import java.io.Writer;
034:        import java.util.Enumeration;
035:        import java.util.Properties;
036:        import java.util.Vector;
037:        import org.apache.tools.ant.BuildException;
038:        import org.apache.tools.ant.DirectoryScanner;
039:        import org.apache.tools.ant.Project;
040:        import org.apache.tools.ant.util.FileUtils;
041:        import org.apache.tools.ant.util.StringUtils;
042:
043:        /**
044:         * Replaces all occurrences of one or more string tokens with given
045:         * values in the indicated files. Each value can be either a string
046:         * or the value of a property available in a designated property file.
047:         * If you want to replace a text that crosses line boundaries, you
048:         * must use a nested <code>&lt;replacetoken&gt;</code> element.
049:         *
050:         * @since Ant 1.1
051:         *
052:         * @ant.task category="filesystem"
053:         */
054:        public class Replace extends MatchingTask {
055:
056:            private static final FileUtils FILE_UTILS = FileUtils
057:                    .getFileUtils();
058:
059:            private File src = null;
060:            private NestedString token = null;
061:            private NestedString value = new NestedString();
062:
063:            private File propertyFile = null;
064:            private File replaceFilterFile = null;
065:            private Properties properties = null;
066:            private Vector replacefilters = new Vector();
067:
068:            private File dir = null;
069:
070:            private int fileCount;
071:            private int replaceCount;
072:            private boolean summary = false;
073:
074:            /** The encoding used to read and write files - if null, uses default */
075:            private String encoding = null;
076:
077:            /**
078:             * An inline string to use as the replacement text.
079:             */
080:            public class NestedString {
081:
082:                private StringBuffer buf = new StringBuffer();
083:
084:                /**
085:                 * The text of the element.
086:                 *
087:                 * @param val the string to add
088:                 */
089:                public void addText(String val) {
090:                    buf.append(val);
091:                }
092:
093:                /**
094:                 * @return the text
095:                 */
096:                public String getText() {
097:                    return buf.toString();
098:                }
099:            }
100:
101:            /**
102:             * A filter to apply.
103:             */
104:            public class Replacefilter {
105:                private String token;
106:                private String value;
107:                private String replaceValue;
108:                private String property;
109:
110:                private StringBuffer inputBuffer;
111:                private StringBuffer outputBuffer = new StringBuffer();
112:
113:                /**
114:                 * Validate the filter's configuration.
115:                 * @throws BuildException if any part is invalid.
116:                 */
117:                public void validate() throws BuildException {
118:                    //Validate mandatory attributes
119:                    if (token == null) {
120:                        String message = "token is a mandatory attribute "
121:                                + "of replacefilter.";
122:                        throw new BuildException(message);
123:                    }
124:
125:                    if ("".equals(token)) {
126:                        String message = "The token attribute must not be an empty "
127:                                + "string.";
128:                        throw new BuildException(message);
129:                    }
130:
131:                    //value and property are mutually exclusive attributes
132:                    if ((value != null) && (property != null)) {
133:                        String message = "Either value or property "
134:                                + "can be specified, but a replacefilter "
135:                                + "element cannot have both.";
136:                        throw new BuildException(message);
137:                    }
138:
139:                    if ((property != null)) {
140:                        //the property attribute must have access to a property file
141:                        if (propertyFile == null) {
142:                            String message = "The replacefilter's property attribute "
143:                                    + "can only be used with the replacetask's "
144:                                    + "propertyFile attribute.";
145:                            throw new BuildException(message);
146:                        }
147:
148:                        //Make sure property exists in property file
149:                        if (properties == null
150:                                || properties.getProperty(property) == null) {
151:                            String message = "property \"" + property
152:                                    + "\" was not found in "
153:                                    + propertyFile.getPath();
154:                            throw new BuildException(message);
155:                        }
156:                    }
157:
158:                    replaceValue = getReplaceValue();
159:                }
160:
161:                /**
162:                 * Get the replacement value for this filter token.
163:                 * @return the replacement value
164:                 */
165:                public String getReplaceValue() {
166:                    if (property != null) {
167:                        return properties.getProperty(property);
168:                    } else if (value != null) {
169:                        return value;
170:                    } else if (Replace.this .value != null) {
171:                        return Replace.this .value.getText();
172:                    } else {
173:                        //Default is empty string
174:                        return "";
175:                    }
176:                }
177:
178:                /**
179:                 * Set the token to replace.
180:                 * @param token <code>String</code> token.
181:                 */
182:                public void setToken(String token) {
183:                    this .token = token;
184:                }
185:
186:                /**
187:                 * Get the string to search for.
188:                 * @return current <code>String</code> token.
189:                 */
190:                public String getToken() {
191:                    return token;
192:                }
193:
194:                /**
195:                 * The replacement string; required if <code>property<code>
196:                 * is not set.
197:                 * @param value <code>String</code> value to replace.
198:                 */
199:                public void setValue(String value) {
200:                    this .value = value;
201:                }
202:
203:                /**
204:                 * Get replacement <code>String</code>.
205:                 * @return replacement or null.
206:                 */
207:                public String getValue() {
208:                    return value;
209:                }
210:
211:                /**
212:                 * Set the name of the property whose value is to serve as
213:                 * the replacement value; required if <code>value</code> is not set.
214:                 * @param property property name.
215:                 */
216:                public void setProperty(String property) {
217:                    this .property = property;
218:                }
219:
220:                /**
221:                 * Get the name of the property whose value is to serve as
222:                 * the replacement value.
223:                 * @return property or null.
224:                 */
225:                public String getProperty() {
226:                    return property;
227:                }
228:
229:                /**
230:                 * Retrieves the output buffer of this filter. The filter guarantees
231:                 * that data is only appended to the end of this StringBuffer.
232:                 * @return The StringBuffer containing the output of this filter.
233:                 */
234:                StringBuffer getOutputBuffer() {
235:                    return outputBuffer;
236:                }
237:
238:                /**
239:                 * Sets the input buffer for this filter.
240:                 * The filter expects from the component providing the input that data
241:                 * is only added by that component to the end of this StringBuffer.
242:                 * This StringBuffer will be modified by this filter, and expects that
243:                 * another component will only apped to this StringBuffer.
244:                 * @param input The input for this filter.
245:                 */
246:                void setInputBuffer(StringBuffer input) {
247:                    inputBuffer = input;
248:                }
249:
250:                /**
251:                 * Processes the buffer as far as possible. Takes into account that
252:                 * appended data may make it possible to replace the end of the already
253:                 * received data, when the token is split over the "old" and the "new"
254:                 * part.
255:                 * @return true if some data has been made available in the
256:                 *         output buffer.
257:                 */
258:                boolean process() {
259:                    if (inputBuffer.length() > token.length()) {
260:                        int pos = replace();
261:                        pos = Math.max((inputBuffer.length() - token.length()),
262:                                pos);
263:                        outputBuffer.append(inputBuffer.substring(0, pos));
264:                        inputBuffer.delete(0, pos);
265:                        return true;
266:                    }
267:                    return false;
268:                }
269:
270:                /**
271:                 * Processes the buffer to the end. Does not take into account that
272:                 * appended data may make it possible to replace the end of the already
273:                 * received data.
274:                 */
275:                void flush() {
276:                    replace();
277:                    // Avoid runtime problem on pre 1.4 when compiling post 1.4
278:                    outputBuffer.append(inputBuffer.toString());
279:                    inputBuffer.delete(0, inputBuffer.length());
280:                }
281:
282:                /**
283:                 * Performs the replace operation.
284:                 * @return The position of the last character that was inserted as
285:                 *         replacement.
286:                 */
287:                private int replace() {
288:                    int found = inputBuffer.toString().indexOf(token);
289:                    int pos = -1;
290:                    while (found >= 0) {
291:                        inputBuffer.replace(found, found + token.length(),
292:                                replaceValue);
293:                        pos = found + replaceValue.length();
294:                        found = inputBuffer.toString().indexOf(token, pos);
295:                        ++replaceCount;
296:                    }
297:                    return pos;
298:                }
299:            }
300:
301:            /**
302:             * Class reading a file in small chunks, and presenting these chunks in
303:             * a StringBuffer. Compatible with the Replacefilter.
304:             * @since 1.7
305:             */
306:            private class FileInput {
307:                private StringBuffer outputBuffer;
308:                private Reader reader;
309:                private char[] buffer;
310:                private static final int BUFF_SIZE = 4096;
311:
312:                /**
313:                 * Constructs the input component. Opens the file for reading.
314:                 * @param source The file to read from.
315:                 * @throws IOException When the file cannot be read from.
316:                 */
317:                FileInput(File source) throws IOException {
318:                    outputBuffer = new StringBuffer();
319:                    buffer = new char[BUFF_SIZE];
320:                    if (encoding == null) {
321:                        reader = new BufferedReader(new FileReader(source));
322:                    } else {
323:                        reader = new BufferedReader(new InputStreamReader(
324:                                new FileInputStream(source), encoding));
325:                    }
326:                }
327:
328:                /**
329:                 * Retrieves the output buffer of this filter. The component guarantees
330:                 * that data is only appended to the end of this StringBuffer.
331:                 * @return The StringBuffer containing the output of this filter.
332:                 */
333:                StringBuffer getOutputBuffer() {
334:                    return outputBuffer;
335:                }
336:
337:                /**
338:                 * Reads some data from the file.
339:                 * @return true when the end of the file has not been reached.
340:                 * @throws IOException When the file cannot be read from.
341:                 */
342:                boolean readChunk() throws IOException {
343:                    int bufferLength = 0;
344:                    bufferLength = reader.read(buffer);
345:                    if (bufferLength < 0) {
346:                        return false;
347:                    }
348:                    outputBuffer.append(new String(buffer, 0, bufferLength));
349:                    return true;
350:                }
351:
352:                /**
353:                 * Closes the file.
354:                 * @throws IOException When the file cannot be closed.
355:                 */
356:                void close() throws IOException {
357:                    reader.close();
358:                }
359:
360:                /**
361:                 * Closes file but doesn't throw exception
362:                 */
363:                void closeQuietly() {
364:                    FileUtils.close(reader);
365:                }
366:
367:            }
368:
369:            /**
370:             * Component writing a file in chunks, taking the chunks from the
371:             * Replacefilter.
372:             * @since 1.7
373:             */
374:            private class FileOutput {
375:                private StringBuffer inputBuffer;
376:                private Writer writer;
377:
378:                /**
379:                 * Constructs the output component. Opens the file for writing.
380:                 * @param out The file to read to.
381:                 * @throws IOException When the file cannot be read from.
382:                 */
383:                FileOutput(File out) throws IOException {
384:                    if (encoding == null) {
385:                        writer = new BufferedWriter(new FileWriter(out));
386:                    } else {
387:                        writer = new BufferedWriter(new OutputStreamWriter(
388:                                new FileOutputStream(out), encoding));
389:                    }
390:                }
391:
392:                /**
393:                 * Sets the input buffer for this component.
394:                 * The filter expects from the component providing the input that data
395:                 * is only added by that component to the end of this StringBuffer.
396:                 * This StringBuffer will be modified by this filter, and expects that
397:                 * another component will only append to this StringBuffer.
398:                 * @param input The input for this filter.
399:                 */
400:                void setInputBuffer(StringBuffer input) {
401:                    inputBuffer = input;
402:                }
403:
404:                /**
405:                 * Writes the buffer as far as possible.
406:                 * @return false to be inline with the Replacefilter.
407:                 * (Yes defining an interface crossed my mind, but would publish the
408:                 * internal behavior.)
409:                 * @throws IOException when the output cannot be written.
410:                 */
411:                boolean process() throws IOException {
412:                    writer.write(inputBuffer.toString());
413:                    inputBuffer.delete(0, inputBuffer.length());
414:                    return false;
415:                }
416:
417:                /**
418:                 * Processes the buffer to the end.
419:                 * @throws IOException when the output cannot be flushed.
420:                 */
421:                void flush() throws IOException {
422:                    process();
423:                    writer.flush();
424:                }
425:
426:                /**
427:                 * Closes the file.
428:                 * @throws IOException When the file cannot be closed.
429:                 */
430:                void close() throws IOException {
431:                    writer.close();
432:                }
433:
434:                /**
435:                 * Closes file but doesn't throw exception
436:                 */
437:                void closeQuietly() {
438:                    FileUtils.close(writer);
439:                }
440:            }
441:
442:            /**
443:             * Do the execution.
444:             * @throws BuildException if we cant build
445:             */
446:            public void execute() throws BuildException {
447:
448:                Vector savedFilters = (Vector) replacefilters.clone();
449:                Properties savedProperties = properties == null ? null
450:                        : (Properties) properties.clone();
451:
452:                if (token != null) {
453:                    // line separators in values and tokens are "\n"
454:                    // in order to compare with the file contents, replace them
455:                    // as needed
456:                    StringBuffer val = new StringBuffer(value.getText());
457:                    stringReplace(val, "\r\n", "\n");
458:                    stringReplace(val, "\n", StringUtils.LINE_SEP);
459:                    StringBuffer tok = new StringBuffer(token.getText());
460:                    stringReplace(tok, "\r\n", "\n");
461:                    stringReplace(tok, "\n", StringUtils.LINE_SEP);
462:                    Replacefilter firstFilter = createPrimaryfilter();
463:                    firstFilter.setToken(tok.toString());
464:                    firstFilter.setValue(val.toString());
465:                }
466:
467:                try {
468:                    if (replaceFilterFile != null) {
469:                        Properties props = getProperties(replaceFilterFile);
470:                        Enumeration e = props.keys();
471:                        while (e.hasMoreElements()) {
472:                            String tok = e.nextElement().toString();
473:                            Replacefilter replaceFilter = createReplacefilter();
474:                            replaceFilter.setToken(tok);
475:                            replaceFilter.setValue(props.getProperty(tok));
476:                        }
477:                    }
478:
479:                    validateAttributes();
480:
481:                    if (propertyFile != null) {
482:                        properties = getProperties(propertyFile);
483:                    }
484:
485:                    validateReplacefilters();
486:                    fileCount = 0;
487:                    replaceCount = 0;
488:
489:                    if (src != null) {
490:                        processFile(src);
491:                    }
492:
493:                    if (dir != null) {
494:                        DirectoryScanner ds = super .getDirectoryScanner(dir);
495:                        String[] srcs = ds.getIncludedFiles();
496:
497:                        for (int i = 0; i < srcs.length; i++) {
498:                            File file = new File(dir, srcs[i]);
499:                            processFile(file);
500:                        }
501:                    }
502:
503:                    if (summary) {
504:                        log("Replaced " + replaceCount + " occurrences in "
505:                                + fileCount + " files.", Project.MSG_INFO);
506:                    }
507:                } finally {
508:                    replacefilters = savedFilters;
509:                    properties = savedProperties;
510:                } // end of finally
511:
512:            }
513:
514:            /**
515:             * Validate attributes provided for this task in .xml build file.
516:             *
517:             * @exception BuildException if any supplied attribute is invalid or any
518:             * mandatory attribute is missing.
519:             */
520:            public void validateAttributes() throws BuildException {
521:                if (src == null && dir == null) {
522:                    String message = "Either the file or the dir attribute "
523:                            + "must be specified";
524:                    throw new BuildException(message, getLocation());
525:                }
526:                if (propertyFile != null && !propertyFile.exists()) {
527:                    String message = "Property file " + propertyFile.getPath()
528:                            + " does not exist.";
529:                    throw new BuildException(message, getLocation());
530:                }
531:                if (token == null && replacefilters.size() == 0) {
532:                    String message = "Either token or a nested replacefilter "
533:                            + "must be specified";
534:                    throw new BuildException(message, getLocation());
535:                }
536:                if (token != null && "".equals(token.getText())) {
537:                    String message = "The token attribute must not be an empty string.";
538:                    throw new BuildException(message, getLocation());
539:                }
540:            }
541:
542:            /**
543:             * Validate nested elements.
544:             *
545:             * @exception BuildException if any supplied attribute is invalid or any
546:             * mandatory attribute is missing.
547:             */
548:            public void validateReplacefilters() throws BuildException {
549:                for (int i = 0; i < replacefilters.size(); i++) {
550:                    Replacefilter element = (Replacefilter) replacefilters
551:                            .elementAt(i);
552:                    element.validate();
553:                }
554:            }
555:
556:            /**
557:             * Load a properties file.
558:             * @param propertyFile the file to load the properties from.
559:             * @return loaded <code>Properties</code> object.
560:             * @throws BuildException if the file could not be found or read.
561:             */
562:            public Properties getProperties(File propertyFile)
563:                    throws BuildException {
564:                Properties props = new Properties();
565:
566:                FileInputStream in = null;
567:                try {
568:                    in = new FileInputStream(propertyFile);
569:                    props.load(in);
570:                } catch (FileNotFoundException e) {
571:                    String message = "Property file (" + propertyFile.getPath()
572:                            + ") not found.";
573:                    throw new BuildException(message);
574:                } catch (IOException e) {
575:                    String message = "Property file (" + propertyFile.getPath()
576:                            + ") cannot be loaded.";
577:                    throw new BuildException(message);
578:                } finally {
579:                    FileUtils.close(in);
580:                }
581:
582:                return props;
583:            }
584:
585:            /**
586:             * Perform the replacement on the given file.
587:             *
588:             * The replacement is performed on a temporary file which then
589:             * replaces the original file.
590:             *
591:             * @param src the source <code>File</code>.
592:             */
593:            private void processFile(File src) throws BuildException {
594:                if (!src.exists()) {
595:                    throw new BuildException("Replace: source file "
596:                            + src.getPath() + " doesn't exist", getLocation());
597:                }
598:
599:                File temp = null;
600:                FileInput in = null;
601:                FileOutput out = null;
602:                try {
603:                    in = new FileInput(src);
604:
605:                    temp = FILE_UTILS.createTempFile("rep", ".tmp", src
606:                            .getParentFile());
607:                    out = new FileOutput(temp);
608:
609:                    int repCountStart = replaceCount;
610:
611:                    logFilterChain(src.getPath());
612:
613:                    out.setInputBuffer(buildFilterChain(in.getOutputBuffer()));
614:
615:                    while (in.readChunk()) {
616:                        if (processFilterChain()) {
617:                            out.process();
618:                        }
619:                    }
620:
621:                    flushFilterChain();
622:
623:                    out.flush();
624:                    in.close();
625:                    in = null;
626:                    out.close();
627:                    out = null;
628:
629:                    boolean changes = (replaceCount != repCountStart);
630:                    if (changes) {
631:                        FILE_UTILS.rename(temp, src);
632:                        temp = null;
633:                    }
634:                } catch (IOException ioe) {
635:                    throw new BuildException(
636:                            "IOException in " + src + " - "
637:                                    + ioe.getClass().getName() + ":"
638:                                    + ioe.getMessage(), ioe, getLocation());
639:                } finally {
640:                    if (null != in) {
641:                        in.closeQuietly();
642:                    }
643:                    if (null != out) {
644:                        out.closeQuietly();
645:                    }
646:                    if (temp != null) {
647:                        if (!temp.delete()) {
648:                            temp.deleteOnExit();
649:                        }
650:                    }
651:                }
652:            }
653:
654:            /**
655:             * Flushes all filters.
656:             */
657:            private void flushFilterChain() {
658:                for (int i = 0; i < replacefilters.size(); i++) {
659:                    Replacefilter filter = (Replacefilter) replacefilters
660:                            .elementAt(i);
661:                    filter.flush();
662:                }
663:            }
664:
665:            /**
666:             * Performs the normal processing of the filters.
667:             * @return true if the filter chain produced new output.
668:             */
669:            private boolean processFilterChain() {
670:                for (int i = 0; i < replacefilters.size(); i++) {
671:                    Replacefilter filter = (Replacefilter) replacefilters
672:                            .elementAt(i);
673:                    if (!filter.process()) {
674:                        return false;
675:                    }
676:                }
677:                return true;
678:            }
679:
680:            /**
681:             * Creates the chain of filters to operate.
682:             * @param inputBuffer <code>StringBuffer</code> containing the input for the
683:             *                    first filter.
684:             * @return <code>StringBuffer</code> containing the output of the last filter.
685:             */
686:            private StringBuffer buildFilterChain(StringBuffer inputBuffer) {
687:                StringBuffer buf = inputBuffer;
688:                for (int i = 0; i < replacefilters.size(); i++) {
689:                    Replacefilter filter = (Replacefilter) replacefilters
690:                            .elementAt(i);
691:                    filter.setInputBuffer(buf);
692:                    buf = filter.getOutputBuffer();
693:                }
694:                return buf;
695:            }
696:
697:            /**
698:             * Logs the chain of filters to operate on the file.
699:             * @param filename <code>String</code>.
700:             */
701:            private void logFilterChain(String filename) {
702:                for (int i = 0; i < replacefilters.size(); i++) {
703:                    Replacefilter filter = (Replacefilter) replacefilters
704:                            .elementAt(i);
705:                    log("Replacing in " + filename + ": " + filter.getToken()
706:                            + " --> " + filter.getReplaceValue(),
707:                            Project.MSG_VERBOSE);
708:                }
709:            }
710:
711:            /**
712:             * Set the source file; required unless <code>dir</code> is set.
713:             * @param file source <code>File</code>.
714:             */
715:            public void setFile(File file) {
716:                this .src = file;
717:            }
718:
719:            /**
720:             * Indicates whether a summary of the replace operation should be
721:             * produced, detailing how many token occurrences and files were
722:             * processed; optional, default=<code>false</code>.
723:             *
724:             * @param summary <code>boolean</code> whether a summary of the
725:             *                replace operation should be logged.
726:             */
727:            public void setSummary(boolean summary) {
728:                this .summary = summary;
729:            }
730:
731:            /**
732:             * Sets the name of a property file containing filters; optional.
733:             * Each property will be treated as a replacefilter where token is the name
734:             * of the property and value is the value of the property.
735:             * @param replaceFilterFile <code>File</code> to load.
736:             */
737:            public void setReplaceFilterFile(File replaceFilterFile) {
738:                this .replaceFilterFile = replaceFilterFile;
739:            }
740:
741:            /**
742:             * The base directory to use when replacing a token in multiple files;
743:             * required if <code>file</code> is not defined.
744:             * @param dir <code>File</code> representing the base directory.
745:             */
746:            public void setDir(File dir) {
747:                this .dir = dir;
748:            }
749:
750:            /**
751:             * Set the string token to replace; required unless a nested
752:             * <code>replacetoken</code> element or the <code>replacefilterfile</code>
753:             * attribute is used.
754:             * @param token token <code>String</code>.
755:             */
756:            public void setToken(String token) {
757:                createReplaceToken().addText(token);
758:            }
759:
760:            /**
761:             * Set the string value to use as token replacement;
762:             * optional, default is the empty string "".
763:             * @param value replacement value.
764:             */
765:            public void setValue(String value) {
766:                createReplaceValue().addText(value);
767:            }
768:
769:            /**
770:             * Set the file encoding to use on the files read and written by the task;
771:             * optional, defaults to default JVM encoding.
772:             *
773:             * @param encoding the encoding to use on the files.
774:             */
775:            public void setEncoding(String encoding) {
776:                this .encoding = encoding;
777:            }
778:
779:            /**
780:             * Create a token to filter as the text of a nested element.
781:             * @return nested token <code>NestedString</code> to configure.
782:             */
783:            public NestedString createReplaceToken() {
784:                if (token == null) {
785:                    token = new NestedString();
786:                }
787:                return token;
788:            }
789:
790:            /**
791:             * Create a string to replace the token as the text of a nested element.
792:             * @return replacement value <code>NestedString</code> to configure.
793:             */
794:            public NestedString createReplaceValue() {
795:                return value;
796:            }
797:
798:            /**
799:             * The name of a property file from which properties specified using nested
800:             * <code>&lt;replacefilter&gt;</code> elements are drawn; required only if
801:             * the <i>property</i> attribute of <code>&lt;replacefilter&gt;</code> is used.
802:             * @param propertyFile <code>File</code> to load.
803:             */
804:            public void setPropertyFile(File propertyFile) {
805:                this .propertyFile = propertyFile;
806:            }
807:
808:            /**
809:             * Add a nested &lt;replacefilter&gt; element.
810:             * @return a nested <code>Replacefilter</code> object to be configured.
811:             */
812:            public Replacefilter createReplacefilter() {
813:                Replacefilter filter = new Replacefilter();
814:                replacefilters.addElement(filter);
815:                return filter;
816:            }
817:
818:            /**
819:             * Adds the token and value as first &lt;replacefilter&gt; element.
820:             * The token and value are always processed first.
821:             * @return a nested <code>Replacefilter</code> object to be configured.
822:             */
823:            private Replacefilter createPrimaryfilter() {
824:                Replacefilter filter = new Replacefilter();
825:                replacefilters.insertElementAt(filter, 0);
826:                return filter;
827:            }
828:
829:            /**
830:             * Replace occurrences of str1 in StringBuffer str with str2.
831:             */
832:            private void stringReplace(StringBuffer str, String str1,
833:                    String str2) {
834:                int found = str.toString().indexOf(str1);
835:                while (found >= 0) {
836:                    str.replace(found, found + str1.length(), str2);
837:                    found = str.toString().indexOf(str1, found + str2.length());
838:                }
839:            }
840:
841:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.