View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.collections4.set;
18  
19  import java.util.Iterator;
20  import java.util.NavigableSet;
21  
22  import org.apache.commons.collections4.Predicate;
23  
24  /**
25   * Decorates another {@code NavigableSet} to validate that all additions
26   * match a specified predicate.
27   * <p>
28   * This set exists to provide validation for the decorated set.
29   * It is normally created to decorate an empty set.
30   * If an object cannot be added to the set, an IllegalArgumentException is thrown.
31   * </p>
32   * <p>
33   * One usage would be to ensure that no null entries are added to the set.
34   * </p>
35   * <pre>
36   * NavigableSet set =
37   *   PredicatedSortedSet.predicatedNavigableSet(new TreeSet(),
38   *                                              NotNullPredicate.notNullPredicate());
39   * </pre>
40   *
41   * @param <E> the type of the elements in this set
42   * @since 4.1
43   */
44  public class PredicatedNavigableSet<E> extends PredicatedSortedSet<E> implements NavigableSet<E> {
45  
46      /** Serialization version */
47      private static final long serialVersionUID = 20150528L;
48  
49      /**
50       * Factory method to create a predicated (validating) navigable set.
51       * <p>
52       * If there are any elements already in the set being decorated, they
53       * are validated.
54       *
55       * @param <E> the element type
56       * @param set  the set to decorate, must not be null
57       * @param predicate  the predicate to use for validation, must not be null
58       * @return a new predicated navigable set.
59       * @throws NullPointerException if set or predicate is null
60       * @throws IllegalArgumentException if the set contains invalid elements
61       * @since 4.0
62       */
63      public static <E> PredicatedNavigableSet<E> predicatedNavigableSet(final NavigableSet<E> set,
64                                                                         final Predicate<? super E> predicate) {
65          return new PredicatedNavigableSet<>(set, predicate);
66      }
67  
68      /**
69       * Constructor that wraps (not copies).
70       * <p>
71       * If there are any elements already in the set being decorated, they
72       * are validated.
73       *
74       * @param set  the set to decorate, must not be null
75       * @param predicate  the predicate to use for validation, must not be null
76       * @throws NullPointerException if set or predicate is null
77       * @throws IllegalArgumentException if the set contains invalid elements
78       */
79      protected PredicatedNavigableSet(final NavigableSet<E> set, final Predicate<? super E> predicate) {
80          super(set, predicate);
81      }
82  
83      @Override
84      public E ceiling(final E e) {
85          return decorated().ceiling(e);
86      }
87  
88      /**
89       * Gets the navigable set being decorated.
90       *
91       * @return the decorated navigable set
92       */
93      @Override
94      protected NavigableSet<E> decorated() {
95          return (NavigableSet<E>) super.decorated();
96      }
97  
98      @Override
99      public Iterator<E> descendingIterator() {
100         return decorated().descendingIterator();
101     }
102 
103     @Override
104     public NavigableSet<E> descendingSet() {
105         return predicatedNavigableSet(decorated().descendingSet(), predicate);
106     }
107 
108     @Override
109     public E floor(final E e) {
110         return decorated().floor(e);
111     }
112 
113     @Override
114     public NavigableSet<E> headSet(final E toElement, final boolean inclusive) {
115         final NavigableSet<E> head = decorated().headSet(toElement, inclusive);
116         return predicatedNavigableSet(head, predicate);
117     }
118 
119     @Override
120     public E higher(final E e) {
121         return decorated().higher(e);
122     }
123 
124     @Override
125     public E lower(final E e) {
126         return decorated().lower(e);
127     }
128 
129     @Override
130     public E pollFirst() {
131         return decorated().pollFirst();
132     }
133 
134     @Override
135     public E pollLast() {
136         return decorated().pollLast();
137     }
138 
139     @Override
140     public NavigableSet<E> subSet(final E fromElement, final boolean fromInclusive, final E toElement,
141             final boolean toInclusive) {
142         final NavigableSet<E> sub = decorated().subSet(fromElement, fromInclusive, toElement, toInclusive);
143         return predicatedNavigableSet(sub, predicate);
144     }
145 
146     @Override
147     public NavigableSet<E> tailSet(final E fromElement, final boolean inclusive) {
148         final NavigableSet<E> tail = decorated().tailSet(fromElement, inclusive);
149         return predicatedNavigableSet(tail, predicate);
150     }
151 
152 }