KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > lowagie > text > pdf > SequenceList


1 /*
2  * Copyright 2004 by Paulo Soares.
3  *
4  * The contents of this file are subject to the Mozilla Public License Version 1.1
5  * (the "License"); you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
7  *
8  * Software distributed under the License is distributed on an "AS IS" basis,
9  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
10  * for the specific language governing rights and limitations under the License.
11  *
12  * The Original Code is 'iText, a free JAVA-PDF library'.
13  *
14  * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
15  * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
16  * All Rights Reserved.
17  * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
18  * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
19  *
20  * Contributor(s): all the names of the contributors are added in the source code
21  * where applicable.
22  *
23  * Alternatively, the contents of this file may be used under the terms of the
24  * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
25  * provisions of LGPL are applicable instead of those above. If you wish to
26  * allow use of your version of this file only under the terms of the LGPL
27  * License and not to allow others to use your version of this file under
28  * the MPL, indicate your decision by deleting the provisions above and
29  * replace them with the notice and other provisions required by the LGPL.
30  * If you do not delete the provisions above, a recipient may use your version
31  * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
32  *
33  * This library is free software; you can redistribute it and/or modify it
34  * under the terms of the MPL as stated above or under the terms of the GNU
35  * Library General Public License as published by the Free Software Foundation;
36  * either version 2 of the License, or any later version.
37  *
38  * This library is distributed in the hope that it will be useful, but WITHOUT
39  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
40  * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
41  * details.
42  *
43  * If you didn't download this code from the following link, you should check if
44  * you aren't using an obsolete version:
45  * http://www.lowagie.com/iText/
46  */

47 package com.lowagie.text.pdf;
48
49 import java.util.LinkedList JavaDoc;
50 import java.util.List JavaDoc;
51 import java.util.ListIterator JavaDoc;
52
53 /**
54  * This class expands a string into a list of numbers. The main use is to select a
55  * range of pages.
56  * <p>
57  * The general systax is:<br>
58  * [!][o][odd][e][even]start-end
59  * <p>
60  * You can have multiple ranges separated by commas ','. The '!' modifier removes the
61  * range from what is already selected. The range changes are incremental, that is,
62  * numbers are added or deleted as the range appears. The start or the end, but not both, can be ommited.
63  */

