Source Code Cross Referenced for Concat.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.File;
022:        import java.io.Reader;
023:        import java.io.Writer;
024:        import java.io.FileReader;
025:        import java.io.InputStream;
026:        import java.io.IOException;
027:        import java.io.PrintWriter;
028:        import java.io.OutputStream;
029:        import java.io.StringReader;
030:        import java.io.BufferedReader;
031:        import java.io.BufferedWriter;
032:        import java.io.FileInputStream;
033:        import java.io.FileOutputStream;
034:        import java.io.InputStreamReader;
035:        import java.io.OutputStreamWriter;
036:        import java.util.Arrays;
037:        import java.util.Vector;
038:        import java.util.Iterator;
039:        import org.apache.tools.ant.Task;
040:        import org.apache.tools.ant.Project;
041:        import org.apache.tools.ant.BuildException;
042:        import org.apache.tools.ant.ProjectComponent;
043:        import org.apache.tools.ant.filters.util.ChainReaderHelper;
044:        import org.apache.tools.ant.types.Path;
045:        import org.apache.tools.ant.types.FileSet;
046:        import org.apache.tools.ant.types.FileList;
047:        import org.apache.tools.ant.types.FilterChain;
048:        import org.apache.tools.ant.types.Resource;
049:        import org.apache.tools.ant.types.ResourceCollection;
050:        import org.apache.tools.ant.types.resources.Restrict;
051:        import org.apache.tools.ant.types.resources.Resources;
052:        import org.apache.tools.ant.types.resources.FileResource;
053:        import org.apache.tools.ant.types.resources.StringResource;
054:        import org.apache.tools.ant.types.resources.selectors.Not;
055:        import org.apache.tools.ant.types.resources.selectors.Exists;
056:        import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
057:        import org.apache.tools.ant.util.FileUtils;
058:        import org.apache.tools.ant.util.ConcatResourceInputStream;
059:
060:        /**
061:         * This class contains the 'concat' task, used to concatenate a series
062:         * of files into a single stream. The destination of this stream may
063:         * be the system console, or a file. The following is a sample
064:         * invocation:
065:         *
066:         * <pre>
067:         * &lt;concat destfile=&quot;${build.dir}/index.xml&quot;
068:         *   append=&quot;false&quot;&gt;
069:         *
070:         *   &lt;fileset dir=&quot;${xml.root.dir}&quot;
071:         *     includes=&quot;*.xml&quot; /&gt;
072:         *
073:         * &lt;/concat&gt;
074:         * </pre>
075:         *
076:         */
077:        public class Concat extends Task {
078:
079:            // The size of buffers to be used
080:            private static final int BUFFER_SIZE = 8192;
081:
082:            private static final FileUtils FILE_UTILS = FileUtils
083:                    .getFileUtils();
084:
085:            private static final ResourceSelector EXISTS = new Exists();
086:            private static final ResourceSelector NOT_EXISTS = new Not(EXISTS);
087:
088:            // Attributes.
089:
090:            /**
091:             * The destination of the stream. If <code>null</code>, the system
092:             * console is used.
093:             */
094:            private File destinationFile;
095:
096:            /**
097:             * Whether or not the stream should be appended if the destination file
098:             * exists.
099:             * Defaults to <code>false</code>.
100:             */
101:            private boolean append;
102:
103:            /**
104:             * Stores the input file encoding.
105:             */
106:            private String encoding;
107:
108:            /** Stores the output file encoding. */
109:            private String outputEncoding;
110:
111:            /** Stores the binary attribute */
112:            private boolean binary;
113:
114:            // Child elements.
115:
116:            /**
117:             * This buffer stores the text within the 'concat' element.
118:             */
119:            private StringBuffer textBuffer;
120:
121:            /**
122:             * Stores a collection of file sets and/or file lists, used to
123:             * select multiple files for concatenation.
124:             */
125:            private Resources rc;
126:
127:            /** for filtering the concatenated */
128:            private Vector filterChains;
129:            /** ignore dates on input files */
130:            private boolean forceOverwrite = true;
131:            /** String to place at the start of the concatented stream */
132:            private TextElement footer;
133:            /** String to place at the end of the concatented stream */
134:            private TextElement header;
135:            /** add missing line.separator to files **/
136:            private boolean fixLastLine = false;
137:            /** endofline for fixlast line */
138:            private String eolString;
139:            /** outputwriter */
140:            private Writer outputWriter = null;
141:
142:            /**
143:             * Construct a new Concat task.
144:             */
145:            public Concat() {
146:                reset();
147:            }
148:
149:            /**
150:             * Reset state to default.
151:             */
152:            public void reset() {
153:                append = false;
154:                forceOverwrite = true;
155:                destinationFile = null;
156:                encoding = null;
157:                outputEncoding = null;
158:                fixLastLine = false;
159:                filterChains = null;
160:                footer = null;
161:                header = null;
162:                binary = false;
163:                outputWriter = null;
164:                textBuffer = null;
165:                eolString = System.getProperty("line.separator");
166:                rc = null;
167:            }
168:
169:            // Attribute setters.
170:
171:            /**
172:             * Sets the destination file, or uses the console if not specified.
173:             * @param destinationFile the destination file
174:             */
175:            public void setDestfile(File destinationFile) {
176:                this .destinationFile = destinationFile;
177:            }
178:
179:            /**
180:             * Sets the behavior when the destination file exists. If set to
181:             * <code>true</code> the stream data will be appended to the
182:             * existing file, otherwise the existing file will be
183:             * overwritten. Defaults to <code>false</code>.
184:             * @param append if true append to the file.
185:             */
186:            public void setAppend(boolean append) {
187:                this .append = append;
188:            }
189:
190:            /**
191:             * Sets the character encoding
192:             * @param encoding the encoding of the input stream and unless
193:             *        outputencoding is set, the outputstream.
194:             */
195:            public void setEncoding(String encoding) {
196:                this .encoding = encoding;
197:                if (outputEncoding == null) {
198:                    outputEncoding = encoding;
199:                }
200:            }
201:
202:            /**
203:             * Sets the character encoding for outputting
204:             * @param outputEncoding the encoding for the output file
205:             * @since Ant 1.6
206:             */
207:            public void setOutputEncoding(String outputEncoding) {
208:                this .outputEncoding = outputEncoding;
209:            }
210:
211:            /**
212:             * Force overwrite existing destination file
213:             * @param force if true always overwrite, otherwise only overwrite
214:             *              if the output file is older any of the input files.
215:             * @since Ant 1.6
216:             */
217:            public void setForce(boolean force) {
218:                this .forceOverwrite = force;
219:            }
220:
221:            // Nested element creators.
222:
223:            /**
224:             * Path of files to concatenate.
225:             * @return the path used for concatenating
226:             * @since Ant 1.6
227:             */
228:            public Path createPath() {
229:                Path path = new Path(getProject());
230:                add(path);
231:                return path;
232:            }
233:
234:            /**
235:             * Set of files to concatenate.
236:             * @param set the set of files
237:             */
238:            public void addFileset(FileSet set) {
239:                add(set);
240:            }
241:
242:            /**
243:             * List of files to concatenate.
244:             * @param list the list of files
245:             */
246:            public void addFilelist(FileList list) {
247:                add(list);
248:            }
249:
250:            /**
251:             * Add an arbitrary ResourceCollection.
252:             * @param c the ResourceCollection to add.
253:             * @since Ant 1.7
254:             */
255:            public void add(ResourceCollection c) {
256:                rc = rc == null ? new Resources() : rc;
257:                rc.add(c);
258:            }
259:
260:            /**
261:             * Adds a FilterChain.
262:             * @param filterChain a filterchain to filter the concatenated input
263:             * @since Ant 1.6
264:             */
265:            public void addFilterChain(FilterChain filterChain) {
266:                if (filterChains == null) {
267:                    filterChains = new Vector();
268:                }
269:                filterChains.addElement(filterChain);
270:            }
271:
272:            /**
273:             * This method adds text which appears in the 'concat' element.
274:             * @param text the text to be concated.
275:             */
276:            public void addText(String text) {
277:                if (textBuffer == null) {
278:                    // Initialize to the size of the first text fragment, with
279:                    // the hopes that it's the only one.
280:                    textBuffer = new StringBuffer(text.length());
281:                }
282:
283:                // Append the fragment -- we defer property replacement until
284:                // later just in case we get a partial property in a fragment.
285:                textBuffer.append(text);
286:            }
287:
288:            /**
289:             * Add a header to the concatenated output
290:             * @param headerToAdd the header
291:             * @since Ant 1.6
292:             */
293:            public void addHeader(TextElement headerToAdd) {
294:                this .header = headerToAdd;
295:            }
296:
297:            /**
298:             * Add a footer to the concatenated output
299:             * @param footerToAdd the footer
300:             * @since Ant 1.6
301:             */
302:            public void addFooter(TextElement footerToAdd) {
303:                this .footer = footerToAdd;
304:            }
305:
306:            /**
307:             * Append line.separator to files that do not end
308:             * with a line.separator, default false.
309:             * @param fixLastLine if true make sure each input file has
310:             *                    new line on the concatenated stream
311:             * @since Ant 1.6
312:             */
313:            public void setFixLastLine(boolean fixLastLine) {
314:                this .fixLastLine = fixLastLine;
315:            }
316:
317:            /**
318:             * Specify the end of line to find and to add if
319:             * not present at end of each input file. This attribute
320:             * is used in conjunction with fixlastline.
321:             * @param crlf the type of new line to add -
322:             *              cr, mac, lf, unix, crlf, or dos
323:             * @since Ant 1.6
324:             */
325:            public void setEol(FixCRLF.CrLf crlf) {
326:                String s = crlf.getValue();
327:                if (s.equals("cr") || s.equals("mac")) {
328:                    eolString = "\r";
329:                } else if (s.equals("lf") || s.equals("unix")) {
330:                    eolString = "\n";
331:                } else if (s.equals("crlf") || s.equals("dos")) {
332:                    eolString = "\r\n";
333:                }
334:            }
335:
336:            /**
337:             * Set the output writer. This is to allow
338:             * concat to be used as a nested element.
339:             * @param outputWriter the output writer.
340:             * @since Ant 1.6
341:             */
342:            public void setWriter(Writer outputWriter) {
343:                this .outputWriter = outputWriter;
344:            }
345:
346:            /**
347:             * Set the binary attribute. If true, concat will concatenate the files
348:             * byte for byte. This mode does not allow any filtering or other
349:             * modifications to the input streams. The default value is false.
350:             * @since Ant 1.6.2
351:             * @param binary if true, enable binary mode.
352:             */
353:            public void setBinary(boolean binary) {
354:                this .binary = binary;
355:            }
356:
357:            /**
358:             * Validate configuration options.
359:             */
360:            private ResourceCollection validate() {
361:
362:                // treat empty nested text as no text
363:                sanitizeText();
364:
365:                // if binary check if incompatible attributes are used
366:                if (binary) {
367:                    if (destinationFile == null) {
368:                        throw new BuildException(
369:                                "destfile attribute is required for binary concatenation");
370:                    }
371:                    if (textBuffer != null) {
372:                        throw new BuildException(
373:                                "Nested text is incompatible with binary concatenation");
374:                    }
375:                    if (encoding != null || outputEncoding != null) {
376:                        throw new BuildException(
377:                                "Seting input or output encoding is incompatible with binary"
378:                                        + " concatenation");
379:                    }
380:                    if (filterChains != null) {
381:                        throw new BuildException(
382:                                "Setting filters is incompatible with binary concatenation");
383:                    }
384:                    if (fixLastLine) {
385:                        throw new BuildException(
386:                                "Setting fixlastline is incompatible with binary concatenation");
387:                    }
388:                    if (header != null || footer != null) {
389:                        throw new BuildException(
390:                                "Nested header or footer is incompatible with binary concatenation");
391:                    }
392:                }
393:                if (destinationFile != null && outputWriter != null) {
394:                    throw new BuildException(
395:                            "Cannot specify both a destination file and an output writer");
396:                }
397:                // Sanity check our inputs.
398:                if (rc == null && textBuffer == null) {
399:                    // Nothing to concatenate!
400:                    throw new BuildException(
401:                            "At least one resource must be provided, or some text.");
402:                }
403:                if (rc != null) {
404:                    // If using resources, disallow inline text. This is similar to
405:                    // using GNU 'cat' with file arguments -- stdin is simply
406:                    // ignored.
407:                    if (textBuffer != null) {
408:                        throw new BuildException(
409:                                "Cannot include inline text when using resources.");
410:                    }
411:                    Restrict noexistRc = new Restrict();
412:                    noexistRc.add(NOT_EXISTS);
413:                    noexistRc.add(rc);
414:                    for (Iterator i = noexistRc.iterator(); i.hasNext();) {
415:                        log(i.next() + " does not exist.", Project.MSG_ERR);
416:                    }
417:                    if (destinationFile != null) {
418:                        for (Iterator i = rc.iterator(); i.hasNext();) {
419:                            Object o = i.next();
420:                            if (o instanceof  FileResource) {
421:                                File f = ((FileResource) o).getFile();
422:                                if (FILE_UTILS.fileNameEquals(f,
423:                                        destinationFile)) {
424:                                    throw new BuildException(
425:                                            "Input file \""
426:                                                    + f
427:                                                    + "\" is the same as the output file.");
428:                                }
429:                            }
430:                        }
431:                    }
432:                    Restrict existRc = new Restrict();
433:                    existRc.add(EXISTS);
434:                    existRc.add(rc);
435:                    boolean outofdate = destinationFile == null
436:                            || forceOverwrite;
437:                    if (!outofdate) {
438:                        for (Iterator i = existRc.iterator(); !outofdate
439:                                && i.hasNext();) {
440:                            Resource r = (Resource) i.next();
441:                            outofdate = (r.getLastModified() == 0L || r
442:                                    .getLastModified() > destinationFile
443:                                    .lastModified());
444:                        }
445:                    }
446:                    if (!outofdate) {
447:                        log(destinationFile + " is up-to-date.",
448:                                Project.MSG_VERBOSE);
449:                        return null; // no need to do anything
450:                    }
451:                    return existRc;
452:                } else {
453:                    StringResource s = new StringResource();
454:                    s.setProject(getProject());
455:                    s.setValue(textBuffer.toString());
456:                    return s;
457:                }
458:            }
459:
460:            /**
461:             * Execute the concat task.
462:             */
463:            public void execute() {
464:                ResourceCollection c = validate();
465:                if (c == null) {
466:                    return;
467:                }
468:                // Do nothing if no resources (including nested text)
469:                if (c.size() < 1 && header == null && footer == null) {
470:                    log(
471:                            "No existing resources and no nested text, doing nothing",
472:                            Project.MSG_INFO);
473:                    return;
474:                }
475:                if (binary) {
476:                    binaryCat(c);
477:                } else {
478:                    cat(c);
479:                }
480:            }
481:
482:            /** perform the binary concatenation */
483:            private void binaryCat(ResourceCollection c) {
484:                log("Binary concatenation of " + c.size() + " resources to "
485:                        + destinationFile);
486:                FileOutputStream out = null;
487:                InputStream in = null;
488:                try {
489:                    try {
490:                        out = new FileOutputStream(destinationFile);
491:                    } catch (Exception t) {
492:                        throw new BuildException("Unable to open "
493:                                + destinationFile + " for writing", t);
494:                    }
495:                    in = new ConcatResourceInputStream(c);
496:                    ((ConcatResourceInputStream) in).setManagingComponent(this );
497:                    Thread t = new Thread(new StreamPumper(in, out));
498:                    t.start();
499:                    try {
500:                        t.join();
501:                    } catch (InterruptedException e) {
502:                        try {
503:                            t.join();
504:                        } catch (InterruptedException ee) {
505:                            // Empty
506:                        }
507:                    }
508:                } finally {
509:                    FileUtils.close(in);
510:                    if (out != null) {
511:                        try {
512:                            out.close();
513:                        } catch (Exception ex) {
514:                            throw new BuildException("Unable to close "
515:                                    + destinationFile, ex);
516:                        }
517:                    }
518:                }
519:            }
520:
521:            /** perform the concatenation */
522:            private void cat(ResourceCollection c) {
523:                OutputStream os = null;
524:                char[] buffer = new char[BUFFER_SIZE];
525:
526:                try {
527:                    PrintWriter writer = null;
528:
529:                    if (outputWriter != null) {
530:                        writer = new PrintWriter(outputWriter);
531:                    } else {
532:                        if (destinationFile == null) {
533:                            // Log using WARN so it displays in 'quiet' mode.
534:                            os = new LogOutputStream(this , Project.MSG_WARN);
535:                        } else {
536:                            // ensure that the parent dir of dest file exists
537:                            File parent = destinationFile.getParentFile();
538:                            if (!parent.exists()) {
539:                                parent.mkdirs();
540:                            }
541:                            os = new FileOutputStream(destinationFile
542:                                    .getAbsolutePath(), append);
543:                        }
544:                        if (outputEncoding == null) {
545:                            writer = new PrintWriter(new BufferedWriter(
546:                                    new OutputStreamWriter(os)));
547:                        } else {
548:                            writer = new PrintWriter(new BufferedWriter(
549:                                    new OutputStreamWriter(os, outputEncoding)));
550:                        }
551:                    }
552:                    if (header != null) {
553:                        if (header.getFiltering()) {
554:                            concatenate(buffer, writer, new StringReader(header
555:                                    .getValue()));
556:                        } else {
557:                            writer.print(header.getValue());
558:                        }
559:                    }
560:                    if (c.size() > 0) {
561:                        concatenate(buffer, writer, new MultiReader(c));
562:                    }
563:                    if (footer != null) {
564:                        if (footer.getFiltering()) {
565:                            concatenate(buffer, writer, new StringReader(footer
566:                                    .getValue()));
567:                        } else {
568:                            writer.print(footer.getValue());
569:                        }
570:                    }
571:                    writer.flush();
572:                    if (os != null) {
573:                        os.flush();
574:                    }
575:                } catch (IOException ioex) {
576:                    throw new BuildException("Error while concatenating: "
577:                            + ioex.getMessage(), ioex);
578:                } finally {
579:                    FileUtils.close(os);
580:                }
581:            }
582:
583:            /** Concatenate a single reader to the writer using buffer */
584:            private void concatenate(char[] buffer, Writer writer, Reader in)
585:                    throws IOException {
586:                if (filterChains != null) {
587:                    ChainReaderHelper helper = new ChainReaderHelper();
588:                    helper.setBufferSize(BUFFER_SIZE);
589:                    helper.setPrimaryReader(in);
590:                    helper.setFilterChains(filterChains);
591:                    helper.setProject(getProject());
592:                    in = new BufferedReader(helper.getAssembledReader());
593:                }
594:                while (true) {
595:                    int nRead = in.read(buffer, 0, buffer.length);
596:                    if (nRead == -1) {
597:                        break;
598:                    }
599:                    writer.write(buffer, 0, nRead);
600:                }
601:                writer.flush();
602:            }
603:
604:            /**
605:             * Treat empty nested text as no text.
606:             *
607:             * <p>Depending on the XML parser, addText may have been called
608:             * for &quot;ignorable whitespace&quot; as well.</p>
609:             */
610:            private void sanitizeText() {
611:                if (textBuffer != null) {
612:                    if (textBuffer.substring(0).trim().length() == 0) {
613:                        textBuffer = null;
614:                    }
615:                }
616:            }
617:
618:            /**
619:             * sub element points to a file or contains text
620:             */
621:            public static class TextElement extends ProjectComponent {
622:                private String value = "";
623:                private boolean trimLeading = false;
624:                private boolean trim = false;
625:                private boolean filtering = true;
626:                private String encoding = null;
627:
628:                /**
629:                 * whether to filter the text in this element
630:                 * or not.
631:                 *
632:                 * @param filtering true if the text should be filtered.
633:                 *                  the default value is true.
634:                 */
635:                public void setFiltering(boolean filtering) {
636:                    this .filtering = filtering;
637:                }
638:
639:                /** return the filtering attribute */
640:                private boolean getFiltering() {
641:                    return filtering;
642:                }
643:
644:                /**
645:                 * The encoding of the text element
646:                 *
647:                 * @param encoding the name of the charset used to encode
648:                 */
649:                public void setEncoding(String encoding) {
650:                    this .encoding = encoding;
651:                }
652:
653:                /**
654:                 * set the text using a file
655:                 * @param file the file to use
656:                 * @throws BuildException if the file does not exist, or cannot be
657:                 *                        read
658:                 */
659:                public void setFile(File file) throws BuildException {
660:                    // non-existing files are not allowed
661:                    if (!file.exists()) {
662:                        throw new BuildException("File " + file
663:                                + " does not exist.");
664:                    }
665:
666:                    BufferedReader reader = null;
667:                    try {
668:                        if (this .encoding == null) {
669:                            reader = new BufferedReader(new FileReader(file));
670:                        } else {
671:                            reader = new BufferedReader(new InputStreamReader(
672:                                    new FileInputStream(file), this .encoding));
673:                        }
674:                        value = FileUtils.readFully(reader);
675:                    } catch (IOException ex) {
676:                        throw new BuildException(ex);
677:                    } finally {
678:                        FileUtils.close(reader);
679:                    }
680:                }
681:
682:                /**
683:                 * set the text using inline
684:                 * @param value the text to place inline
685:                 */
686:                public void addText(String value) {
687:                    this .value += getProject().replaceProperties(value);
688:                }
689:
690:                /**
691:                 * s:^\s*:: on each line of input
692:                 * @param strip if true do the trim
693:                 */
694:                public void setTrimLeading(boolean strip) {
695:                    this .trimLeading = strip;
696:                }
697:
698:                /**
699:                 * whether to call text.trim()
700:                 * @param trim if true trim the text
701:                 */
702:                public void setTrim(boolean trim) {
703:                    this .trim = trim;
704:                }
705:
706:                /**
707:                 * @return the text, after possible trimming
708:                 */
709:                public String getValue() {
710:                    if (value == null) {
711:                        value = "";
712:                    }
713:                    if (value.trim().length() == 0) {
714:                        value = "";
715:                    }
716:                    if (trimLeading) {
717:                        char[] current = value.toCharArray();
718:                        StringBuffer b = new StringBuffer(current.length);
719:                        boolean startOfLine = true;
720:                        int pos = 0;
721:                        while (pos < current.length) {
722:                            char ch = current[pos++];
723:                            if (startOfLine) {
724:                                if (ch == ' ' || ch == '\t') {
725:                                    continue;
726:                                }
727:                                startOfLine = false;
728:                            }
729:                            b.append(ch);
730:                            if (ch == '\n' || ch == '\r') {
731:                                startOfLine = true;
732:                            }
733:                        }
734:                        value = b.toString();
735:                    }
736:                    if (trim) {
737:                        value = value.trim();
738:                    }
739:                    return value;
740:                }
741:            }
742:
743:            /**
744:             * This class reads from each of the source files in turn.
745:             * The concatentated result can then be filtered as
746:             * a single stream.
747:             */
748:            private class MultiReader extends Reader {
749:                private Reader reader = null;
750:                private int lastPos = 0;
751:                private char[] lastChars = new char[eolString.length()];
752:                private boolean needAddSeparator = false;
753:                private Iterator i;
754:
755:                private MultiReader(ResourceCollection c) {
756:                    i = c.iterator();
757:                }
758:
759:                private Reader getReader() throws IOException {
760:                    if (reader == null && i.hasNext()) {
761:                        Resource r = (Resource) i.next();
762:                        log("Concating " + r.toLongString(),
763:                                Project.MSG_VERBOSE);
764:                        InputStream is = r.getInputStream();
765:                        reader = new BufferedReader(
766:                                encoding == null ? new InputStreamReader(is)
767:                                        : new InputStreamReader(is, encoding));
768:                        Arrays.fill(lastChars, (char) 0);
769:                    }
770:                    return reader;
771:                }
772:
773:                private void nextReader() throws IOException {
774:                    close();
775:                    reader = null;
776:                }
777:
778:                /**
779:                 * Read a character from the current reader object. Advance
780:                 * to the next if the reader is finished.
781:                 * @return the character read, -1 for EOF on the last reader.
782:                 * @exception IOException - possibly thrown by the read for a reader
783:                 *            object.
784:                 */
785:                public int read() throws IOException {
786:                    if (needAddSeparator) {
787:                        int ret = eolString.charAt(lastPos++);
788:                        if (lastPos >= eolString.length()) {
789:                            lastPos = 0;
790:                            needAddSeparator = false;
791:                        }
792:                        return ret;
793:                    }
794:                    while (getReader() != null) {
795:                        int ch = getReader().read();
796:                        if (ch == -1) {
797:                            nextReader();
798:                            if (fixLastLine && isMissingEndOfLine()) {
799:                                needAddSeparator = true;
800:                                lastPos = 0;
801:                            }
802:                        } else {
803:                            addLastChar((char) ch);
804:                            return ch;
805:                        }
806:                    }
807:                    return -1;
808:                }
809:
810:                /**
811:                 * Read into the buffer <code>cbuf</code>.
812:                 * @param cbuf The array to be read into.
813:                 * @param off The offset.
814:                 * @param len The length to read.
815:                 * @exception IOException - possibly thrown by the reads to the
816:                 *            reader objects.
817:                 */
818:                public int read(char[] cbuf, int off, int len)
819:                        throws IOException {
820:
821:                    int amountRead = 0;
822:                    while (getReader() != null || needAddSeparator) {
823:                        if (needAddSeparator) {
824:                            cbuf[off] = eolString.charAt(lastPos++);
825:                            if (lastPos >= eolString.length()) {
826:                                lastPos = 0;
827:                                needAddSeparator = false;
828:                            }
829:                            len--;
830:                            off++;
831:                            amountRead++;
832:                            if (len == 0) {
833:                                return amountRead;
834:                            }
835:                            continue;
836:                        }
837:                        int nRead = getReader().read(cbuf, off, len);
838:                        if (nRead == -1 || nRead == 0) {
839:                            nextReader();
840:                            if (fixLastLine && isMissingEndOfLine()) {
841:                                needAddSeparator = true;
842:                                lastPos = 0;
843:                            }
844:                        } else {
845:                            if (fixLastLine) {
846:                                for (int i = nRead; i > (nRead - lastChars.length); --i) {
847:                                    if (i <= 0) {
848:                                        break;
849:                                    }
850:                                    addLastChar(cbuf[off + i - 1]);
851:                                }
852:                            }
853:                            len -= nRead;
854:                            off += nRead;
855:                            amountRead += nRead;
856:                            if (len == 0) {
857:                                return amountRead;
858:                            }
859:                        }
860:                    }
861:                    if (amountRead == 0) {
862:                        return -1;
863:                    } else {
864:                        return amountRead;
865:                    }
866:                }
867:
868:                /**
869:                 * Close the current reader
870:                 */
871:                public void close() throws IOException {
872:                    if (reader != null) {
873:                        reader.close();
874:                    }
875:                }
876:
877:                /**
878:                 * if checking for end of line at end of file
879:                 * add a character to the lastchars buffer
880:                 */
881:                private void addLastChar(char ch) {
882:                    for (int i = lastChars.length - 2; i >= 0; --i) {
883:                        lastChars[i] = lastChars[i + 1];
884:                    }
885:                    lastChars[lastChars.length - 1] = ch;
886:                }
887:
888:                /**
889:                 * return true if the lastchars buffer does
890:                 * not contain the lineseparator
891:                 */
892:                private boolean isMissingEndOfLine() {
893:                    for (int i = 0; i < lastChars.length; ++i) {
894:                        if (lastChars[i] != eolString.charAt(i)) {
895:                            return true;
896:                        }
897:                    }
898:                    return false;
899:                }
900:            }
901:
902:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.