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 }