KickJava   Java API By Example, From Geeks To Geeks.

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


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

18 package org.apache.tools.ant.filters;
19
20 import java.io.IOException JavaDoc;
21 import java.io.Reader JavaDoc;
22 import org.apache.tools.ant.BuildException;
23 import org.apache.tools.ant.taskdefs.condition.Os;
24 import org.apache.tools.ant.types.EnumeratedAttribute;
25
26 /**
27  * Converts text to local OS formatting conventions, as well as repair text
28  * damaged by misconfigured or misguided editors or file transfer programs.
29  * <p>
30  * This filter can take the following arguments:
31  * <ul>
32  * <li>eof
33  * <li>eol
34  * <li>fixlast
35  * <li>javafiles
36  * <li>tab
37  * <li>tablength
38  * </ul>
39  * None of which are required.
40  * <p>
41  * This version generalises the handling of EOL characters, and allows for
42  * CR-only line endings (the standard on Mac systems prior to OS X). Tab
43  * handling has also been generalised to accommodate any tabwidth from 2 to 80,
44  * inclusive. Importantly, it can leave untouched any literal TAB characters
45  * embedded within Java string or character constants.
46  * <p>
47  * <em>Caution:</em> run with care on carefully formatted files. This may
48  * sound obvious, but if you don't specify asis, presume that your files are
49  * going to be modified. If "tabs" is "add" or "remove", whitespace characters
50  * may be added or removed as necessary. Similarly, for EOLs, eol="asis"
51  * actually means convert to your native O/S EOL convention while eol="crlf" or
52  * cr="add" can result in CR characters being removed in one special case
53  * accommodated, i.e., CRCRLF is regarded as a single EOL to handle cases where
54  * other programs have converted CRLF into CRCRLF.
55  *
56  * <P>
57  * Example:
58  *
59  * <pre>
60  * &lt;&lt;fixcrlf tab=&quot;add&quot; eol=&quot;crlf&quot; eof=&quot;asis&quot;/&gt;
61  * </pre>
62  *
63  * Or:
64  *
65  * <pre>
66  * &lt;filterreader classname=&quot;org.apache.tools.ant.filters.FixCrLfFilter&quot;&gt;
67  * &lt;param eol=&quot;crlf&quot; tab=&quot;asis&quot;/&gt;
68  * &lt;/filterreader&gt;
69  * </pre>
70  *
71  */

