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 }