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.http.pathmap;
20  
21  import java.util.ArrayList;
22  import java.util.Collection;
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.Set;
26  import java.util.TreeSet;
27  import java.util.function.Predicate;
28  
29  /**
30   * A Set of PathSpec strings.
31   * <p>
32   * Used by {@link org.eclipse.jetty.util.IncludeExclude} logic
33   */
34  public class PathSpecSet implements Set<String>, Predicate<String>
35  {
36      private final Set<PathSpec> specs = new TreeSet<>();
37  
38      @Override
39      public boolean test(String s)
40      {
41          for (PathSpec spec : specs)
42          {
43              if (spec.matches(s))
44              {
45                  return true;
46              }
47          }
48          return false;
49      }
50  
51      @Override
52      public boolean isEmpty()
53      {
54          return specs.isEmpty();
55      }
56  
57      @Override
58      public Iterator<String> iterator()
59      {
60          return new Iterator<String>()
61          {
62              private Iterator<PathSpec> iter = specs.iterator();
63  
64              @Override
65              public boolean hasNext()
66              {
67                  return iter.hasNext();
68              }
69  
70              @Override
71              public String next()
72              {
73                  PathSpec spec = iter.next();
74                  if (spec == null)
75                  {
76                      return null;
77                  }
78                  return spec.getDeclaration();
79              }
80  
81              @Override
82              public void remove()
83              {
84                  throw new UnsupportedOperationException("Remove not supported by this Iterator");
85              }
86          };
87      }
88  
89      @Override
90      public int size()
91      {
92          return specs.size();
93      }
94  
95      @Override
96      public boolean contains(Object o)
97      {
98          if (o instanceof PathSpec)
99          {
100             return specs.contains(o);
101         }
102         if (o instanceof String)
103         {
104             return specs.contains(toPathSpec((String)o));
105         }
106         return false;
107     }
108 
109     private PathSpec asPathSpec(Object o)
110     {
111         if (o == null)
112         {
113             return null;
114         }
115         if (o instanceof PathSpec)
116         {
117             return (PathSpec)o;
118         }
119         if (o instanceof String)
120         {
121             return toPathSpec((String)o);
122         }
123         return toPathSpec(o.toString());
124     }
125 
126     private PathSpec toPathSpec(String rawSpec)
127     {
128         if ((rawSpec == null) || (rawSpec.length() < 1))
129         {
130             throw new RuntimeException("Path Spec String must start with '^', '/', or '*.': got [" + rawSpec + "]");
131         }
132         if (rawSpec.charAt(0) == '^')
133         {
134             return new RegexPathSpec(rawSpec);
135         }
136         else
137         {
138             return new ServletPathSpec(rawSpec);
139         }
140     }
141 
142     @Override
143     public Object[] toArray()
144     {
145         return toArray(new String[specs.size()]);
146     }
147 
148     @Override
149     public <T> T[] toArray(T[] a)
150     {
151         int i = 0;
152         for (PathSpec spec : specs)
153         {
154             a[i++] = (T)spec.getDeclaration();
155         }
156         return a;
157     }
158 
159     @Override
160     public boolean add(String e)
161     {
162         return specs.add(toPathSpec(e));
163     }
164 
165     @Override
166     public boolean remove(Object o)
167     {
168         return specs.remove(asPathSpec(o));
169     }
170 
171     @Override
172     public boolean containsAll(Collection<?> coll)
173     {
174         for (Object o : coll)
175         {
176             if (!specs.contains(asPathSpec(o)))
177                 return false;
178         }
179         return true;
180     }
181 
182     @Override
183     public boolean addAll(Collection<? extends String> coll)
184     {
185         boolean ret = false;
186 
187         for (String s : coll)
188         {
189             ret |= add(s);
190         }
191 
192         return ret;
193     }
194 
195     @Override
196     public boolean retainAll(Collection<?> coll)
197     {
198         List<PathSpec> collSpecs = new ArrayList<>();
199         for (Object o : coll)
200         {
201             collSpecs.add(asPathSpec(o));
202         }
203         return specs.retainAll(collSpecs);
204     }
205 
206     @Override
207     public boolean removeAll(Collection<?> coll)
208     {
209         List<PathSpec> collSpecs = new ArrayList<>();
210         for (Object o : coll)
211         {
212             collSpecs.add(asPathSpec(o));
213         }
214         return specs.removeAll(collSpecs);
215     }
216 
217     @Override
218     public void clear()
219     {
220         specs.clear();
221     }
222 }