View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2015 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  import java.util.function.BiFunction;
24  
25  
26  /** Utility class to maintain a set of inclusions and exclusions.
27   * <p>Maintains a set of included and excluded elements.  The method {@link #matches(Object)}
28   * will return true IFF the passed object is not in the excluded set AND ( either the 
29   * included set is empty OR the object is in the included set) 
30   * <p>The type of the underlying {@link Set} used may be passed into the 
31   * constructor, so special sets like Servlet PathMap may be used.
32   * <p>
33   * @param <ITEM> The type of element
34   */
35  public class IncludeExclude<ITEM> 
36  {
37      private final Set<ITEM> _includes;
38      private final Set<ITEM> _excludes;
39      private final BiFunction<Set<ITEM>,ITEM, Boolean> _matcher;
40  
41      /**
42       * Default constructor over {@link HashSet}
43       */
44      public IncludeExclude()
45      {
46          this(HashSet.class,null);
47      }
48      
49      /**
50       * Construct an IncludeExclude
51       * @param setClass The type of {@link Set} to using internally
52       * @param matcher A function to test if a passed ITEM is matched by the passed SET, or null to use {@link Set#contains(Object)}
53       */
54      public <SET extends Set<ITEM>> IncludeExclude(Class<SET> setClass, BiFunction<SET,ITEM, Boolean> matcher)
55      {
56          try
57          {
58              _includes = setClass.newInstance();
59              _excludes = setClass.newInstance();
60              _matcher = (BiFunction<Set<ITEM>,ITEM, Boolean>)matcher;
61          }
62          catch (InstantiationException | IllegalAccessException e)
63          {
64              throw new RuntimeException(e);
65          }
66      }
67  
68      public void include(ITEM element)
69      {
70          _includes.add(element);
71      }
72      
73      public void include(ITEM... element)
74      {
75          for (ITEM e: element)
76              _includes.add(e);
77      }
78  
79      public void exclude(ITEM element)
80      {
81          _excludes.add(element);
82      }
83      
84      public void exclude(ITEM... element)
85      {
86          for (ITEM e: element)
87              _excludes.add(e);
88      }
89      
90      public boolean matches(ITEM e)
91      {
92          if (_matcher==null)
93          {
94              if (_includes.size()>0 && !_includes.contains(e))
95                  return false;
96              return !_excludes.contains(e);
97          }
98          if (_includes.size()>0 && !_matcher.apply(_includes,e))
99              return false;
100         return !_matcher.apply(_excludes,e);
101     }
102 
103     public int size()
104     {
105         return _includes.size()+_excludes.size();
106     }
107     
108     public Set<ITEM> getIncluded()
109     {
110         return _includes;
111     }
112     
113     public Set<ITEM> getExcluded()
114     {
115         return _excludes;
116     }
117 
118     public void clear()
119     {
120         _includes.clear();
121         _excludes.clear();
122     }
123 
124     @Override
125     public String toString()
126     {
127         return String.format("%s@%x{i=%s,e=%s,m=%s}",this.getClass().getSimpleName(),hashCode(),_includes,_excludes,_matcher);
128     }
129 }