]> WPIA git - gigi.git/blob - lib/jetty/org/eclipse/jetty/http/pathmap/PathMappings.java
Merge "Update notes about password security"
[gigi.git] / lib / jetty / org / eclipse / jetty / http / pathmap / PathMappings.java
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.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.Iterator;
25 import java.util.List;
26
27 import org.eclipse.jetty.util.annotation.ManagedAttribute;
28 import org.eclipse.jetty.util.annotation.ManagedObject;
29 import org.eclipse.jetty.util.component.ContainerLifeCycle;
30 import org.eclipse.jetty.util.component.Dumpable;
31 import org.eclipse.jetty.util.log.Log;
32 import org.eclipse.jetty.util.log.Logger;
33
34 /**
35  * Path Mappings of PathSpec to Resource.
36  * <p>
37  * Sorted into search order upon entry into the Set
38  * 
39  * @param <E> the type of mapping endpoint
40  */
41 @ManagedObject("Path Mappings")
42 public class PathMappings<E> implements Iterable<MappedResource<E>>, Dumpable
43 {
44     private static final Logger LOG = Log.getLogger(PathMappings.class);
45     private List<MappedResource<E>> mappings = new ArrayList<MappedResource<E>>();
46     private MappedResource<E> defaultResource = null;
47     private MappedResource<E> rootResource = null;
48
49     @Override
50     public String dump()
51     {
52         return ContainerLifeCycle.dump(this);
53     }
54
55     @Override
56     public void dump(Appendable out, String indent) throws IOException
57     {
58         ContainerLifeCycle.dump(out,indent,mappings);
59     }
60
61     @ManagedAttribute(value = "mappings", readonly = true)
62     public List<MappedResource<E>> getMappings()
63     {
64         return mappings;
65     }
66
67     public void reset()
68     {
69         mappings.clear();
70     }
71     
72     /**
73      * Return a list of MappedResource matches for the specified path.
74      * 
75      * @param path the path to return matches on
76      * @return the list of mapped resource the path matches on
77      */
78     public List<MappedResource<E>> getMatches(String path)
79     {
80         boolean matchRoot = "/".equals(path);
81         
82         List<MappedResource<E>> ret = new ArrayList<>();
83         int len = mappings.size();
84         for (int i = 0; i < len; i++)
85         {
86             MappedResource<E> mr = mappings.get(i);
87
88             switch (mr.getPathSpec().group)
89             {
90                 case ROOT:
91                     if (matchRoot)
92                         ret.add(mr);
93                     break;
94                 case DEFAULT:
95                     if (matchRoot || mr.getPathSpec().matches(path))
96                         ret.add(mr);
97                     break;
98                 default:
99                     if (mr.getPathSpec().matches(path))
100                         ret.add(mr);
101                     break;
102             }
103         }
104         return ret;
105     }
106
107     public MappedResource<E> getMatch(String path)
108     {
109         if (path.equals("/") && rootResource != null)
110         {
111             return rootResource;
112         }
113         
114         int len = mappings.size();
115         for (int i = 0; i < len; i++)
116         {
117             MappedResource<E> mr = mappings.get(i);
118             if (mr.getPathSpec().matches(path))
119             {
120                 return mr;
121             }
122         }
123         return defaultResource;
124     }
125
126     @Override
127     public Iterator<MappedResource<E>> iterator()
128     {
129         return mappings.iterator();
130     }
131
132     @SuppressWarnings("incomplete-switch")
133     public void put(PathSpec pathSpec, E resource)
134     {
135         MappedResource<E> entry = new MappedResource<>(pathSpec,resource);
136         switch (pathSpec.group)
137         {
138             case DEFAULT:
139                 defaultResource = entry;
140                 break;
141             case ROOT:
142                 rootResource = entry;
143                 break;
144         }
145         
146         // TODO: add warning when replacing an existing pathspec?
147         
148         mappings.add(entry);
149         if (LOG.isDebugEnabled())
150             LOG.debug("Added {} to {}",entry,this);
151         Collections.sort(mappings);
152     }
153
154     @Override
155     public String toString()
156     {
157         return String.format("%s[size=%d]",this.getClass().getSimpleName(),mappings.size());
158     }
159 }