001/*
002 * Copyright (C) 2007 The Guava Authors
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
017package com.google.common.collect.testing;
018
019import com.google.common.annotations.GwtCompatible;
020import java.util.AbstractCollection;
021import java.util.Arrays;
022import java.util.Collection;
023import java.util.Iterator;
024
025/**
026 * A simplistic collection which implements only the bare minimum allowed by the spec, and throws
027 * exceptions whenever it can.
028 *
029 * @author Kevin Bourrillion
030 */
031@GwtCompatible
032public class MinimalCollection<E> extends AbstractCollection<E> {
033  // TODO: expose allow nulls parameter?
034
035  public static <E> MinimalCollection<E> of(E... contents) {
036    return new MinimalCollection<E>(Object.class, true, contents);
037  }
038
039  // TODO: use this
040  public static <E> MinimalCollection<E> ofClassAndContents(Class<? super E> type, E... contents) {
041    return new MinimalCollection<E>(type, true, contents);
042  }
043
044  private final E[] contents;
045  private final Class<? super E> type;
046  private final boolean allowNulls;
047
048  // Package-private so that it can be extended.
049  MinimalCollection(Class<? super E> type, boolean allowNulls, E... contents) {
050    // TODO: consider making it shuffle the contents to test iteration order.
051    this.contents = Platform.clone(contents);
052    this.type = type;
053    this.allowNulls = allowNulls;
054
055    if (!allowNulls) {
056      for (Object element : contents) {
057        if (element == null) {
058          throw new NullPointerException();
059        }
060      }
061    }
062  }
063
064  @Override
065  public int size() {
066    return contents.length;
067  }
068
069  @Override
070  public boolean contains(Object object) {
071    if (!allowNulls) {
072      // behave badly
073      if (object == null) {
074        throw new NullPointerException();
075      }
076    }
077    Platform.checkCast(type, object); // behave badly
078    return Arrays.asList(contents).contains(object);
079  }
080
081  @Override
082  public boolean containsAll(Collection<?> collection) {
083    if (!allowNulls) {
084      for (Object object : collection) {
085        // behave badly
086        if (object == null) {
087          throw new NullPointerException();
088        }
089      }
090    }
091    return super.containsAll(collection);
092  }
093
094  @Override
095  public Iterator<E> iterator() {
096    return Arrays.asList(contents).iterator();
097  }
098
099  @Override
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
112  public boolean addAll(Collection<? extends E> elementsToAdd) {
113    throw up();
114  }
115
116  @Override
117  public boolean removeAll(Collection<?> elementsToRemove) {
118    throw up();
119  }
120
121  @Override
122  public boolean retainAll(Collection<?> elementsToRetain) {
123    throw up();
124  }
125
126  @Override
127  public void clear() {
128    throw up();
129  }
130
131  private static UnsupportedOperationException up() {
132    throw new UnsupportedOperationException();
133  }
134}