View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.util;
20  
21  import java.util.HashSet;
22  import java.util.Objects;
23  import java.util.Set;
24  import java.util.function.Predicate;
25  
26  
27  /** Utility class to maintain a set of inclusions and exclusions.
28   * <p>Maintains a set of included and excluded elements.  The method {@link #matches(Object)}
29   * will return true IFF the passed object is not in the excluded set AND ( either the 
30   * included set is empty OR the object is in the included set) 
31   * <p>The type of the underlying {@link Set} used may be passed into the 
32   * constructor, so special sets like Servlet PathMap may be used.
33   * <p>
34   * @param <ITEM> The type of element
35   */
36  public class IncludeExclude<ITEM> 
37  {
38      private final Set<ITEM> _includes;
39      private final Predicate<ITEM> _includePredicate;
40      private final Set<ITEM> _excludes;
41      private final Predicate<ITEM> _excludePredicate;
42      
43      private static class SetContainsPredicate<ITEM> implements Predicate<ITEM>
44      {
45          private final Set<ITEM> set;
46          
47          public SetContainsPredicate(Set<ITEM> set)
48          {
49              this.set = set;
50          }
51          
52          @Override
53          public boolean test(ITEM item)
54          {
55              return set.contains(item);
56          }
57      }
58      
59      /**
60       * Default constructor over {@link HashSet}
61       */
62      public IncludeExclude()
63      {
64          this(HashSet.class);
65      }
66      
67      /**
68       * Construct an IncludeExclude.
69       * <p>
70       * If the {@link Set} class also implements {@link Predicate}, then that Predicate is
71       * used to match against the set, otherwise a simple {@link Set#contains(Object)} test is used.
72       * @param setClass The type of {@link Set} to using internally
73       * @param <SET> the {@link Set} type
74       */
75      public <SET extends Set<ITEM>> IncludeExclude(Class<SET> setClass)
76      {
77          try
78          {
79              _includes = setClass.newInstance();
80              _excludes = setClass.newInstance();
81              
82              if(_includes instanceof Predicate) {
83                  _includePredicate = (Predicate<ITEM>)_includes;
84              } else {
85                  _includePredicate = new SetContainsPredicate<>(_includes);
86              }
87              
88              if(_excludes instanceof Predicate) {
89                  _excludePredicate = (Predicate<ITEM>)_excludes;
90              } else {
91                  _excludePredicate = new SetContainsPredicate<>(_excludes);
92              }
93          }
94          catch (InstantiationException | IllegalAccessException e)
95          {
96              throw new RuntimeException(e);
97          }
98      }
99      
100     /**
101      * Construct an IncludeExclude
102      * 
103      * @param includeSet the Set of items that represent the included space 
104      * @param includePredicate the Predicate for included item testing
105      * @param excludeSet the Set of items that represent the excluded space
106      * @param excludePredicate the Predicate for excluded item testing
107      * @param <SET> the {@link Set} type
108      */
109     public <SET extends Set<ITEM>> IncludeExclude(Set<ITEM> includeSet, Predicate<ITEM> includePredicate, Set<ITEM> excludeSet, Predicate<ITEM> excludePredicate)
110     {
111         Objects.requireNonNull(includeSet,"Include Set");
112         Objects.requireNonNull(includePredicate,"Include Predicate");
113         Objects.requireNonNull(excludeSet,"Exclude Set");
114         Objects.requireNonNull(excludePredicate,"Exclude Predicate");
115         
116         _includes = includeSet;
117         _includePredicate = includePredicate;
118         _excludes = excludeSet;
119         _excludePredicate = excludePredicate;
120     }
121     
122     public void include(ITEM element)
123     {
124         _includes.add(element);
125     }
126     
127     public void include(ITEM... element)
128     {
129         for (ITEM e: element)
130             _includes.add(e);
131     }
132 
133     public void exclude(ITEM element)
134     {
135         _excludes.add(element);
136     }
137     
138     public void exclude(ITEM... element)
139     {
140         for (ITEM e: element)
141             _excludes.add(e);
142     }
143     
144     public boolean matches(ITEM e)
145     {
146         if (!_includes.isEmpty() && !_includePredicate.test(e))
147             return false;
148         return !_excludePredicate.test(e);
149     }
150     
151     public int size()
152     {
153         return _includes.size()+_excludes.size();
154     }
155     
156     public Set<ITEM> getIncluded()
157     {
158         return _includes;
159     }
160     
161     public Set<ITEM> getExcluded()
162     {
163         return _excludes;
164     }
165 
166     public void clear()
167     {
168         _includes.clear();
169         _excludes.clear();
170     }
171 
172     @Override
173     public String toString()
174     {
175         return String.format("%s@%x{i=%s,ip=%s,e=%s,ep=%s}",this.getClass().getSimpleName(),hashCode(),_includes,_includePredicate,_excludes,_excludePredicate);
176     }
177 }