001/*
002 * Copyright (C) 2008 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.features;
018
019import com.google.common.annotations.GwtCompatible;
020import com.google.common.collect.testing.Helpers;
021import java.lang.annotation.Inherited;
022import java.lang.annotation.Retention;
023import java.lang.annotation.RetentionPolicy;
024import java.util.Collection;
025import java.util.LinkedHashSet;
026import java.util.Set;
027import java.util.SortedSet;
028
029/**
030 * Optional features of classes derived from {@code Collection}.
031 *
032 * @author George van den Driessche
033 */
034// Enum values use constructors with generic varargs.
035@SuppressWarnings("unchecked")
036@GwtCompatible
037public enum CollectionFeature implements Feature<Collection> {
038  /**
039   * The collection must not throw {@code NullPointerException} on calls such as {@code
040   * contains(null)} or {@code remove(null)}, but instead must return a simple {@code false}.
041   */
042  ALLOWS_NULL_QUERIES,
043  ALLOWS_NULL_VALUES(ALLOWS_NULL_QUERIES),
044
045  /**
046   * Indicates that a collection disallows certain elements (other than {@code null}, whose validity
047   * as an element is indicated by the presence or absence of {@link #ALLOWS_NULL_VALUES}). From the
048   * documentation for {@link Collection}:
049   *
050   * <blockquote>
051   *
052   * "Some collection implementations have restrictions on the elements that they may contain. For
053   * example, some implementations prohibit null elements, and some have restrictions on the types
054   * of their elements."
055   *
056   * </blockquote>
057   */
058  RESTRICTS_ELEMENTS,
059
060  /**
061   * Indicates that a collection has a well-defined ordering of its elements. The ordering may
062   * depend on the element values, such as a {@link SortedSet}, or on the insertion ordering, such
063   * as a {@link LinkedHashSet}. All list tests and sorted-collection tests automatically specify
064   * this feature.
065   */
066  KNOWN_ORDER,
067
068  /**
069   * Indicates that a collection has a different {@link Object#toString} representation than most
070   * collections. If not specified, the collection tests will examine the value returned by {@link
071   * Object#toString}.
072   */
073  NON_STANDARD_TOSTRING,
074
075  /**
076   * Indicates that the constructor or factory method of a collection, usually an immutable set,
077   * throws an {@link IllegalArgumentException} when presented with duplicate elements instead of
078   * collapsing them to a single element or including duplicate instances in the collection.
079   */
080  REJECTS_DUPLICATES_AT_CREATION,
081
082  SUPPORTS_ADD,
083  SUPPORTS_REMOVE,
084  SUPPORTS_ITERATOR_REMOVE,
085  FAILS_FAST_ON_CONCURRENT_MODIFICATION,
086
087  /**
088   * Features supported by general-purpose collections - everything but {@link #RESTRICTS_ELEMENTS}.
089   *
090   * @see java.util.Collection the definition of general-purpose collections.
091   */
092  GENERAL_PURPOSE(SUPPORTS_ADD, SUPPORTS_REMOVE, SUPPORTS_ITERATOR_REMOVE),
093
094  /** Features supported by collections where only removal is allowed. */
095  REMOVE_OPERATIONS(SUPPORTS_REMOVE, SUPPORTS_ITERATOR_REMOVE),
096
097  SERIALIZABLE,
098  SERIALIZABLE_INCLUDING_VIEWS(SERIALIZABLE),
099
100  SUBSET_VIEW,
101  DESCENDING_VIEW,
102
103  /**
104   * For documenting collections that support no optional features, such as {@link
105   * java.util.Collections#emptySet}
106   */
107  NONE;
108
109  private final Set<Feature<? super Collection>> implied;
110
111  CollectionFeature(Feature<? super Collection>... implied) {
112    this.implied = Helpers.copyToSet(implied);
113  }
114
115  @Override
116  public Set<Feature<? super Collection>> getImpliedFeatures() {
117    return implied;
118  }
119
120  @Retention(RetentionPolicy.RUNTIME)
121  @Inherited
122  @TesterAnnotation
123  public @interface Require {
124    CollectionFeature[] value() default {};
125
126    CollectionFeature[] absent() default {};
127  }
128}