View Javadoc
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 }