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