001 /*
002 * Licensed under the Apache License, Version 2.0 (the "License");
003 * you may not use this file except in compliance with the License.
004 * You may obtain a copy of the License at
005 *
006 * http://www.apache.org/licenses/LICENSE-2.0
007 *
008 * Unless required by applicable law or agreed to in writing, software
009 * distributed under the License is distributed on an "AS IS" BASIS,
010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011 * See the License for the specific language governing permissions and
012 * limitations under the License.
013 */
014 package org.apache.commons.classscan.util;
015
016 import java.lang.reflect.Array;
017 import java.util.Arrays;
018 import java.util.Collection;
019 import java.util.Iterator;
020 import java.util.NoSuchElementException;
021 import java.util.Set;
022
023 /**
024 * Set of immutable instances.
025 *
026 * @param <V>
027 * The contained type
028 */
029 public class ReadOnlySet<V> implements Set<V> {
030
031 protected V[] values;
032
033 public ReadOnlySet(V[] values) {
034 if(values==null) {
035 throw new UnsupportedOperationException();
036 }
037 else {
038 this.values = values;
039 }
040 }
041
042 /**
043 * Subclasses may use this constructor to delay initialization of values.
044 * The derived class must call setValues before general use.
045 */
046 protected ReadOnlySet() {
047 }
048
049 /**
050 * @param values
051 * The array to view
052 */
053 protected void setValues(V[] values) {
054 this.values = values;
055 }
056
057 @Override
058 public boolean contains(Object o) {
059 for (V t : values) {
060 if (t.equals(o)) {
061 return true;
062 }
063 }
064 return false;
065 }
066
067 @Override
068 public boolean containsAll(Collection<?> collection) {
069 for (Object single : collection) {
070 if (!contains(single)) {
071 return false;
072 }
073 }
074 return true;
075 }
076
077 @Override
078 public boolean isEmpty() {
079 return values.length == 0;
080 }
081
082 @Override
083 public Iterator<V> iterator() {
084 return new Iterator<V>() {
085 int i;
086
087 @Override
088 public boolean hasNext() {
089 return i < values.length;
090 }
091
092 @Override
093 public V next() {
094 if (i == values.length) {
095 throw new NoSuchElementException("Reading past end of iterator");
096 }
097 return values[i++];
098 }
099
100 @Override
101 public void remove() {
102 throw new UnsupportedOperationException("Read only iterator");
103 }
104 };
105 }
106
107 @Override
108 public int size() {
109 return values.length;
110 }
111
112 @Override
113 public Object[] toArray() {
114 return values.clone();
115 }
116
117 @Override
118 public <T> T[] toArray(T[] a) {
119 int numberToNull = a.length - values.length;
120 if (numberToNull >= 0) {
121 System.arraycopy(values, 0, a, 0, values.length);
122 if (numberToNull > 0) {
123 Arrays.fill(a, values.length, a.length, null);
124 }
125 return a;
126 }
127
128 @SuppressWarnings("unchecked")
129 T[] rv = (T[]) Array.newInstance(a.getClass().getComponentType(), values.length);
130 System.arraycopy(values, 0, rv, 0, values.length);
131 return rv;
132 }
133
134 @Override
135 final public boolean add(V e) {
136 throw new UnsupportedOperationException("Set is readonly");
137 }
138
139 @Override
140 final public boolean addAll(Collection<? extends V> c) {
141 throw new UnsupportedOperationException("Set is readonly");
142 }
143
144 @Override
145 final public void clear() {
146 throw new UnsupportedOperationException("Set is readonly");
147 }
148
149 @Override
150 final public boolean remove(Object e) {
151 throw new UnsupportedOperationException("Set is readonly");
152 }
153
154 @Override
155 final public boolean removeAll(Collection<?> c) {
156 throw new UnsupportedOperationException("Set is readonly");
157 }
158
159 @Override
160 final public boolean retainAll(Collection<?> c) {
161 throw new UnsupportedOperationException("Set is readonly");
162 }
163
164 }