1 /*
2 * The contents of this file are subject to the terms of the Common Development and
3 * Distribution License (the License). You may not use this file except in compliance with the
4 * License.
5 *
6 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
7 * specific language governing permission and limitations under the License.
8 *
9 * When distributing Covered Software, include this CDDL Header Notice in each file and include
10 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
11 * Header, with the fields enclosed by brackets [] replaced by your own identifying
12 * information: "Portions Copyrighted [year] [name of copyright owner]".
13 *
14 * Copyright 2011-2015 ForgeRock AS.
15 */
16 package org.forgerock.json;
17
18 import java.io.Serializable;
19 import java.util.AbstractSet;
20 import java.util.Iterator;
21 import java.util.NoSuchElementException;
22 import java.util.Set;
23
24 /**
25 * Exposes a range of integer values as a set. Used to expose a set of values without
26 * requiring the allocation of storage for all values.
27 */
28 class RangeSet extends AbstractSet<String> implements Set<String>, Cloneable, Serializable {
29
30 /** Establishes serialized object compatibility. */
31 static final long serialVersionUID = 1L;
32
33 /** The start of the range, inclusive. */
34 private int start;
35
36 /** The end of the range, inclusive. */
37 private int end;
38
39 /**
40 * Constructs a range set for the specified range.
41 *
42 * @param start the start of the range, inclusive.
43 * @param end the end of the range, inclusive.
44 */
45 public RangeSet(int start, int end) {
46 this.start = start;
47 this.end = end;
48 if (start > end) {
49 throw new IllegalArgumentException("start must be <= end");
50 }
51 }
52
53 /**
54 * Returns an iterator over the elements in this set.
55 */
56 @Override
57 public Iterator<String> iterator() {
58 return new Iterator<String>() {
59 int cursor = start;
60 @Override
61 public boolean hasNext() {
62 return cursor <= end;
63 }
64 @Override
65 public String next() {
66 if (cursor > end) {
67 throw new NoSuchElementException();
68 }
69 return Integer.toString(cursor++);
70 }
71 @Override
72 public void remove() {
73 throw new UnsupportedOperationException();
74 }
75 };
76 }
77
78 /**
79 * Returns the number of elements in this set.
80 */
81 @Override
82 public int size() {
83 return end - start + 1;
84 }
85
86 /**
87 * Returns {@code false} unconditionally. Range sets always have at least one element.
88 */
89 @Override
90 public boolean isEmpty() {
91 return false;
92 }
93
94 /**
95 * Returns {@code true} if this set contains the specified element.
96 */
97 @Override
98 public boolean contains(Object o) {
99 boolean result = false;
100 if (o != null && o instanceof String) {
101 try {
102 int n = Integer.parseInt((String) o);
103 result = (n >= start && n <= end);
104 } catch (NumberFormatException nfe) {
105 // result remains false
106 }
107 }
108 return result;
109 }
110
111 /**
112 * Unconditionally throws {@link UnsupportedOperationException}, as range sets are
113 * immutable.
114 */
115 @Override
116 public boolean add(String e) {
117 throw new UnsupportedOperationException();
118 }
119
120 /**
121 * Unconditionally throws {@link UnsupportedOperationException}, as range sets are
122 * immutable.
123 */
124 @Override
125 public boolean remove(Object o) {
126 throw new UnsupportedOperationException();
127 }
128
129 /**
130 * Unconditionally throws {@link UnsupportedOperationException}, as range sets are
131 * immutable.
132 */
133 @Override
134 public void clear() {
135 throw new UnsupportedOperationException();
136 }
137 }