001: /*
002: * Copyright 2003-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.collections.map;
017:
018: import java.lang.reflect.Array;
019: import java.util.Collection;
020: import java.util.Iterator;
021: import java.util.Map;
022: import java.util.Set;
023:
024: import org.apache.commons.collections.Unmodifiable;
025: import org.apache.commons.collections.iterators.AbstractIteratorDecorator;
026: import org.apache.commons.collections.keyvalue.AbstractMapEntryDecorator;
027: import org.apache.commons.collections.set.AbstractSetDecorator;
028:
029: /**
030: * Decorates a map entry <code>Set</code> to ensure it can't be altered.
031: *
032: * @since Commons Collections 3.0
033: * @version $Revision: 155406 $ $Date: 2005-02-26 12:55:26 +0000 (Sat, 26 Feb 2005) $
034: *
035: * @author Stephen Colebourne
036: */
037: public final class UnmodifiableEntrySet extends AbstractSetDecorator
038: implements Unmodifiable {
039:
040: /**
041: * Factory method to create an unmodifiable set of Map Entry objects.
042: *
043: * @param set the set to decorate, must not be null
044: * @throws IllegalArgumentException if set is null
045: */
046: public static Set decorate(Set set) {
047: if (set instanceof Unmodifiable) {
048: return set;
049: }
050: return new UnmodifiableEntrySet(set);
051: }
052:
053: //-----------------------------------------------------------------------
054: /**
055: * Constructor that wraps (not copies).
056: *
057: * @param set the set to decorate, must not be null
058: * @throws IllegalArgumentException if set is null
059: */
060: private UnmodifiableEntrySet(Set set) {
061: super (set);
062: }
063:
064: //-----------------------------------------------------------------------
065: public boolean add(Object object) {
066: throw new UnsupportedOperationException();
067: }
068:
069: public boolean addAll(Collection coll) {
070: throw new UnsupportedOperationException();
071: }
072:
073: public void clear() {
074: throw new UnsupportedOperationException();
075: }
076:
077: public boolean remove(Object object) {
078: throw new UnsupportedOperationException();
079: }
080:
081: public boolean removeAll(Collection coll) {
082: throw new UnsupportedOperationException();
083: }
084:
085: public boolean retainAll(Collection coll) {
086: throw new UnsupportedOperationException();
087: }
088:
089: //-----------------------------------------------------------------------
090: public Iterator iterator() {
091: return new UnmodifiableEntrySetIterator(collection.iterator());
092: }
093:
094: public Object[] toArray() {
095: Object[] array = collection.toArray();
096: for (int i = 0; i < array.length; i++) {
097: array[i] = new UnmodifiableEntry((Map.Entry) array[i]);
098: }
099: return array;
100: }
101:
102: public Object[] toArray(Object array[]) {
103: Object[] result = array;
104: if (array.length > 0) {
105: // we must create a new array to handle multi-threaded situations
106: // where another thread could access data before we decorate it
107: result = (Object[]) Array.newInstance(array.getClass()
108: .getComponentType(), 0);
109: }
110: result = collection.toArray(result);
111: for (int i = 0; i < result.length; i++) {
112: result[i] = new UnmodifiableEntry((Map.Entry) result[i]);
113: }
114:
115: // check to see if result should be returned straight
116: if (result.length > array.length) {
117: return result;
118: }
119:
120: // copy back into input array to fulfil the method contract
121: System.arraycopy(result, 0, array, 0, result.length);
122: if (array.length > result.length) {
123: array[result.length] = null;
124: }
125: return array;
126: }
127:
128: //-----------------------------------------------------------------------
129: /**
130: * Implementation of an entry set iterator.
131: */
132: final static class UnmodifiableEntrySetIterator extends
133: AbstractIteratorDecorator {
134:
135: protected UnmodifiableEntrySetIterator(Iterator iterator) {
136: super (iterator);
137: }
138:
139: public Object next() {
140: Map.Entry entry = (Map.Entry) iterator.next();
141: return new UnmodifiableEntry(entry);
142: }
143:
144: public void remove() {
145: throw new UnsupportedOperationException();
146: }
147: }
148:
149: //-----------------------------------------------------------------------
150: /**
151: * Implementation of a map entry that is unmodifiable.
152: */
153: final static class UnmodifiableEntry extends
154: AbstractMapEntryDecorator {
155:
156: protected UnmodifiableEntry(Map.Entry entry) {
157: super (entry);
158: }
159:
160: public Object setValue(Object obj) {
161: throw new UnsupportedOperationException();
162: }
163: }
164:
165: }
|