1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.websocket.server.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 import org.eclipse.jetty.websocket.server.pathmap.PathMappings.MappedResource;
34
35
36
37
38
39
40
41
42 @ManagedObject("Path Mappings")
43 public class PathMappings<E> implements Iterable<MappedResource<E>>, Dumpable
44 {
45 @ManagedObject("Mapped Resource")
46 public static class MappedResource<E> implements Comparable<MappedResource<E>>
47 {
48 private final PathSpec pathSpec;
49 private final E resource;
50
51 public MappedResource(PathSpec pathSpec, E resource)
52 {
53 this.pathSpec = pathSpec;
54 this.resource = resource;
55 }
56
57
58
59
60 @Override
61 public int compareTo(MappedResource<E> other)
62 {
63 return this.pathSpec.compareTo(other.pathSpec);
64 }
65
66 @Override
67 public boolean equals(Object obj)
68 {
69 if (this == obj)
70 {
71 return true;
72 }
73 if (obj == null)
74 {
75 return false;
76 }
77 if (getClass() != obj.getClass())
78 {
79 return false;
80 }
81 MappedResource<?> other = (MappedResource<?>)obj;
82 if (pathSpec == null)
83 {
84 if (other.pathSpec != null)
85 {
86 return false;
87 }
88 }
89 else if (!pathSpec.equals(other.pathSpec))
90 {
91 return false;
92 }
93 return true;
94 }
95
96 @ManagedAttribute(value = "path spec", readonly = true)
97 public PathSpec getPathSpec()
98 {
99 return pathSpec;
100 }
101
102 @ManagedAttribute(value = "resource", readonly = true)
103 public E getResource()
104 {
105 return resource;
106 }
107
108 @Override
109 public int hashCode()
110 {
111 final int prime = 31;
112 int result = 1;
113 result = (prime * result) + ((pathSpec == null)?0:pathSpec.hashCode());
114 return result;
115 }
116
117 @Override
118 public String toString()
119 {
120 return String.format("MappedResource[pathSpec=%s,resource=%s]",pathSpec,resource);
121 }
122 }
123
124 private static final Logger LOG = Log.getLogger(PathMappings.class);
125 private List<MappedResource<E>> mappings = new ArrayList<MappedResource<E>>();
126 private MappedResource<E> defaultResource = null;
127
128 @Override
129 public String dump()
130 {
131 return ContainerLifeCycle.dump(this);
132 }
133
134 @Override
135 public void dump(Appendable out, String indent) throws IOException
136 {
137 ContainerLifeCycle.dump(out,indent,mappings);
138 }
139
140 @ManagedAttribute(value = "mappings", readonly = true)
141 public List<MappedResource<E>> getMappings()
142 {
143 return mappings;
144 }
145
146 public void reset()
147 {
148 mappings.clear();
149 }
150
151 public MappedResource<E> getMatch(String path)
152 {
153 int len = mappings.size();
154 for (int i = 0; i < len; i++)
155 {
156 MappedResource<E> mr = mappings.get(i);
157 if (mr.getPathSpec().matches(path))
158 {
159 return mr;
160 }
161 }
162 return defaultResource;
163 }
164
165 @Override
166 public Iterator<MappedResource<E>> iterator()
167 {
168 return mappings.iterator();
169 }
170
171 public void put(PathSpec pathSpec, E resource)
172 {
173 MappedResource<E> entry = new MappedResource<>(pathSpec,resource);
174 if (pathSpec.group == PathSpecGroup.DEFAULT)
175 {
176 defaultResource = entry;
177 }
178
179 mappings.add(entry);
180 if (LOG.isDebugEnabled())
181 LOG.debug("Added {} to {}",entry,this);
182 Collections.sort(mappings);
183 }
184
185 @Override
186 public String toString()
187 {
188 return String.format("%s[size=%d]",this.getClass().getSimpleName(),mappings.size());
189 }
190 }