1. /*
  2. * Copyright 2003-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.apache.commons.collections.map;
  17. import java.lang.reflect.Array;
  18. import java.util.Collection;
  19. import java.util.Iterator;
  20. import java.util.Map;
  21. import java.util.Set;
  22. import org.apache.commons.collections.Unmodifiable;
  23. import org.apache.commons.collections.iterators.AbstractIteratorDecorator;
  24. import org.apache.commons.collections.keyvalue.AbstractMapEntryDecorator;
  25. import org.apache.commons.collections.set.AbstractSetDecorator;
  26. /**
  27. * Decorates a map entry <code>Set</code> to ensure it can't be altered.
  28. *
  29. * @since Commons Collections 3.0
  30. * @version $Revision: 1.6 $ $Date: 2004/02/18 01:13:19 $
  31. *
  32. * @author Stephen Colebourne
  33. */
  34. public final class UnmodifiableEntrySet
  35. extends AbstractSetDecorator implements Unmodifiable {
  36. /**
  37. * Factory method to create an unmodifiable set of Map Entry objects.
  38. *
  39. * @param set the set to decorate, must not be null
  40. * @throws IllegalArgumentException if set is null
  41. */
  42. public static Set decorate(Set set) {
  43. if (set instanceof Unmodifiable) {
  44. return set;
  45. }
  46. return new UnmodifiableEntrySet(set);
  47. }
  48. //-----------------------------------------------------------------------
  49. /**
  50. * Constructor that wraps (not copies).
  51. *
  52. * @param set the set to decorate, must not be null
  53. * @throws IllegalArgumentException if set is null
  54. */
  55. private UnmodifiableEntrySet(Set set) {
  56. super(set);
  57. }
  58. //-----------------------------------------------------------------------
  59. public boolean add(Object object) {
  60. throw new UnsupportedOperationException();
  61. }
  62. public boolean addAll(Collection coll) {
  63. throw new UnsupportedOperationException();
  64. }
  65. public void clear() {
  66. throw new UnsupportedOperationException();
  67. }
  68. public boolean remove(Object object) {
  69. throw new UnsupportedOperationException();
  70. }
  71. public boolean removeAll(Collection coll) {
  72. throw new UnsupportedOperationException();
  73. }
  74. public boolean retainAll(Collection coll) {
  75. throw new UnsupportedOperationException();
  76. }
  77. //-----------------------------------------------------------------------
  78. public Iterator iterator() {
  79. return new UnmodifiableEntrySetIterator(collection.iterator());
  80. }
  81. public Object[] toArray() {
  82. Object[] array = collection.toArray();
  83. for (int i = 0; i < array.length; i++) {
  84. array[i] = new UnmodifiableEntry((Map.Entry) array[i]);
  85. }
  86. return array;
  87. }
  88. public Object[] toArray(Object array[]) {
  89. Object[] result = array;
  90. if (array.length > 0) {
  91. // we must create a new array to handle multi-threaded situations
  92. // where another thread could access data before we decorate it
  93. result = (Object[]) Array.newInstance(array.getClass().getComponentType(), 0);
  94. }
  95. result = collection.toArray(result);
  96. for (int i = 0; i < result.length; i++) {
  97. result[i] = new UnmodifiableEntry((Map.Entry) result[i]);
  98. }
  99. // check to see if result should be returned straight
  100. if (result.length > array.length) {
  101. return result;
  102. }
  103. // copy back into input array to fulfil the method contract
  104. System.arraycopy(result, 0, array, 0, result.length);
  105. if (array.length > result.length) {
  106. array[result.length] = null;
  107. }
  108. return array;
  109. }
  110. //-----------------------------------------------------------------------
  111. /**
  112. * Implementation of an entry set iterator.
  113. */
  114. final static class UnmodifiableEntrySetIterator extends AbstractIteratorDecorator {
  115. protected UnmodifiableEntrySetIterator(Iterator iterator) {
  116. super(iterator);
  117. }
  118. public Object next() {
  119. Map.Entry entry = (Map.Entry) iterator.next();
  120. return new UnmodifiableEntry(entry);
  121. }
  122. public void remove() {
  123. throw new UnsupportedOperationException();
  124. }
  125. }
  126. //-----------------------------------------------------------------------
  127. /**
  128. * Implementation of a map entry that is unmodifiable.
  129. */
  130. final static class UnmodifiableEntry extends AbstractMapEntryDecorator {
  131. protected UnmodifiableEntry(Map.Entry entry) {
  132. super(entry);
  133. }
  134. public Object setValue(Object obj) {
  135. throw new UnsupportedOperationException();
  136. }
  137. }
  138. }