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 }