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 * https://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 */ 017package org.apache.commons.collections4.multiset; 018 019import java.io.IOException; 020import java.io.ObjectInputStream; 021import java.io.ObjectOutputStream; 022import java.util.Collection; 023import java.util.Iterator; 024import java.util.Set; 025import java.util.function.Predicate; 026 027import org.apache.commons.collections4.MultiSet; 028import org.apache.commons.collections4.SortedMultiSet; 029import org.apache.commons.collections4.Unmodifiable; 030import org.apache.commons.collections4.iterators.UnmodifiableIterator; 031import org.apache.commons.collections4.set.UnmodifiableSet; 032 033/** 034 * Decorates another {@link SortedMultiSet} to ensure it can't be altered. 035 * <p> 036 * Attempts to modify it will result in an UnsupportedOperationException. 037 * </p> 038 * 039 * @param <E> The type held in the multiset 040 * @since 4.6.0 041 */ 042public final class UnmodifiableSortedMultiSet<E> 043 extends AbstractSortedMultiSetDecorator<E> implements Unmodifiable { 044 045 /** Serialization version */ 046 private static final long serialVersionUID = 20260705L; 047 048 /** 049 * Factory method to create an unmodifiable multiset. 050 * <p> 051 * If the multiset passed in is already unmodifiable, it is returned. 052 * </p> 053 * 054 * @param <E> the type of the elements in the multiset 055 * @param multiset The multiset to decorate, may not be null 056 * @return An unmodifiable SortedMultiSet 057 * @throws NullPointerException if multiset is null 058 */ 059 public static <E> SortedMultiSet<E> unmodifiableSortedMultiSet(final SortedMultiSet<? extends E> multiset) { 060 if (multiset instanceof Unmodifiable) { 061 @SuppressWarnings("unchecked") // safe to upcast 062 final SortedMultiSet<E> tmpMultiSet = (SortedMultiSet<E>) multiset; 063 return tmpMultiSet; 064 } 065 return new UnmodifiableSortedMultiSet<>(multiset); 066 } 067 068 /** 069 * Constructor that wraps (not copies). 070 * 071 * @param multiset The multiset to decorate, may not be null 072 * @throws NullPointerException if multiset is null 073 */ 074 @SuppressWarnings("unchecked") // safe to upcast 075 private UnmodifiableSortedMultiSet(final SortedMultiSet<? extends E> multiset) { 076 super((SortedMultiSet<E>) multiset); 077 } 078 079 @Override 080 public boolean add(final E object) { 081 throw new UnsupportedOperationException(); 082 } 083 084 @Override 085 public int add(final E object, final int count) { 086 throw new UnsupportedOperationException(); 087 } 088 089 @Override 090 public boolean addAll(final Collection<? extends E> coll) { 091 throw new UnsupportedOperationException(); 092 } 093 094 @Override 095 public void clear() { 096 throw new UnsupportedOperationException(); 097 } 098 099 @Override 100 public Set<MultiSet.Entry<E>> entrySet() { 101 final Set<MultiSet.Entry<E>> set = decorated().entrySet(); 102 return UnmodifiableSet.unmodifiableSet(set); 103 } 104 105 @Override 106 public Iterator<E> iterator() { 107 return UnmodifiableIterator.<E>unmodifiableIterator(decorated().iterator()); 108 } 109 110 /** 111 * Deserializes the collection in using a custom routine. 112 * 113 * @param in The input stream 114 * @throws IOException Thrown if an error occurs while reading from the stream 115 * @throws ClassNotFoundException if an object read from the stream cannot be loaded 116 * @throws ClassCastException if deserialized object has wrong type 117 */ 118 @SuppressWarnings("unchecked") // will throw CCE, see Javadoc 119 private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { 120 in.defaultReadObject(); 121 setCollection((Collection<E>) in.readObject()); 122 } 123 124 @Override 125 public boolean remove(final Object object) { 126 throw new UnsupportedOperationException(); 127 } 128 129 @Override 130 public int remove(final Object object, final int count) { 131 throw new UnsupportedOperationException(); 132 } 133 134 @Override 135 public boolean removeAll(final Collection<?> coll) { 136 throw new UnsupportedOperationException(); 137 } 138 139 @Override 140 public boolean removeIf(final Predicate<? super E> filter) { 141 throw new UnsupportedOperationException(); 142 } 143 144 @Override 145 public boolean retainAll(final Collection<?> coll) { 146 throw new UnsupportedOperationException(); 147 } 148 149 @Override 150 public int setCount(final E object, final int count) { 151 throw new UnsupportedOperationException(); 152 } 153 154 @Override 155 public Set<E> uniqueSet() { 156 final Set<E> set = decorated().uniqueSet(); 157 return UnmodifiableSet.unmodifiableSet(set); 158 } 159 160 /** 161 * Serializes this object to an ObjectOutputStream. 162 * 163 * @param out The target ObjectOutputStream. 164 * @throws IOException thrown when an I/O errors occur writing to the target stream. 165 */ 166 private void writeObject(final ObjectOutputStream out) throws IOException { 167 out.defaultWriteObject(); 168 out.writeObject(decorated()); 169 } 170 171}