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.websocket.server.pathmap;
20
21 /**
22 * The base PathSpec, what all other path specs are based on
23 */
24 public abstract class PathSpec implements Comparable<PathSpec>
25 {
26 protected String pathSpec;
27 protected PathSpecGroup group;
28 protected int pathDepth;
29 protected int specLength;
30
31 @Override
32 public int compareTo(PathSpec other)
33 {
34 // Grouping (increasing)
35 int diff = this.group.ordinal() - other.group.ordinal();
36 if (diff != 0)
37 {
38 return diff;
39 }
40
41 // Spec Length (decreasing)
42 diff = other.specLength - this.specLength;
43 if (diff != 0)
44 {
45 return diff;
46 }
47
48 // Path Spec Name (alphabetical)
49 return this.pathSpec.compareTo(other.pathSpec);
50 }
51
52 @Override
53 public boolean equals(Object obj)
54 {
55 if (this == obj)
56 {
57 return true;
58 }
59 if (obj == null)
60 {
61 return false;
62 }
63 if (getClass() != obj.getClass())
64 {
65 return false;
66 }
67 PathSpec other = (PathSpec)obj;
68 if (pathSpec == null)
69 {
70 if (other.pathSpec != null)
71 {
72 return false;
73 }
74 }
75 else if (!pathSpec.equals(other.pathSpec))
76 {
77 return false;
78 }
79 return true;
80 }
81
82 public PathSpecGroup getGroup()
83 {
84 return group;
85 }
86
87 /**
88 * Get the number of path elements that this path spec declares.
89 * <p>
90 * This is used to determine longest match logic.
91 *
92 * @return the depth of the path segments that this spec declares
93 */
94 public int getPathDepth()
95 {
96 return pathDepth;
97 }
98
99 /**
100 * Return the portion of the path that is after the path spec.
101 *
102 * @param path
103 * the path to match against
104 * @return the path info portion of the string
105 */
106 public abstract String getPathInfo(String path);
107
108 /**
109 * Return the portion of the path that matches a path spec.
110 *
111 * @param path
112 * the path to match against
113 * @return the match, or null if no match at all
114 */
115 public abstract String getPathMatch(String path);
116
117 /**
118 * The as-provided path spec.
119 *
120 * @return the as-provided path spec
121 */
122 public String getPathSpec()
123 {
124 return pathSpec;
125 }
126
127 /**
128 * Get the relative path.
129 *
130 * @param base
131 * the base the path is relative to
132 * @param path
133 * the additional path
134 * @return the base plus path with pathSpec portion removed
135 */
136 public abstract String getRelativePath(String base, String path);
137
138 @Override
139 public int hashCode()
140 {
141 final int prime = 31;
142 int result = 1;
143 result = (prime * result) + ((pathSpec == null)?0:pathSpec.hashCode());
144 return result;
145 }
146
147 /**
148 * Test to see if the provided path matches this path spec
149 *
150 * @param path
151 * the path to test
152 * @return true if the path matches this path spec, false otherwise
153 */
154 public abstract boolean matches(String path);
155
156 @Override
157 public String toString()
158 {
159 StringBuilder str = new StringBuilder();
160 str.append(this.getClass().getSimpleName()).append("[\"");
161 str.append(pathSpec);
162 str.append("\",pathDepth=").append(pathDepth);
163 str.append(",group=").append(group);
164 str.append("]");
165 return str.toString();
166 }
167 }