1 /*
2  * Copyright (C) 2007 The Guava Authors
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 
17 package com.google.common.collect.testing;
18 
19 import com.google.common.annotations.GwtCompatible;
20 import java.util.AbstractCollection;
21 import java.util.Arrays;
22 import java.util.Collection;
23 import java.util.Iterator;
24 
25 /**
26  * A simplistic collection which implements only the bare minimum allowed by the spec, and throws
27  * exceptions whenever it can.
28  *
29  * @author Kevin Bourrillion
30  */
31 @GwtCompatible
32 public class MinimalCollection<E> extends AbstractCollection<E> {
33   // TODO: expose allow nulls parameter?
34 
of(E... contents)35   public static <E> MinimalCollection<E> of(E... contents) {
36     return new MinimalCollection<E>(Object.class, true, contents);
37   }
38 
39   // TODO: use this
ofClassAndContents(Class<? super E> type, E... contents)40   public static <E> MinimalCollection<E> ofClassAndContents(Class<? super E> type, E... contents) {
41     return new MinimalCollection<E>(type, true, contents);
42   }
43 
44   private final E[] contents;
45   private final Class<? super E> type;
46   private final boolean allowNulls;
47 
48   // Package-private so that it can be extended.
MinimalCollection(Class<? super E> type, boolean allowNulls, E... contents)49   MinimalCollection(Class<? super E> type, boolean allowNulls, E... contents) {
50     // TODO: consider making it shuffle the contents to test iteration order.
51     this.contents = Platform.clone(contents);
52     this.type = type;
53     this.allowNulls = allowNulls;
54 
55     if (!allowNulls) {
56       for (Object element : contents) {
57         if (element == null) {
58           throw new NullPointerException();
59         }
60       }
61     }
62   }
63 
64   @Override
size()65   public int size() {
66     return contents.length;
67   }
68 
69   @Override
contains(Object object)70   public boolean contains(Object object) {
71     if (!allowNulls) {
72       // behave badly
73       if (object == null) {
74         throw new NullPointerException();
75       }
76     }
77     Platform.checkCast(type, object); // behave badly
78     return Arrays.asList(contents).contains(object);
79   }
80 
81   @Override
containsAll(Collection<?> collection)82   public boolean containsAll(Collection<?> collection) {
83     if (!allowNulls) {
84       for (Object object : collection) {
85         // behave badly
86         if (object == null) {
87           throw new NullPointerException();
88         }
89       }
90     }
91     return super.containsAll(collection);
92   }
93 
94   @Override
iterator()95   public Iterator<E> iterator() {
96     return Arrays.asList(contents).iterator();
97   }
98 
99   @Override
toArray()100   public Object[] toArray() {
101     Object[] result = new Object[contents.length];
102     System.arraycopy(contents, 0, result, 0, contents.length);
103     return result;
104   }
105 
106   /*
107    * a "type A" unmodifiable collection freaks out proactively, even if there
108    * wasn't going to be any actual work to do anyway
109    */
110 
111   @Override
addAll(Collection<? extends E> elementsToAdd)112   public boolean addAll(Collection<? extends E> elementsToAdd) {
113     throw up();
114   }
115 
116   @Override
removeAll(Collection<?> elementsToRemove)117   public boolean removeAll(Collection<?> elementsToRemove) {
118     throw up();
119   }
120 
121   @Override
retainAll(Collection<?> elementsToRetain)122   public boolean retainAll(Collection<?> elementsToRetain) {
123     throw up();
124   }
125 
126   @Override
clear()127   public void clear() {
128     throw up();
129   }
130 
up()131   private static UnsupportedOperationException up() {
132     throw new UnsupportedOperationException();
133   }
134 }
135