Source Code Cross Referenced for FixCrLfFilter.java in  » Build » ANT » org » apache » tools » ant » filters » 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.filters 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
0003:         *  contributor license agreements.  See the NOTICE file distributed with
0004:         *  this work for additional information regarding copyright ownership.
0005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
0006:         *  (the "License"); you may not use this file except in compliance with
0007:         *  the License.  You may obtain a copy of the License at
0008:         *
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         *  Unless required by applicable law or agreed to in writing, software
0012:         *  distributed under the License is distributed on an "AS IS" BASIS,
0013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         *  See the License for the specific language governing permissions and
0015:         *  limitations under the License.
0016:         *
0017:         */
0018:        package org.apache.tools.ant.filters;
0019:
0020:        import java.io.IOException;
0021:        import java.io.Reader;
0022:        import org.apache.tools.ant.BuildException;
0023:        import org.apache.tools.ant.taskdefs.condition.Os;
0024:        import org.apache.tools.ant.types.EnumeratedAttribute;
0025:
0026:        /**
0027:         * Converts text to local OS formatting conventions, as well as repair text
0028:         * damaged by misconfigured or misguided editors or file transfer programs.
0029:         * <p>
0030:         * This filter can take the following arguments:
0031:         * <ul>
0032:         * <li>eof
0033:         * <li>eol
0034:         * <li>fixlast
0035:         * <li>javafiles
0036:         * <li>tab
0037:         * <li>tablength
0038:         * </ul>
0039:         * None of which are required.
0040:         * <p>
0041:         * This version generalises the handling of EOL characters, and allows for
0042:         * CR-only line endings (the standard on Mac systems prior to OS X). Tab
0043:         * handling has also been generalised to accommodate any tabwidth from 2 to 80,
0044:         * inclusive. Importantly, it can leave untouched any literal TAB characters
0045:         * embedded within Java string or character constants.
0046:         * <p>
0047:         * <em>Caution:</em> run with care on carefully formatted files. This may
0048:         * sound obvious, but if you don't specify asis, presume that your files are
0049:         * going to be modified. If "tabs" is "add" or "remove", whitespace characters
0050:         * may be added or removed as necessary. Similarly, for EOLs, eol="asis"
0051:         * actually means convert to your native O/S EOL convention while eol="crlf" or
0052:         * cr="add" can result in CR characters being removed in one special case
0053:         * accommodated, i.e., CRCRLF is regarded as a single EOL to handle cases where
0054:         * other programs have converted CRLF into CRCRLF.
0055:         *
0056:         * <P>
0057:         * Example:
0058:         *
0059:         * <pre>
0060:         * &lt;&lt;fixcrlf tab=&quot;add&quot; eol=&quot;crlf&quot; eof=&quot;asis&quot;/&gt;
0061:         * </pre>
0062:         *
0063:         * Or:
0064:         *
0065:         * <pre>
0066:         * &lt;filterreader classname=&quot;org.apache.tools.ant.filters.FixCrLfFilter&quot;&gt;
0067:         *   &lt;param eol=&quot;crlf&quot; tab=&quot;asis&quot;/&gt;
0068:         *  &lt;/filterreader&gt;
0069:         * </pre>
0070:         *
0071:         */
0072:        public final class FixCrLfFilter extends BaseParamFilterReader
0073:                implements  ChainableReader {
0074:            private static final char CTRLZ = '\u001A';
0075:
0076:            private int tabLength = 8;
0077:
0078:            private CrLf eol;
0079:
0080:            private AddAsisRemove ctrlz;
0081:
0082:            private AddAsisRemove tabs;
0083:
0084:            private boolean javafiles = false;
0085:
0086:            private boolean fixlast = true;
0087:
0088:            private boolean initialized = false;
0089:
0090:            /**
0091:             * Constructor for "dummy" instances.
0092:             *
0093:             * @see BaseFilterReader#BaseFilterReader()
0094:             */
0095:            public FixCrLfFilter() {
0096:                super ();
0097:            }
0098:
0099:            /**
0100:             * Create a new filtered reader.
0101:             *
0102:             * @param in
0103:             *            A Reader object providing the underlying stream. Must not be
0104:             *            <code>null</code>.
0105:             * @throws IOException on error.
0106:             */
0107:            public FixCrLfFilter(final Reader in) throws IOException {
0108:                super (in);
0109:            }
0110:
0111:            // Instance initializer: Executes just after the super() call in this
0112:            // class's constructor.
0113:            {
0114:                tabs = AddAsisRemove.ASIS;
0115:                if (Os.isFamily("mac") && !Os.isFamily("unix")) {
0116:                    ctrlz = AddAsisRemove.REMOVE;
0117:                    setEol(CrLf.MAC);
0118:                } else if (Os.isFamily("dos")) {
0119:                    ctrlz = AddAsisRemove.ASIS;
0120:                    setEol(CrLf.DOS);
0121:                } else {
0122:                    ctrlz = AddAsisRemove.REMOVE;
0123:                    setEol(CrLf.UNIX);
0124:                }
0125:            }
0126:
0127:            /**
0128:             * Create a new FixCrLfFilter using the passed in Reader for instantiation.
0129:             *
0130:             * @param rdr
0131:             *            A Reader object providing the underlying stream. Must not be
0132:             *            <code>null</code>.
0133:             *
0134:             * @return a new filter based on this configuration, but filtering the
0135:             *         specified reader.
0136:             */
0137:            public Reader chain(final Reader rdr) {
0138:                try {
0139:                    FixCrLfFilter newFilter = new FixCrLfFilter(rdr);
0140:
0141:                    newFilter.setJavafiles(getJavafiles());
0142:                    newFilter.setEol(getEol());
0143:                    newFilter.setTab(getTab());
0144:                    newFilter.setTablength(getTablength());
0145:                    newFilter.setEof(getEof());
0146:                    newFilter.setFixlast(getFixlast());
0147:                    newFilter.initInternalFilters();
0148:
0149:                    return newFilter;
0150:                } catch (IOException e) {
0151:                    throw new BuildException(e);
0152:                }
0153:            }
0154:
0155:            /**
0156:             * Get how DOS EOF (control-z) characters are being handled.
0157:             *
0158:             * @return values:
0159:             *         <ul>
0160:             *         <li>add: ensure that there is an eof at the end of the file
0161:             *         <li>asis: leave eof characters alone
0162:             *         <li>remove: remove any eof character found at the end
0163:             *         </ul>
0164:             */
0165:            public AddAsisRemove getEof() {
0166:                // Return copy so that the call must call setEof() to change the state
0167:                // of fixCRLF
0168:                return ctrlz.newInstance();
0169:            }
0170:
0171:            /**
0172:             * Get how EndOfLine characters are being handled.
0173:             *
0174:             * @return values:
0175:             *         <ul>
0176:             *         <li>asis: convert line endings to your O/S convention
0177:             *         <li>cr: convert line endings to CR
0178:             *         <li>lf: convert line endings to LF
0179:             *         <li>crlf: convert line endings to CRLF
0180:             *         </ul>
0181:             */
0182:            public CrLf getEol() {
0183:                // Return copy so that the call must call setEol() to change the state
0184:                // of fixCRLF
0185:                return eol.newInstance();
0186:            }
0187:
0188:            /**
0189:             * Get whether a missing EOL be added to the final line of the stream.
0190:             *
0191:             * @return true if a filtered file will always end with an EOL
0192:             */
0193:            public boolean getFixlast() {
0194:                return fixlast;
0195:            }
0196:
0197:            /**
0198:             * Get whether the stream is to be treated as though it contains Java
0199:             * source.
0200:             * <P>
0201:             * This attribute is only used in assocation with the &quot;<i><b>tab</b></i>&quot;
0202:             * attribute. Tabs found in Java literals are protected from changes by this
0203:             * filter.
0204:             *
0205:             * @return true if whitespace in Java character and string literals is
0206:             *         ignored.
0207:             */
0208:            public boolean getJavafiles() {
0209:                return javafiles;
0210:            }
0211:
0212:            /**
0213:             * Return how tab characters are being handled.
0214:             *
0215:             * @return values:
0216:             *         <ul>
0217:             *         <li>add: convert sequences of spaces which span a tab stop to
0218:             *         tabs
0219:             *         <li>asis: leave tab and space characters alone
0220:             *         <li>remove: convert tabs to spaces
0221:             *         </ul>
0222:             */
0223:            public AddAsisRemove getTab() {
0224:                // Return copy so that the caller must call setTab() to change the state
0225:                // of fixCRLF.
0226:                return tabs.newInstance();
0227:            }
0228:
0229:            /**
0230:             * Get the tab length to use.
0231:             *
0232:             * @return the length of tab in spaces
0233:             */
0234:            public int getTablength() {
0235:                return tabLength;
0236:            }
0237:
0238:            private static String calculateEolString(CrLf eol) {
0239:                // Calculate the EOL string per the current config
0240:                if (eol == CrLf.ASIS) {
0241:                    return System.getProperty("line.separator");
0242:                }
0243:                if (eol == CrLf.CR || eol == CrLf.MAC) {
0244:                    return "\r";
0245:                }
0246:                if (eol == CrLf.CRLF || eol == CrLf.DOS) {
0247:                    return "\r\n";
0248:                }
0249:                // assume (eol == CrLf.LF || eol == CrLf.UNIX)
0250:                return "\n";
0251:            }
0252:
0253:            /**
0254:             * Wrap the input stream with the internal filters necessary to perform the
0255:             * configuration settings.
0256:             */
0257:            private void initInternalFilters() {
0258:
0259:                // If I'm removing an EOF character, do so first so that the other
0260:                // filters don't see that character.
0261:                in = (ctrlz == AddAsisRemove.REMOVE) ? new RemoveEofFilter(in)
0262:                        : in;
0263:
0264:                // Change all EOL characters to match the calculated EOL string. If
0265:                // configured to do so, append a trailing EOL so that the file ends on
0266:                // a EOL.
0267:                in = new NormalizeEolFilter(in, calculateEolString(eol),
0268:                        getFixlast());
0269:
0270:                if (tabs != AddAsisRemove.ASIS) {
0271:                    // If filtering Java source, prevent changes to whitespace in
0272:                    // character and string literals.
0273:                    if (getJavafiles()) {
0274:                        in = new MaskJavaTabLiteralsFilter(in);
0275:                    }
0276:                    // Add/Remove tabs
0277:                    in = (tabs == AddAsisRemove.ADD) ? (Reader) new AddTabFilter(
0278:                            in, getTablength())
0279:                            : (Reader) new RemoveTabFilter(in, getTablength());
0280:                }
0281:                // Add missing EOF character
0282:                in = (ctrlz == AddAsisRemove.ADD) ? new AddEofFilter(in) : in;
0283:                initialized = true;
0284:            }
0285:
0286:            /**
0287:             * Return the next character in the filtered stream.
0288:             *
0289:             * @return the next character in the resulting stream, or -1 if the end of
0290:             *         the resulting stream has been reached.
0291:             *
0292:             * @exception IOException
0293:             *                if the underlying stream throws an IOException during
0294:             *                reading.
0295:             */
0296:            public synchronized int read() throws IOException {
0297:                if (!initialized) {
0298:                    initInternalFilters();
0299:                }
0300:                return in.read();
0301:            }
0302:
0303:            /**
0304:             * Specify how DOS EOF (control-z) characters are to be handled.
0305:             *
0306:             * @param attr
0307:             *            valid values:
0308:             *            <ul>
0309:             *            <li>add: ensure that there is an eof at the end of the file
0310:             *            <li>asis: leave eof characters alone
0311:             *            <li>remove: remove any eof character found at the end
0312:             *            </ul>
0313:             */
0314:            public void setEof(AddAsisRemove attr) {
0315:                ctrlz = attr.resolve();
0316:            }
0317:
0318:            /**
0319:             * Specify how end of line (EOL) characters are to be handled.
0320:             *
0321:             * @param attr
0322:             *            valid values:
0323:             *            <ul>
0324:             *            <li>asis: convert line endings to your O/S convention
0325:             *            <li>cr: convert line endings to CR
0326:             *            <li>lf: convert line endings to LF
0327:             *            <li>crlf: convert line endings to CRLF
0328:             *            </ul>
0329:             */
0330:            public void setEol(CrLf attr) {
0331:                eol = attr.resolve();
0332:            }
0333:
0334:            /**
0335:             * Specify whether a missing EOL will be added to the final line of input.
0336:             *
0337:             * @param fixlast
0338:             *            if true a missing EOL will be appended.
0339:             */
0340:            public void setFixlast(boolean fixlast) {
0341:                this .fixlast = fixlast;
0342:            }
0343:
0344:            /**
0345:             * Indicate whether this stream contains Java source.
0346:             *
0347:             * This attribute is only used in assocation with the &quot;<i><b>tab</b></i>&quot;
0348:             * attribute.
0349:             *
0350:             * @param javafiles
0351:             *            set to true to prevent this filter from changing tabs found in
0352:             *            Java literals.
0353:             */
0354:            public void setJavafiles(boolean javafiles) {
0355:                this .javafiles = javafiles;
0356:            }
0357:
0358:            /**
0359:             * Specify how tab characters are to be handled.
0360:             *
0361:             * @param attr
0362:             *            valid values:
0363:             *            <ul>
0364:             *            <li>add: convert sequences of spaces which span a tab stop to
0365:             *            tabs
0366:             *            <li>asis: leave tab and space characters alone
0367:             *            <li>remove: convert tabs to spaces
0368:             *            </ul>
0369:             */
0370:            public void setTab(AddAsisRemove attr) {
0371:                tabs = attr.resolve();
0372:            }
0373:
0374:            /**
0375:             * Specify tab length in characters.
0376:             *
0377:             * @param tabLength
0378:             *            specify the length of tab in spaces. Valid values are between
0379:             *            2 and 80 inclusive. The default for this parameter is 8.
0380:             * @throws IOException on error.
0381:             */
0382:            public void setTablength(int tabLength) throws IOException {
0383:                if (tabLength < 2 || tabLength > 80) {
0384:                    throw new IOException("tablength must be between 2 and 80");
0385:                }
0386:                this .tabLength = tabLength;
0387:            }
0388:
0389:            /**
0390:             * This filter reader redirects all read I/O methods through its own read()
0391:             * method.
0392:             *
0393:             * <P>
0394:             * The input stream is already buffered by the copy task so this doesn't
0395:             * significantly impact performance while it makes writing the individual
0396:             * fix filters much easier.
0397:             * </P>
0398:             */
0399:            private static class SimpleFilterReader extends Reader {
0400:                private Reader in;
0401:
0402:                private int[] preempt = new int[16];
0403:
0404:                private int preemptIndex = 0;
0405:
0406:                public SimpleFilterReader(Reader in) {
0407:                    this .in = in;
0408:                }
0409:
0410:                public void push(char c) {
0411:                    push((int) c);
0412:                }
0413:
0414:                public void push(int c) {
0415:                    try {
0416:                        preempt[preemptIndex++] = c;
0417:                    } catch (ArrayIndexOutOfBoundsException e) {
0418:                        int[] p2 = new int[preempt.length * 2];
0419:                        System.arraycopy(preempt, 0, p2, 0, preempt.length);
0420:                        preempt = p2;
0421:                        push(c);
0422:                    }
0423:                }
0424:
0425:                public void push(char[] cs, int start, int length) {
0426:                    for (int i = start + length - 1; i >= start;) {
0427:                        push(cs[i--]);
0428:                    }
0429:                }
0430:
0431:                public void push(char[] cs) {
0432:                    push(cs, 0, cs.length);
0433:                }
0434:
0435:                public void push(String s) {
0436:                    push(s.toCharArray());
0437:                }
0438:
0439:                /**
0440:                 * Does this filter want to block edits on the last character returned
0441:                 * by read()?
0442:                 */
0443:                public boolean editsBlocked() {
0444:                    return in instanceof  SimpleFilterReader
0445:                            && ((SimpleFilterReader) in).editsBlocked();
0446:                }
0447:
0448:                public int read() throws java.io.IOException {
0449:                    return preemptIndex > 0 ? preempt[--preemptIndex] : in
0450:                            .read();
0451:                }
0452:
0453:                public void close() throws java.io.IOException {
0454:                    in.close();
0455:                }
0456:
0457:                public void reset() throws IOException {
0458:                    in.reset();
0459:                }
0460:
0461:                public boolean markSupported() {
0462:                    return in.markSupported();
0463:                }
0464:
0465:                public boolean ready() throws java.io.IOException {
0466:                    return in.ready();
0467:                }
0468:
0469:                public void mark(int i) throws java.io.IOException {
0470:                    in.mark(i);
0471:                }
0472:
0473:                public long skip(long i) throws java.io.IOException {
0474:                    return in.skip(i);
0475:                }
0476:
0477:                public int read(char[] buf) throws java.io.IOException {
0478:                    return read(buf, 0, buf.length);
0479:                }
0480:
0481:                public int read(char[] buf, int start, int length)
0482:                        throws java.io.IOException {
0483:                    int count = 0;
0484:                    int c = 0;
0485:
0486:                    while (length-- > 0 && (c = this .read()) != -1) {
0487:                        buf[start++] = (char) c;
0488:                        count++;
0489:                    }
0490:                    // if at EOF with no characters in the buffer, return EOF
0491:                    return (count == 0 && c == -1) ? -1 : count;
0492:                }
0493:            }
0494:
0495:            private static class MaskJavaTabLiteralsFilter extends
0496:                    SimpleFilterReader {
0497:                private boolean editsBlocked = false;
0498:
0499:                private static final int JAVA = 1;
0500:
0501:                private static final int IN_CHAR_CONST = 2;
0502:
0503:                private static final int IN_STR_CONST = 3;
0504:
0505:                private static final int IN_SINGLE_COMMENT = 4;
0506:
0507:                private static final int IN_MULTI_COMMENT = 5;
0508:
0509:                private static final int TRANS_TO_COMMENT = 6;
0510:
0511:                private static final int TRANS_FROM_MULTI = 8;
0512:
0513:                private int state;
0514:
0515:                public MaskJavaTabLiteralsFilter(Reader in) {
0516:                    super (in);
0517:                    state = JAVA;
0518:                }
0519:
0520:                public boolean editsBlocked() {
0521:                    return editsBlocked || super .editsBlocked();
0522:                }
0523:
0524:                public int read() throws IOException {
0525:                    int this Char = super .read();
0526:                    // Mask, block from being edited, all characters in constants.
0527:                    editsBlocked = (state == IN_CHAR_CONST || state == IN_STR_CONST);
0528:
0529:                    switch (state) {
0530:                    case JAVA:
0531:                        // The current character is always emitted.
0532:                        switch (this Char) {
0533:                        case '\'':
0534:                            state = IN_CHAR_CONST;
0535:                            break;
0536:                        case '"':
0537:                            state = IN_STR_CONST;
0538:                            break;
0539:                        case '/':
0540:                            state = TRANS_TO_COMMENT;
0541:                            break;
0542:                        default:
0543:                            // Fall tru
0544:                        }
0545:                        break;
0546:                    case IN_CHAR_CONST:
0547:                        switch (this Char) {
0548:                        case '\'':
0549:                            state = JAVA;
0550:                            break;
0551:                        default:
0552:                            // Fall tru
0553:                        }
0554:                        break;
0555:                    case IN_STR_CONST:
0556:                        switch (this Char) {
0557:                        case '"':
0558:                            state = JAVA;
0559:                            break;
0560:                        default:
0561:                            // Fall tru
0562:                        }
0563:                        break;
0564:                    case IN_SINGLE_COMMENT:
0565:                        // The current character is always emitted.
0566:                        switch (this Char) {
0567:                        case '\n':
0568:                        case '\r': // EOL
0569:                            state = JAVA;
0570:                            break;
0571:                        default:
0572:                            // Fall tru
0573:                        }
0574:                        break;
0575:                    case IN_MULTI_COMMENT:
0576:                        // The current character is always emitted.
0577:                        switch (this Char) {
0578:                        case '*':
0579:                            state = TRANS_FROM_MULTI;
0580:                            break;
0581:                        default:
0582:                            // Fall tru
0583:                        }
0584:                        break;
0585:                    case TRANS_TO_COMMENT:
0586:                        // The current character is always emitted.
0587:                        switch (this Char) {
0588:                        case '*':
0589:                            state = IN_MULTI_COMMENT;
0590:                            break;
0591:                        case '/':
0592:                            state = IN_SINGLE_COMMENT;
0593:                            break;
0594:                        case '\'':
0595:                            state = IN_CHAR_CONST;
0596:                            break;
0597:                        case '"':
0598:                            state = IN_STR_CONST;
0599:                            break;
0600:                        default:
0601:                            state = JAVA;
0602:                        }
0603:                        break;
0604:                    case TRANS_FROM_MULTI:
0605:                        // The current character is always emitted.
0606:                        switch (this Char) {
0607:                        case '/':
0608:                            state = JAVA;
0609:                            break;
0610:                        default:
0611:                            // Fall tru
0612:                        }
0613:                        break;
0614:                    default:
0615:                        // Fall tru
0616:                    }
0617:                    return this Char;
0618:                }
0619:            }
0620:
0621:            private static class NormalizeEolFilter extends SimpleFilterReader {
0622:                private boolean previousWasEOL;
0623:
0624:                private boolean fixLast;
0625:
0626:                private int normalizedEOL = 0;
0627:
0628:                private char[] eol = null;
0629:
0630:                public NormalizeEolFilter(Reader in, String eolString,
0631:                        boolean fixLast) {
0632:                    super (in);
0633:                    eol = eolString.toCharArray();
0634:                    this .fixLast = fixLast;
0635:                }
0636:
0637:                public int read() throws IOException {
0638:                    int this Char = super .read();
0639:
0640:                    if (normalizedEOL == 0) {
0641:                        int numEOL = 0;
0642:                        boolean atEnd = false;
0643:                        switch (this Char) {
0644:                        case CTRLZ:
0645:                            int c = super .read();
0646:                            if (c == -1) {
0647:                                atEnd = true;
0648:                                if (fixLast && !previousWasEOL) {
0649:                                    numEOL = 1;
0650:                                    push(this Char);
0651:                                }
0652:                            } else {
0653:                                push(c);
0654:                            }
0655:                            break;
0656:                        case -1:
0657:                            atEnd = true;
0658:                            if (fixLast && !previousWasEOL) {
0659:                                numEOL = 1;
0660:                            }
0661:                            break;
0662:                        case '\n':
0663:                            // EOL was "\n"
0664:                            numEOL = 1;
0665:                            break;
0666:                        case '\r':
0667:                            numEOL = 1;
0668:                            int c1 = super .read();
0669:                            int c2 = super .read();
0670:
0671:                            if (c1 == '\r' && c2 == '\n') {
0672:                                // EOL was "\r\r\n"
0673:                            } else if (c1 == '\r') {
0674:                                // EOL was "\r\r" - handle as two consecutive "\r" and
0675:                                // "\r"
0676:                                numEOL = 2;
0677:                                push(c2);
0678:                            } else if (c1 == '\n') {
0679:                                // EOL was "\r\n"
0680:                                push(c2);
0681:                            } else {
0682:                                // EOL was "\r"
0683:                                push(c2);
0684:                                push(c1);
0685:                            }
0686:                        default:
0687:                            // Fall tru
0688:                        }
0689:                        if (numEOL > 0) {
0690:                            while (numEOL-- > 0) {
0691:                                push(eol);
0692:                                normalizedEOL += eol.length;
0693:                            }
0694:                            previousWasEOL = true;
0695:                            this Char = read();
0696:                        } else if (!atEnd) {
0697:                            previousWasEOL = false;
0698:                        }
0699:                    } else {
0700:                        normalizedEOL--;
0701:                    }
0702:                    return this Char;
0703:                }
0704:            }
0705:
0706:            private static class AddEofFilter extends SimpleFilterReader {
0707:                private int lastChar = -1;
0708:
0709:                public AddEofFilter(Reader in) {
0710:                    super (in);
0711:                }
0712:
0713:                public int read() throws IOException {
0714:                    int this Char = super .read();
0715:
0716:                    // if source is EOF but last character was NOT ctrl-z, return ctrl-z
0717:                    if (this Char == -1) {
0718:                        if (lastChar != CTRLZ) {
0719:                            lastChar = CTRLZ;
0720:                            return lastChar;
0721:                        }
0722:                    } else {
0723:                        lastChar = this Char;
0724:                    }
0725:                    return this Char;
0726:                }
0727:            }
0728:
0729:            private static class RemoveEofFilter extends SimpleFilterReader {
0730:                private int lookAhead = -1;
0731:
0732:                public RemoveEofFilter(Reader in) {
0733:                    super (in);
0734:
0735:                    try {
0736:                        lookAhead = in.read();
0737:                    } catch (IOException e) {
0738:                        lookAhead = -1;
0739:                    }
0740:                }
0741:
0742:                public int read() throws IOException {
0743:                    int lookAhead2 = super .read();
0744:
0745:                    // If source at EOF and lookAhead is ctrl-z, return EOF (NOT ctrl-z)
0746:                    if (lookAhead2 == -1 && lookAhead == CTRLZ) {
0747:                        return -1;
0748:                    }
0749:                    // Return current look-ahead
0750:                    int i = lookAhead;
0751:                    lookAhead = lookAhead2;
0752:                    return i;
0753:                }
0754:            }
0755:
0756:            private static class AddTabFilter extends SimpleFilterReader {
0757:                private int columnNumber = 0;
0758:
0759:                private int tabLength = 0;
0760:
0761:                public AddTabFilter(Reader in, int tabLength) {
0762:                    super (in);
0763:                    this .tabLength = tabLength;
0764:                }
0765:
0766:                public int read() throws IOException {
0767:                    int c = super .read();
0768:
0769:                    switch (c) {
0770:                    case '\r':
0771:                    case '\n':
0772:                        columnNumber = 0;
0773:                        break;
0774:                    case ' ':
0775:                        columnNumber++;
0776:                        if (!editsBlocked()) {
0777:                            int colNextTab = ((columnNumber + tabLength - 1) / tabLength)
0778:                                    * tabLength;
0779:                            int countSpaces = 1;
0780:                            int numTabs = 0;
0781:
0782:                            scanWhitespace: while ((c = super .read()) != -1) {
0783:                                switch (c) {
0784:                                case ' ':
0785:                                    if (++columnNumber == colNextTab) {
0786:                                        numTabs++;
0787:                                        countSpaces = 0;
0788:                                        colNextTab += tabLength;
0789:                                    } else {
0790:                                        countSpaces++;
0791:                                    }
0792:                                    break;
0793:                                case '\t':
0794:                                    columnNumber = colNextTab;
0795:                                    numTabs++;
0796:                                    countSpaces = 0;
0797:                                    colNextTab += tabLength;
0798:                                    break;
0799:                                default:
0800:                                    push(c);
0801:                                    break scanWhitespace;
0802:                                }
0803:                            }
0804:                            while (countSpaces-- > 0) {
0805:                                push(' ');
0806:                                columnNumber--;
0807:                            }
0808:                            while (numTabs-- > 0) {
0809:                                push('\t');
0810:                                columnNumber -= tabLength;
0811:                            }
0812:                            c = super .read();
0813:                            switch (c) {
0814:                            case ' ':
0815:                                columnNumber++;
0816:                                break;
0817:                            case '\t':
0818:                                columnNumber += tabLength;
0819:                                break;
0820:                            default:
0821:                                // Fall tru
0822:                            }
0823:                        }
0824:                        break;
0825:                    case '\t':
0826:                        columnNumber = ((columnNumber + tabLength - 1) / tabLength)
0827:                                * tabLength;
0828:                        break;
0829:                    default:
0830:                        columnNumber++;
0831:                    }
0832:                    return c;
0833:                }
0834:            }
0835:
0836:            private static class RemoveTabFilter extends SimpleFilterReader {
0837:                private int columnNumber = 0;
0838:
0839:                private int tabLength = 0;
0840:
0841:                public RemoveTabFilter(Reader in, int tabLength) {
0842:                    super (in);
0843:
0844:                    this .tabLength = tabLength;
0845:                }
0846:
0847:                public int read() throws IOException {
0848:                    int c = super .read();
0849:
0850:                    switch (c) {
0851:                    case '\r':
0852:                    case '\n':
0853:                        columnNumber = 0;
0854:                        break;
0855:                    case '\t':
0856:                        int width = tabLength - columnNumber % tabLength;
0857:
0858:                        if (!editsBlocked()) {
0859:                            for (; width > 1; width--) {
0860:                                push(' ');
0861:                            }
0862:                            c = ' ';
0863:                        }
0864:                        columnNumber += width;
0865:                        break;
0866:                    default:
0867:                        columnNumber++;
0868:                    }
0869:                    return c;
0870:                }
0871:            }
0872:
0873:            /**
0874:             * Enumerated attribute with the values "asis", "add" and "remove".
0875:             */
0876:            public static class AddAsisRemove extends EnumeratedAttribute {
0877:                private static final AddAsisRemove ASIS = newInstance("asis");
0878:
0879:                private static final AddAsisRemove ADD = newInstance("add");
0880:
0881:                private static final AddAsisRemove REMOVE = newInstance("remove");
0882:
0883:                /** {@inheritDoc}. */
0884:                public String[] getValues() {
0885:                    return new String[] { "add", "asis", "remove" };
0886:                }
0887:
0888:                /**
0889:                 * Equality depending in the index.
0890:                 * @param other the object to test equality against.
0891:                 * @return true if the object has the same index as this.
0892:                 */
0893:                public boolean equals(Object other) {
0894:                    return other instanceof  AddAsisRemove
0895:                            && getIndex() == ((AddAsisRemove) other).getIndex();
0896:                }
0897:
0898:                /**
0899:                 * Hashcode depending on the index.
0900:                 * @return the index as the hashcode.
0901:                 */
0902:                public int hashCode() {
0903:                    return getIndex();
0904:                }
0905:
0906:                AddAsisRemove resolve() throws IllegalStateException {
0907:                    if (this .equals(ASIS)) {
0908:                        return ASIS;
0909:                    }
0910:                    if (this .equals(ADD)) {
0911:                        return ADD;
0912:                    }
0913:                    if (this .equals(REMOVE)) {
0914:                        return REMOVE;
0915:                    }
0916:                    throw new IllegalStateException("No replacement for "
0917:                            + this );
0918:                }
0919:
0920:                // Works like clone() but doesn't show up in the Javadocs
0921:                private AddAsisRemove newInstance() {
0922:                    return newInstance(getValue());
0923:                }
0924:
0925:                /**
0926:                 * Create an instance of this enumerated value based on the string value.
0927:                 * @param value the value to use.
0928:                 * @return an enumerated instance.
0929:                 */
0930:                public static AddAsisRemove newInstance(String value) {
0931:                    AddAsisRemove a = new AddAsisRemove();
0932:                    a.setValue(value);
0933:                    return a;
0934:                }
0935:            }
0936:
0937:            /**
0938:             * Enumerated attribute with the values "asis", "cr", "lf" and "crlf".
0939:             */
0940:            public static class CrLf extends EnumeratedAttribute {
0941:                private static final CrLf ASIS = newInstance("asis");
0942:
0943:                private static final CrLf CR = newInstance("cr");
0944:
0945:                private static final CrLf CRLF = newInstance("crlf");
0946:
0947:                private static final CrLf DOS = newInstance("dos");
0948:
0949:                private static final CrLf LF = newInstance("lf");
0950:
0951:                private static final CrLf MAC = newInstance("mac");
0952:
0953:                private static final CrLf UNIX = newInstance("unix");
0954:
0955:                /**
0956:                 * @see EnumeratedAttribute#getValues
0957:                 */
0958:                /** {@inheritDoc}. */
0959:                public String[] getValues() {
0960:                    return new String[] { "asis", "cr", "lf", "crlf", "mac",
0961:                            "unix", "dos" };
0962:                }
0963:
0964:                /**
0965:                 * Equality depending in the index.
0966:                 * @param other the object to test equality against.
0967:                 * @return true if the object has the same index as this.
0968:                 */
0969:                public boolean equals(Object other) {
0970:                    return other instanceof  CrLf
0971:                            && getIndex() == ((CrLf) other).getIndex();
0972:                }
0973:
0974:                /**
0975:                 * Hashcode depending on the index.
0976:                 * @return the index as the hashcode.
0977:                 */
0978:                public int hashCode() {
0979:                    return getIndex();
0980:                }
0981:
0982:                CrLf resolve() {
0983:                    if (this .equals(ASIS)) {
0984:                        return ASIS;
0985:                    }
0986:                    if (this .equals(CR) || this .equals(MAC)) {
0987:                        return CR;
0988:                    }
0989:                    if (this .equals(CRLF) || this .equals(DOS)) {
0990:                        return CRLF;
0991:                    }
0992:                    if (this .equals(LF) || this .equals(UNIX)) {
0993:                        return LF;
0994:                    }
0995:                    throw new IllegalStateException("No replacement for "
0996:                            + this );
0997:                }
0998:
0999:                // Works like clone() but doesn't show up in the Javadocs
1000:                private CrLf newInstance() {
1001:                    return newInstance(getValue());
1002:                }
1003:
1004:                /**
1005:                 * Create an instance of this enumerated value based on the string value.
1006:                 * @param value the value to use.
1007:                 * @return an enumerated instance.
1008:                 */
1009:                public static CrLf newInstance(String value) {
1010:                    CrLf c = new CrLf();
1011:                    c.setValue(value);
1012:                    return c;
1013:                }
1014:            }
1015:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.