72 public final class FixCrLfFilter extends BaseParamFilterReader implements ChainableReader {
73     private static final char CTRLZ = '\u001A';
74
75     private int tabLength = 8;
76
77     private CrLf eol;
78
79     private AddAsisRemove ctrlz;
80
81     private AddAsisRemove tabs;
82
83     private boolean javafiles = false;
84
85     private boolean fixlast = true;
86
87     private boolean initialized = false;
88
89     /**
90      * Constructor for "dummy" instances.
91      *
92      * @see BaseFilterReader#BaseFilterReader()
93      */

94     public FixCrLfFilter() {
95         super();
96     }
97
98     /**
99      * Create a new filtered reader.
100      *
101      * @param in
102      * A Reader object providing the underlying stream. Must not be
103      * <code>null</code>.
104      * @throws IOException on error.
105      */

106     public FixCrLfFilter(final Reader JavaDoc in) throws IOException JavaDoc {
107         super(in);
108     }
109
110     // Instance initializer: Executes just after the super() call in this
111
// class's constructor.
112
{
113         tabs = AddAsisRemove.ASIS;
114         if (Os.isFamily("mac") && !Os.isFamily("unix")) {
115             ctrlz = AddAsisRemove.REMOVE;
116             setEol(CrLf.MAC);
117         } else if (Os.isFamily("dos")) {
118             ctrlz = AddAsisRemove.ASIS;
119             setEol(CrLf.DOS);
120         } else {
121             ctrlz = AddAsisRemove.REMOVE;
122             setEol(CrLf.UNIX);
123         }
124     }
125
126     /**
127      * Create a new FixCrLfFilter using the passed in Reader for instantiation.
128      *
129      * @param rdr
130      * A Reader object providing the underlying stream. Must not be
131      * <code>null</code>.
132      *
133      * @return a new filter based on this configuration, but filtering the
134      * specified reader.
135      */

136     public Reader JavaDoc chain(final Reader JavaDoc rdr) {
137         try {
138             FixCrLfFilter newFilter = new FixCrLfFilter(rdr);
139
140             newFilter.setJavafiles(getJavafiles());
141             newFilter.setEol(getEol());
142             newFilter.setTab(getTab());
143             newFilter.setTablength(getTablength());
144             newFilter.setEof(getEof());
145             newFilter.setFixlast(getFixlast());
146             newFilter.initInternalFilters();
147
148             return newFilter;
149         } catch (IOException JavaDoc e) {
150             throw new BuildException(e);
151         }
152     }
153
154     /**
155      * Get how DOS EOF (control-z) characters are being handled.
156      *
157      * @return values:
158      * <ul>
159      * <li>add: ensure that there is an eof at the end of the file
160      * <li>asis: leave eof characters alone
161      * <li>remove: remove any eof character found at the end
162      * </ul>
163      */

164     public AddAsisRemove getEof() {
165         // Return copy so that the call must call setEof() to change the state
166
// of fixCRLF
167
return ctrlz.newInstance();
168     }
169
170     /**
171      * Get how EndOfLine characters are being handled.
172      *
173      * @return values:
174      * <ul>
175      * <li>asis: convert line endings to your O/S convention
176      * <li>cr: convert line endings to CR
177      * <li>lf: convert line endings to LF
178      * <li>crlf: convert line endings to CRLF
179      * </ul>
180      */

181     public CrLf getEol() {
182         // Return copy so that the call must call setEol() to change the state
183
// of fixCRLF
184
return eol.newInstance();
185     }
186
187     /**
188      * Get whether a missing EOL be added to the final line of the stream.
189      *
190      * @return true if a filtered file will always end with an EOL
191      */

192     public boolean getFixlast() {
193         return fixlast;
194     }
195
196     /**
197      * Get whether the stream is to be treated as though it contains Java
198      * source.
199      * <P>
200      * This attribute is only used in assocation with the &quot;<i><b>tab</b></i>&quot;
201      * attribute. Tabs found in Java literals are protected from changes by this
202      * filter.
203      *
204      * @return true if whitespace in Java character and string literals is
205      * ignored.
206      */

207     public boolean getJavafiles() {
208         return javafiles;
209     }
210
211     /**
212      * Return how tab characters are being handled.
213      *
214      * @return values:
215      * <ul>
216      * <li>add: convert sequences of spaces which span a tab stop to
217      * tabs
218      * <li>asis: leave tab and space characters alone
219      * <li>remove: convert tabs to spaces
220      * </ul>
221      */

222     public AddAsisRemove getTab() {
223         // Return copy so that the caller must call setTab() to change the state
224
// of fixCRLF.
225
return tabs.newInstance();
226     }
227
228     /**
229      * Get the tab length to use.
230      *
231      * @return the length of tab in spaces
232      */

233     public int getTablength() {
234         return tabLength;
235     }
236
237     private static String JavaDoc calculateEolString(CrLf eol) {
238         // Calculate the EOL string per the current config
239
if (eol == CrLf.ASIS) {
240             return System.getProperty("line.separator");
241         }
242         if (eol == CrLf.CR || eol == CrLf.MAC) {
243             return "\r";
244         }
245         if (eol == CrLf.CRLF || eol == CrLf.DOS) {
246             return "\r\n";
247         }
248         // assume (eol == CrLf.LF || eol == CrLf.UNIX)
249
return "\n";
250     }
251
252     /**
253      * Wrap the input stream with the internal filters necessary to perform the
254      * configuration settings.
255      */

256     private void initInternalFilters() {
257
258         // If I'm removing an EOF character, do so first so that the other
259
// filters don't see that character.
260
in = (ctrlz == AddAsisRemove.REMOVE) ? new RemoveEofFilter(in) : in;
261
262         // Change all EOL characters to match the calculated EOL string. If
263
// configured to do so, append a trailing EOL so that the file ends on
264
// a EOL.
265
in = new NormalizeEolFilter(in, calculateEolString(eol), getFixlast());
266
267         if (tabs != AddAsisRemove.ASIS) {
268             // If filtering Java source, prevent changes to whitespace in
269
// character and string literals.
270
if (getJavafiles()) {
271                 in = new MaskJavaTabLiteralsFilter(in);
272             }
273             // Add/Remove tabs
274
in = (tabs == AddAsisRemove.ADD) ? (Reader JavaDoc) new AddTabFilter(in, getTablength())
275                     : (Reader JavaDoc) new RemoveTabFilter(in, getTablength());
276         }
277         // Add missing EOF character
278
in = (ctrlz == AddAsisRemove.ADD) ? new AddEofFilter(in) : in;
279         initialized = true;
280     }
281
282     /**
283      * Return the next character in the filtered stream.
284      *
285      * @return the next character in the resulting stream, or -1 if the end of
286      * the resulting stream has been reached.
287      *
288      * @exception IOException
289      * if the underlying stream throws an IOException during
290      * reading.
291      */

292     public synchronized int read() throws IOException JavaDoc {
293         if (!initialized) {
294             initInternalFilters();
295         }
296         return in.read();
297     }
298
299     /**
300      * Specify how DOS EOF (control-z) characters are to be handled.
301      *
302      * @param attr
303      * valid values:
304      * <ul>
305      * <li>add: ensure that there is an eof at the end of the file
306      * <li>asis: leave eof characters alone
307      * <li>remove: remove any eof character found at the end
308      * </ul>
309      */

310     public void setEof(AddAsisRemove attr) {
311         ctrlz = attr.resolve();
312     }
313
314     /**
315      * Specify how end of line (EOL) characters are to be handled.
316      *
317      * @param attr
318      * valid values:
319      * <ul>
320      * <li>asis: convert line endings to your O/S convention
321      * <li>cr: convert line endings to CR
322      * <li>lf: convert line endings to LF
323      * <li>crlf: convert line endings to CRLF
324      * </ul>
325      */

326     public void setEol(CrLf attr) {
327         eol = attr.resolve();
328     }
329
330     /**
331      * Specify whether a missing EOL will be added to the final line of input.
332      *
333      * @param fixlast
334      * if true a missing EOL will be appended.
335      */

336     public void setFixlast(boolean fixlast) {
337         this.fixlast = fixlast;
338     }
339
340     /**
341      * Indicate whether this stream contains Java source.
342      *
343      * This attribute is only used in assocation with the &quot;<i><b>tab</b></i>&quot;
344      * attribute.
345      *
346      * @param javafiles
347      * set to true to prevent this filter from changing tabs found in
348      * Java literals.
349      */

350     public void setJavafiles(boolean javafiles) {
351         this.javafiles = javafiles;
352     }
353
354     /**
355      * Specify how tab characters are to be handled.
356      *
357      * @param attr
358      * valid values:
359      * <ul>
360      * <li>add: convert sequences of spaces which span a tab stop to
361      * tabs
362      * <li>asis: leave tab and space characters alone
363      * <li>remove: convert tabs to spaces
364      * </ul>
365      */

366     public void setTab(AddAsisRemove attr) {
367         tabs = attr.resolve();
368     }
369
370     /**
371      * Specify tab length in characters.
372      *
373      * @param tabLength
374      * specify the length of tab in spaces. Valid values are between
375      * 2 and 80 inclusive. The default for this parameter is 8.
376      * @throws IOException on error.
377      */

378     public void setTablength(int tabLength) throws IOException JavaDoc {
379         if (tabLength < 2 || tabLength > 80) {
380             throw new IOException JavaDoc("tablength must be between 2 and 80");
381         }
382         this.tabLength = tabLength;
383     }
384
385     /**
386      * This filter reader redirects all read I/O methods through its own read()
387      * method.
388      *
389      * <P>
390      * The input stream is already buffered by the copy task so this doesn't
391      * significantly impact performance while it makes writing the individual
392      * fix filters much easier.
393      * </P>
394      */

395     private static class SimpleFilterReader extends Reader JavaDoc {
396         private Reader JavaDoc in;
397
398         private int[] preempt = new int[16];
399
400         private int preemptIndex = 0;
401
402         public SimpleFilterReader(Reader JavaDoc in) {
403             this.in = in;
404         }
405
406         public void push(char c) {
407             push((int) c);
408         }
409
410         public void push(int c) {
411             try {
412                 preempt[preemptIndex++] = c;
413             } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
414                 int[] p2 = new int[preempt.length * 2];
415                 System.arraycopy(preempt, 0, p2, 0, preempt.length);
416                 preempt = p2;
417                 push(c);
418             }
419         }
420
421         public void push(char[] cs, int start, int length) {
422             for (int i = start + length - 1; i >= start;) {
423                 push(cs[i--]);
424             }
425         }
426
427         public void push(char[] cs) {
428             push(cs, 0, cs.length);
429         }
430
431         public void push(String JavaDoc s) {
432             push(s.toCharArray());
433         }
434
435         /**
436          * Does this filter want to block edits on the last character returned
437          * by read()?
438          */

439         public boolean editsBlocked() {
440             return in instanceof SimpleFilterReader && ((SimpleFilterReader) in).editsBlocked();
441         }
442
443         public int read() throws java.io.IOException JavaDoc {
444             return preemptIndex > 0 ? preempt[--preemptIndex] : in.read();
445         }
446
447         public void close() throws java.io.IOException JavaDoc {
448             in.close();
449         }
450
451         public void reset() throws IOException JavaDoc {
452             in.reset();
453         }
454
455         public boolean markSupported() {
456             return in.markSupported();
457         }
458
459         public boolean ready() throws java.io.IOException JavaDoc {
460             return in.ready();
461         }
462
463         public void mark(int i) throws java.io.IOException JavaDoc {
464             in.mark(i);
465         }
466
467         public long skip(long i) throws java.io.IOException JavaDoc {
468             return in.skip(i);
469         }
470
471         public int read(char[] buf) throws java.io.IOException JavaDoc {
472             return read(buf, 0, buf.length);
473         }
474
475         public int read(char[] buf, int start, int length) throws java.io.IOException JavaDoc {
476             int count = 0;
477             int c = 0;
478
479             while (length-- > 0 && (c = this.read()) != -1) {
480                 buf[start++] = (char) c;
481                 count++;
482             }
483             // if at EOF with no characters in the buffer, return EOF
484
return (count == 0 && c == -1) ? -1 : count;
485         }
486     }
487
488     private static class MaskJavaTabLiteralsFilter extends SimpleFilterReader {
489         private boolean editsBlocked = false;
490
491         private static final int JAVA = 1;
492
493         private static final int IN_CHAR_CONST = 2;
494
495         private static final int IN_STR_CONST = 3;
496
497         private static final int IN_SINGLE_COMMENT = 4;
498
499         private static final int IN_MULTI_COMMENT = 5;
500
501         private static final int TRANS_TO_COMMENT = 6;
502
503         private static final int TRANS_FROM_MULTI = 8;
504
505         private int state;
506
507         public MaskJavaTabLiteralsFilter(Reader JavaDoc in) {
508             super(in);
509             state = JAVA;
510         }
511
512         public boolean editsBlocked() {
513             return editsBlocked || super.editsBlocked();
514         }
515
516         public int read() throws IOException JavaDoc {
517             int thisChar = super.read();
518             // Mask, block from being edited, all characters in constants.
519
editsBlocked = (state == IN_CHAR_CONST || state == IN_STR_CONST);
520
521             switch (state) {
522             case JAVA:
523                 // The current character is always emitted.
524
switch (thisChar) {
525                 case '\'':
526                     state = IN_CHAR_CONST;
527                     break;
528                 case '"':
529                     state = IN_STR_CONST;
530                     break;
531                 case '/':
532                     state = TRANS_TO_COMMENT;
533                     break;
534                 default:
535                     // Fall tru
536
}
537                 break;
538             case IN_CHAR_CONST:
539                 switch (thisChar) {
540                 case '\'':
541                     state = JAVA;
542                     break;
543                 default:
544                     // Fall tru
545
}
546                 break;
547             case IN_STR_CONST:
548                 switch (thisChar) {
549                 case '"':
550                     state = JAVA;
551                     break;
552                 default:
553                     // Fall tru
554
}
555                 break;
556             case IN_SINGLE_COMMENT:
557                 // The current character is always emitted.
558
switch (thisChar) {
559                 case '\n':
560                 case '\r': // EOL
561
state = JAVA;
562                     break;
563                 default:
564                     // Fall tru
565
}
566                 break;
567             case IN_MULTI_COMMENT:
568                 // The current character is always emitted.
569
switch (thisChar) {
570                 case '*':
571                     state = TRANS_FROM_MULTI;
572                     break;
573                 default:
574                     // Fall tru
575
}
576                 break;
577             case TRANS_TO_COMMENT:
578                 // The current character is always emitted.
579
switch (thisChar) {
580                 case '*':
581                     state = IN_MULTI_COMMENT;
582                     break;
583                 case '/':
584                     state = IN_SINGLE_COMMENT;
585                     break;
586                 case '\'':
587                     state = IN_CHAR_CONST;
588                     break;
589                 case '"':
590                     state = IN_STR_CONST;
591                     break;
592                 default:
593                     state = JAVA;
594                 }
595                 break;
596             case TRANS_FROM_MULTI:
597                 // The current character is always emitted.
598
switch (thisChar) {
599                 case '/':
600                     state = JAVA;
601                     break;
602                 default:
603                     // Fall tru
604
}
605                 break;
606             default:
607                 // Fall tru
608
}
609             return thisChar;
610         }
611     }
612
613     private static class NormalizeEolFilter extends SimpleFilterReader {
614         private boolean previousWasEOL;
615
616         private boolean fixLast;
617
618         private int normalizedEOL = 0;
619
620         private char[] eol = null;
621
622         public NormalizeEolFilter(Reader JavaDoc in, String JavaDoc eolString, boolean fixLast) {
623             super(in);
624             eol = eolString.toCharArray();
625             this.fixLast = fixLast;
626         }
627
628         public int read() throws IOException JavaDoc {
629             int thisChar = super.read();
630
631             if (normalizedEOL == 0) {
632                 int numEOL = 0;
633                 boolean atEnd = false;
634                 switch (thisChar) {
635                 case CTRLZ:
636                     int c = super.read();
637                     if (c == -1) {
638                         atEnd = true;
639                         if (fixLast && !previousWasEOL) {
640                             numEOL = 1;
641                             push(thisChar);
642                         }
643                     } else {
644                         push(c);
645                     }
646                     break;
647                 case -1:
648                     atEnd = true;
649                     if (fixLast && !previousWasEOL) {
650                         numEOL = 1;
651                     }
652                     break;
653                 case '\n':
654                     // EOL was "\n"
655
numEOL = 1;
656                     break;
657                 case '\r':
658                     numEOL = 1;
659                     int c1 = super.read();
660                     int c2 = super.read();
661
662                     if (c1 == '\r' && c2 == '\n') {
663                         // EOL was "\r\r\n"
664
} else if (c1 == '\r') {
665                         // EOL was "\r\r" - handle as two consecutive "\r" and
666
// "\r"
667
numEOL = 2;
668                         push(c2);
669                     } else if (c1 == '\n') {
670                         // EOL was "\r\n"
671
push(c2);
672                     } else {
673                         // EOL was "\r"
674
push(c2);
675                         push(c1);
676                     }
677                 default:
678                     // Fall tru
679
}
680                 if (numEOL > 0) {
681                     while (numEOL-- > 0) {
682                         push(eol);
683                         normalizedEOL += eol.length;
684                     }
685                     previousWasEOL = true;
686                     thisChar = read();
687                 } else if (!atEnd) {
688                     previousWasEOL = false;
689                 }
690             } else {
691                 normalizedEOL--;
692             }
693             return thisChar;
694         }
695     }
696
697     private static class AddEofFilter extends SimpleFilterReader {
698         private int lastChar = -1;
699
700         public AddEofFilter(Reader JavaDoc in) {
701             super(in);
702         }
703
704         public int read() throws IOException JavaDoc {
705             int thisChar = super.read();
706
707             // if source is EOF but last character was NOT ctrl-z, return ctrl-z
708
if (thisChar == -1) {
709                 if (lastChar != CTRLZ) {
710                     lastChar = CTRLZ;
711                     return lastChar;
712                 }
713             } else {
714                 lastChar = thisChar;
715             }
716             return thisChar;
717         }
718     }
719
720     private static class RemoveEofFilter extends SimpleFilterReader {
721         private int lookAhead = -1;
722
723         public RemoveEofFilter(Reader JavaDoc in) {
724             super(in);
725
726             try {
727                 lookAhead = in.read();
728             } catch (IOException JavaDoc e) {
729                 lookAhead = -1;
730             }
731         }
732
733         public int read() throws IOException JavaDoc {
734             int lookAhead2 = super.read();
735
736             // If source at EOF and lookAhead is ctrl-z, return EOF (NOT ctrl-z)
737
if (lookAhead2 == -1 && lookAhead == CTRLZ) {
738                 return -1;
739             }
740             // Return current look-ahead
741
int i = lookAhead;
742             lookAhead = lookAhead2;
743             return i;
744         }
745     }
746
747     private static class AddTabFilter extends SimpleFilterReader {
748         private int columnNumber = 0;
749
750         private int tabLength = 0;
751
752         public AddTabFilter(Reader JavaDoc in, int tabLength) {
753             super(in);
754             this.tabLength = tabLength;
755         }
756
757         public int read() throws IOException JavaDoc {
758             int c = super.read();
759
760             switch (c) {
761             case '\r':
762             case '\n':
763                 columnNumber = 0;
764                 break;
765             case ' ':
766                 columnNumber++;
767                 if (!editsBlocked()) {
768                     int colNextTab = ((columnNumber + tabLength - 1) / tabLength) * tabLength;
769                     int countSpaces = 1;
770                     int numTabs = 0;
771
772                     scanWhitespace: while ((c = super.read()) != -1) {
773                         switch (c) {
774                         case ' ':
775                             if (++columnNumber == colNextTab) {
776                                 numTabs++;
777                                 countSpaces = 0;
778                                 colNextTab += tabLength;
779                             } else {
780                                 countSpaces++;
781                             }
782                             break;
783                         case '\t':
784                             columnNumber = colNextTab;
785                             numTabs++;
786                             countSpaces = 0;
787                             colNextTab += tabLength;
788                             break;
789                         default:
790                             push(c);
791                             break scanWhitespace;
792                         }
793                     }
794                     while (countSpaces-- > 0) {
795                         push(' ');
796                         columnNumber--;
797                     }
798                     while (numTabs-- > 0) {
799                         push('\t');
800                         columnNumber -= tabLength;
801                     }
802                     c = super.read();
803                     switch (c) {
804                     case ' ':
805                         columnNumber++;
806                         break;
807                     case '\t':
808                         columnNumber += tabLength;
809                         break;
810                     default:
811                         // Fall tru
812
}
813                 }
814                 break;
815             case '\t':
816                 columnNumber = ((columnNumber + tabLength - 1) / tabLength) * tabLength;
817                 break;
818             default:
819                 columnNumber++;
820             }
821             return c;
822         }
823     }
824
825     private static class RemoveTabFilter extends SimpleFilterReader {
826         private int columnNumber = 0;
827
828         private int tabLength = 0;
829
830         public RemoveTabFilter(Reader JavaDoc in, int tabLength) {
831             super(in);
832
833             this.tabLength = tabLength;
834         }
835
836         public int read() throws IOException JavaDoc {
837             int c = super.read();
838
839             switch (c) {
840             case '\r':
841             case '\n':
842                 columnNumber = 0;
843                 break;
844             case '\t':
845                 int width = tabLength - columnNumber % tabLength;
846
847                 if (!editsBlocked()) {
848                     for (; width > 1; width--) {
849                         push(' ');
850                     }
851                     c = ' ';
852                 }
853                 columnNumber += width;
854                 break;
855             default:
856                 columnNumber++;
857             }
858             return c;
859         }
860     }
861
862     /**
863      * Enumerated attribute with the values "asis", "add" and "remove".
864      */