64 public class SequenceList {
65     protected static final int COMMA = 1;
66     protected static final int MINUS = 2;
67     protected static final int NOT = 3;
68     protected static final int TEXT = 4;
69     protected static final int NUMBER = 5;
70     protected static final int END = 6;
71     protected static final char EOT = '\uffff';
72
73     private static final int FIRST = 0;
74     private static final int DIGIT = 1;
75     private static final int OTHER = 2;
76     private static final int DIGIT2 = 3;
77     private static final String JavaDoc NOT_OTHER = "-,!0123456789";
78
79     protected char text[];
80     protected int ptr;
81     protected int number;
82     protected String JavaDoc other;
83
84     protected int low;
85     protected int high;
86     protected boolean odd;
87     protected boolean even;
88     protected boolean inverse;
89
90     protected SequenceList(String JavaDoc range) {
91         ptr = 0;
92         text = range.toCharArray();
93     }
94     
95     protected char nextChar() {
96         while (true) {
97             if (ptr >= text.length)
98                 return EOT;
99             char c = text[ptr++];
100             if (c > ' ')
101                 return c;
102         }
103     }
104     
105     protected void putBack() {
106         --ptr;
107         if (ptr < 0)
108             ptr = 0;
109     }
110     
111     protected int getType() {
112         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
113         int state = FIRST;
114         while (true) {
115             char c = nextChar();
116             if (c == EOT) {
117                 if (state == DIGIT) {
118                     number = Integer.parseInt(other = buf.toString());
119                     return NUMBER;
120                 }
121                 else if (state == OTHER) {
122                     other = buf.toString().toLowerCase();
123                     return TEXT;
124                 }
125                 return END;
126             }
127             switch (state) {
128                 case FIRST:
129                     switch (c) {
130                         case '!':
131                             return NOT;
132                         case '-':
133                             return MINUS;
134                         case ',':
135                             return COMMA;
136                     }
137                     buf.append(c);
138                     if (c >= '0' && c <= '9')
139                         state = DIGIT;
140                     else
141                         state = OTHER;
142                     break;
143                 case DIGIT:
144                     if (c >= '0' && c <= '9')
145                         buf.append(c);
146                     else {
147                         putBack();
148                         number = Integer.parseInt(other = buf.toString());
149                         return NUMBER;
150                     }
151                     break;
152                 case OTHER:
153                     if (NOT_OTHER.indexOf(c) < 0)
154                         buf.append(c);
155                     else {
156                         putBack();
157                         other = buf.toString().toLowerCase();
158                         return TEXT;
159                     }
160                     break;
161             }
162         }
163     }
164     
165     private void otherProc() {
166         if (other.equals("odd") || other.equals("o")) {
167             odd = true;
168             even = false;
169         }
170         else if (other.equals("even") || other.equals("e")) {
171             odd = false;
172             even = true;
173         }
174     }
175     
176     protected boolean getAttributes() {
177         low = -1;
178         high = -1;
179         odd = even = inverse = false;
180         int state = OTHER;
181         while (true) {
182             int type = getType();
183             if (type == END || type == COMMA) {
184                 if (state == DIGIT)
185                     high = low;
186                 return (type == END);
187             }
188             switch (state) {
189                 case OTHER:
190                     switch (type) {
191                         case NOT:
192                             inverse = true;
193                             break;
194                         case MINUS:
195                             state = DIGIT2;
196                             break;
197                         default:
198                             if (type == NUMBER) {
199                                 low = number;
200                                 state = DIGIT;
201                             }
202                             else
203                                 otherProc();
204                             break;
205                     }
206                     break;
207                 case DIGIT:
208                     switch (type) {
209                         case NOT:
210                             inverse = true;
211                             state = OTHER;
212                             high = low;
213                             break;
214                         case MINUS:
215                             state = DIGIT2;
216                             break;
217                         default:
218                             high = low;
219                             state = OTHER;
220                             otherProc();
221                             break;
222                     }
223                     break;
224                 case DIGIT2:
225                     switch (type) {
226                         case NOT:
227                             inverse = true;
228                             state = OTHER;
229                             break;
230                         case MINUS:
231                             break;
232                         case NUMBER:
233                             high = number;
234                             state = OTHER;
235                             break;
236                         default:
237                             state = OTHER;
238                             otherProc();
239                             break;
240                     }
241                     break;
242             }
243         }
244     }
245     
246     /**
247      * Generates a list of numbers from a string.
248      * @param ranges the comma separated ranges
249      * @param maxNumber the maximum number in the range
250      * @return a list with the numbers as <CODE>Integer</CODE>
251      */

252     public static List JavaDoc expand(String JavaDoc ranges, int maxNumber) {
253         SequenceList parse = new SequenceList(ranges);
254         LinkedList JavaDoc list = new LinkedList JavaDoc();
255         boolean sair = false;
256         while (!sair) {
257             sair = parse.getAttributes();
258             if (parse.low == -1 && parse.high == -1 && !parse.even && !parse.odd)
259                 continue;
260             if (parse.low < 1)
261                 parse.low = 1;
262             if (parse.high < 1 || parse.high > maxNumber)
263                 parse.high = maxNumber;
264             if (parse.low > maxNumber)
265                 parse.low = maxNumber;
266             
267             //System.out.println("low="+parse.low+",high="+parse.high+",odd="+parse.odd+",even="+parse.even+",inverse="+parse.inverse);
268
int inc = 1;
269             if (parse.inverse) {
270                 if (parse.low > parse.high) {
271                     int t = parse.low;
272                     parse.low = parse.high;
273                     parse.high = t;
274                 }
275                 for (ListIterator JavaDoc it = list.listIterator(); it.hasNext();) {
276                     int n = ((Integer JavaDoc)it.next()).intValue();
277                     if (parse.even && (n & 1) == 1)
278                         continue;
279                     if (parse.odd && (n & 1) == 0)
280                         continue;
281                     if (n >= parse.low && n <= parse.high)
282                         it.remove();
283                 }
284             }
285             else {
286                 if (parse.low > parse.high) {
287                     inc = -1;
288                     if (parse.odd || parse.even) {
289                         --inc;
290                         if (parse.even)
291                             parse.low &= ~1;
292                         else
293                             parse.low -= ((parse.low & 1) == 1 ? 0 : 1);
294                     }
295                     for (int k = parse.low; k >= parse.high; k += inc)
296                         list.add(new Integer JavaDoc(k));
297                 }
298                 else {
299                     if (parse.odd || parse.even) {
300                         ++inc;
301                         if (parse.odd)
302                             parse.low |= 1;
303                         else
304                             parse.low += ((parse.low & 1) == 1 ? 1 : 0);
305                     }
306                     for (int k = parse.low; k <= parse.high; k += inc) {
307                         list.add(new Integer JavaDoc(k));
308                     }
309                 }
310             }
311 // for (int k = 0; k < list.size(); ++k)
312
// System.out.print(((Integer)list.get(k)).intValue() + ",");
313
// System.out.println();
314
}
315         return list;
316     }
317 }
Popular Tags