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