865     public static class AddAsisRemove extends EnumeratedAttribute {
866         private static final AddAsisRemove ASIS = newInstance("asis");
867
868         private static final AddAsisRemove ADD = newInstance("add");
869
870         private static final AddAsisRemove REMOVE = newInstance("remove");
871
872         /** {@inheritDoc}. */
873         public String JavaDoc[] getValues() {
874             return new String JavaDoc[] {"add", "asis", "remove"};
875         }
876
877         /**
878          * Equality depending in the index.
879          * @param other the object to test equality against.
880          * @return true if the object has the same index as this.
881          */

882         public boolean equals(Object JavaDoc other) {
883             return other instanceof AddAsisRemove
884                     && getIndex() == ((AddAsisRemove) other).getIndex();
885         }
886
887         /**
888          * Hashcode depending on the index.
889          * @return the index as the hashcode.
890          */

891         public int hashCode() {
892             return getIndex();
893         }
894
895         AddAsisRemove resolve() throws IllegalStateException JavaDoc {
896             if (this.equals(ASIS)) {
897                 return ASIS;
898             }
899             if (this.equals(ADD)) {
900                 return ADD;
901             }
902             if (this.equals(REMOVE)) {
903                 return REMOVE;
904             }
905             throw new IllegalStateException JavaDoc("No replacement for " + this);
906         }
907
908         // Works like clone() but doesn't show up in the Javadocs
909
private AddAsisRemove newInstance() {
910             return newInstance(getValue());
911         }
912
913         /**
914          * Create an instance of this enumerated value based on the string value.
915          * @param value the value to use.
916          * @return an enumerated instance.
917          */

918         public static AddAsisRemove newInstance(String JavaDoc value) {
919             AddAsisRemove a = new AddAsisRemove();
920             a.setValue(value);
921             return a;
922         }
923     }
924
925     /**
926      * Enumerated attribute with the values "asis", "cr", "lf" and "crlf".
927      */

