View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2017 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.Set;
23  
24  
25  /** Utility class to maintain a set of inclusions and exclusions.
26   * <p>Maintains a set of included and excluded elements.  The method {@link #matches(Object)}
27   * will return true IFF the passed object is not in the excluded set AND ( either the 
28   * included set is empty OR the object is in the included set) 
29   * <p>The type of the underlying {@link Set} used may be passed into the 
30   * constructor, so special sets like Servlet PathMap may be used.
31   * <p>
32   * @param <P> The type of element of the set (often a pattern)
33   * @param <T> The type of the instance passed to the predicate 
34   */
35  public class IncludeExcludeSet<P,T> implements Predicate<T>
36  {
37      private final Set<P> _includes;
38      private final Predicate<T> _includePredicate;
39      private final Set<P> _excludes;
40      private final Predicate<T> _excludePredicate;
41      
42      private static class SetContainsPredicate<T> implements Predicate<T>
43      {
44          private final Set<T> set;
45          
46          public SetContainsPredicate(Set<T> set)
47          {
48              this.set = set;
49          }
50          
51          @Override
52          public boolean test(T item)
53          {
54              return set.contains(item);
55          }
56      }
57      
58      /**
59       * Default constructor over {@link HashSet}
60       */
61      public IncludeExcludeSet()
62      {
63          this(HashSet.class);
64      }
65      
66      /**
67       * Construct an IncludeExclude
68       * @param setClass The type of {@link Set} to using internally to hold patterns. Two instances will be created.
69       * one for include patterns and one for exclude patters.  If the class is also a {@link Predicate},
70       * then it is also used as the item test for the set, otherwise a {@link SetContainsPredicate} instance
71       * is created.
72       * @param <SET> The type of a set to use as the backing store
73       */
74      public <SET extends Set<P>> IncludeExcludeSet(Class<SET> setClass)
75      {
76          try
77          {
78              _includes = setClass.newInstance();
79              _excludes = setClass.newInstance();
80              
81              if(_includes instanceof Predicate) 
82              {
83                  _includePredicate = (Predicate<T>)_includes;
84              } 
85              else 
86              {
87                  _includePredicate = new SetContainsPredicate(_includes);
88              }
89              
90              if(_excludes instanceof Predicate) 
91              {
92                  _excludePredicate = (Predicate<T>)_excludes;
93              } 
94              else 
95              {
96                  _excludePredicate = new SetContainsPredicate(_excludes);
97              }
98          }
99          catch (InstantiationException | IllegalAccessException e)
100         {
101             throw new RuntimeException(e);
102         }
103     }
104     
105     /**
106      * Construct an IncludeExclude
107      * 
108      * @param includeSet the Set of items that represent the included space 
109      * @param includePredicate the Predicate for included item testing (null for simple {@link Set#contains(Object)} test)
110      * @param excludeSet the Set of items that represent the excluded space
111      * @param excludePredicate the Predicate for excluded item testing (null for simple {@link Set#contains(Object)} test)
112      * @param <SET> The type of a set to use as the backing store
113      */
114     public <SET extends Set<P>> IncludeExcludeSet(Set<P> includeSet, Predicate<T> includePredicate, Set<P> excludeSet, Predicate<T> excludePredicate)
115     {
116         _includes = includeSet;
117         _includePredicate = includePredicate;
118         _excludes = excludeSet;
119         _excludePredicate = excludePredicate;
120     }
121     
122     public void include(P element)
123     {
124         _includes.add(element);
125     }
126     
127     public void include(P... element)
128     {
129         for (P e: element)
130             _includes.add(e);
131     }
132 
133     public void exclude(P element)
134     {
135         _excludes.add(element);
136     }
137     
138     public void exclude(P... element)
139     {
140         for (P e: element)
141             _excludes.add(e);
142     }
143 
144     public boolean matches(T t)
145     {
146         return test(t);
147     }
148     
149     public boolean test(T t)
150     {
151         if (!_includes.isEmpty() && !_includePredicate.test(t))
152             return false;
153         return !_excludePredicate.test(t);
154     }
155     
156     public int size()
157     {
158         return _includes.size()+_excludes.size();
159     }
160     
161     public Set<P> getIncluded()
162     {
163         return _includes;
164     }
165     
166     public Set<P> getExcluded()
167     {
168         return _excludes;
169     }
170 
171     public void clear()
172     {
173         _includes.clear();
174         _excludes.clear();
175     }
176 
177     @Override
178     public String toString()
179     {
180         return String.format("%s@%x{i=%s,ip=%s,e=%s,ep=%s}",this.getClass().getSimpleName(),hashCode(),_includes,_includePredicate,_excludes,_excludePredicate);
181     }
182 }