1:
37:
38: package ;
39:
40: import ;
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46:
47:
50: public abstract class SetOfIntegerSyntax
51: implements Cloneable, Serializable
52: {
53: private static final long serialVersionUID = 3666874174847632203L;
54:
55: private int[][] members;
56:
57: private static int[][] normalize(int[][] values, int size)
58: {
59:
60:
61: Arrays.sort(values, 0, size, new Comparator()
62: {
63: public int compare(Object o1, Object o2)
64: {
65: int[] v1 = (int[]) o1;
66: int[] v2 = (int[]) o2;
67: if (v1[0] == v2[0])
68: return v1[1] - v2[1];
69: return v1[0] - v2[0];
70: }
71: });
72:
73:
74: int outIndex = 0;
75: for (int i = 0; i < size; ++i)
76: {
77:
78:
79: int save = i;
80: while (i + 1 < size && values[i + 1][0] <= values[i][1] + 1)
81: {
82: values[i][1] = Math.max(values[i][1], values[i + 1][1]);
83: ++i;
84: }
85: values[outIndex++] = values[save];
86: }
87:
88: int[][] result = new int[outIndex][];
89: System.arraycopy(values, 0, result, 0, outIndex);
90:
91: return result;
92: }
93:
94:
101: protected SetOfIntegerSyntax(int member)
102: {
103: if (member < 0)
104: throw new IllegalArgumentException("member may not be less than 0");
105:
106: this.members = new int[][]{{member, member}};
107: }
108:
109:
117: protected SetOfIntegerSyntax(int[][] members)
118: {
119: int[][] newMembers;
120: int outIndex = 0;
121: if (members == null)
122: newMembers = new int[0][];
123: else
124: {
125: newMembers = new int[members.length][];
126: for (int index = 0; index < members.length; index++)
127: {
128: int lower;
129: int upper;
130:
131: if (members[index].length == 1)
132: {
133: lower = members[index][0];
134: upper = members[index][0];
135: }
136: else if (members[index].length == 2)
137: {
138: lower = members[index][0];
139: upper = members[index][1];
140: }
141: else
142: throw new IllegalArgumentException("invalid member element");
143:
144:
145: if (lower <= upper && lower < 0)
146: throw new IllegalArgumentException("invalid member element");
147:
148: if (lower <= upper)
149: {
150: int[] range = new int[2];
151: range[0] = lower;
152: range[1] = upper;
153: newMembers[outIndex++] = range;
154: }
155: }
156: }
157:
158: this.members = normalize(newMembers, outIndex);
159: }
160:
161: private boolean skipWhitespace(StringCharacterIterator i)
162: {
163: while (Character.isWhitespace(i.current()))
164: i.next();
165: return i.current() == CharacterIterator.DONE;
166: }
167:
168: private boolean skipNumber(StringCharacterIterator i)
169: {
170: boolean readAny = false;
171: while (Character.isDigit(i.current()))
172: {
173: readAny = true;
174: i.next();
175: }
176: return readAny;
177: }
178:
179: protected SetOfIntegerSyntax(String s)
180: {
181: ArrayList vals = new ArrayList();
182:
183: StringCharacterIterator it = new StringCharacterIterator(s);
184:
185: while (true)
186: {
187:
188: if (skipWhitespace(it))
189: break;
190:
191:
192: int index = it.getIndex();
193: if (! skipNumber(it))
194: throw new IllegalArgumentException();
195: int[] item = new int[2];
196: item[0] = Integer.parseInt(s.substring(index, it.getIndex()));
197:
198: if (! skipWhitespace(it))
199: {
200: char c = it.current();
201: if (c == ':' || c == '-')
202: {
203: it.next();
204: if (skipWhitespace(it))
205: throw new IllegalArgumentException();
206: index = it.getIndex();
207: if (! skipNumber(it))
208: throw new IllegalArgumentException();
209: item[1] = Integer.parseInt(s.substring(index, it.getIndex()));
210: }
211: else
212: item[1] = item[0];
213: }
214: else
215: item[1] = item[0];
216:
217: if (item[0] <= item[1])
218: vals.add(item);
219:
220: if (skipWhitespace(it))
221: break;
222: if (it.current() != ',')
223: throw new IllegalArgumentException();
224: it.next();
225: }
226:
227: members = normalize((int[][]) vals.toArray(new int[0][]), vals.size());
228: }
229:
230:
239: protected SetOfIntegerSyntax(int lowerBound, int upperBound)
240: {
241:
242: if (lowerBound <= upperBound
243: && lowerBound < 0)
244: throw new IllegalArgumentException();
245:
246: members = (lowerBound <= upperBound ? new int[][]{{lowerBound, upperBound}}
247: : new int[0][]);
248: }
249:
250:
257: public boolean contains(int value)
258: {
259:
260: for (int index = 0; index < members.length; index++)
261: {
262: if (value < members[index][0])
263: return false;
264: else if (value <= members[index][1])
265: return true;
266: }
267:
268: return false;
269: }
270:
271:
278: public boolean contains(IntegerSyntax value)
279: {
280: return contains(value.getValue());
281: }
282:
283:
290: public boolean equals(Object obj)
291: {
292: if (! (obj instanceof SetOfIntegerSyntax))
293: return false;
294: SetOfIntegerSyntax other = (SetOfIntegerSyntax) obj;
295: if (other.members.length != members.length)
296: return false;
297: for (int i = 0; i < members.length; ++i)
298: {
299: if (members[i][0] != other.members[i][0]
300: || members[i][1] != other.members[i][1])
301: return false;
302: }
303: return true;
304: }
305:
306:
311: public int[][] getMembers()
312: {
313: return (int[][]) members.clone();
314: }
315:
316:
321: public int hashCode()
322: {
323: int result = 0;
324: for (int i = 0; i < members.length; ++i)
325: result += members[i][0] + members[i][1];
326: return result;
327: }
328:
329:
336: public int next(int x)
337: {
338: for (int i = 0; i < members.length; ++i)
339: {
340: if (x >= members[i][1])
341: continue;
342: if (x < members[i][0])
343: return members[i][0];
344:
345: return x + 1;
346: }
347: return -1;
348: }
349:
350:
355: public String toString()
356: {
357: StringBuilder sb = new StringBuilder();
358: for (int i = 0; i < members.length; ++i)
359: {
360: if (i > 0)
361: sb.append(',');
362: sb.append(members[i][0]);
363: if (members[i][0] != members[i][1])
364: {
365: sb.append('-');
366: sb.append(members[i][1]);
367: }
368: }
369: return sb.toString();
370: }
371: }