928     public static class CrLf extends EnumeratedAttribute {
929         private static final CrLf ASIS = newInstance("asis");
930
931         private static final CrLf CR = newInstance("cr");
932
933         private static final CrLf CRLF = newInstance("crlf");
934
935         private static final CrLf DOS = newInstance("dos");
936
937         private static final CrLf LF = newInstance("lf");
938
939         private static final CrLf MAC = newInstance("mac");
940
941         private static final CrLf UNIX = newInstance("unix");
942
943         /**
944          * @see EnumeratedAttribute#getValues
945          */

946         /** {@inheritDoc}. */
947         public String JavaDoc[] getValues() {
948             return new String JavaDoc[] {"asis", "cr", "lf", "crlf", "mac", "unix", "dos"};
949         }
950
951         /**
952          * Equality depending in the index.
953          * @param other the object to test equality against.
954          * @return true if the object has the same index as this.
955          */

956         public boolean equals(Object JavaDoc other) {
957             return other instanceof CrLf && getIndex() == ((CrLf) other).getIndex();
958         }
959
960         /**
961          * Hashcode depending on the index.
962          * @return the index as the hashcode.
963          */

964         public int hashCode() {
965             return getIndex();
966         }
967
968         CrLf resolve() {
969             if (this.equals(ASIS)) {
970                 return ASIS;
971             }
972             if (this.equals(CR) || this.equals(MAC)) {
973                 return CR;
974             }
975             if (this.equals(CRLF) || this.equals(DOS)) {
976                 return CRLF;
977             }
978             if (this.equals(LF) || this.equals(UNIX)) {
979                 return LF;
980             }
981             throw new IllegalStateException JavaDoc("No replacement for " + this);
982         }
983
984         // Works like clone() but doesn't show up in the Javadocs
985
private CrLf newInstance() {
986             return newInstance(getValue());
987         }
988
989         /**
990          * Create an instance of this enumerated value based on the string value.
991          * @param value the value to use.
992          * @return an enumerated instance.
993          */

994         public static CrLf newInstance(String JavaDoc value) {
995             CrLf c = new CrLf();
996             c.setValue(value);
997             return c;
998         }
999     }
1000}
1001
Popular Tags