2009/05/20 - Apache Shale has been retired.
For more information, please explore the Attic.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shale.remoting.impl;
19
20 import javax.faces.context.FacesContext;
21 import org.apache.shale.remoting.Mapping;
22 import org.apache.shale.remoting.Mappings;
23 import org.apache.shale.remoting.Mechanism;
24 import org.apache.shale.remoting.Processor;
25
26 /***
27 * <p>Default implementation of {@link Mapping}. This implementation recognizes
28 * patterns similar to URL mappings in the Servlet Specification:</p>
29 * <ul>
30 * <li><em>/foo/*</em> - prefix matching</li>
31 * <li><em>*.foo</em> - extension matching</li>
32 * </ul>
33 * <p>If a view identifier matches, the corresponding resource identifier is
34 * calculated by stripping the non-wildcard part of the view identifier
35 * (<code>/foo</code> or <code>.foo</code> for the examples above) and
36 * returning the remainder.</p>
37 */
38 public class MappingImpl implements Mapping {
39
40
41
42
43
44 /***
45 * <p>Construct an unconfigured instance.</p>
46 */
47 public MappingImpl() {
48 this(null, null, null);
49 }
50
51
52 /***
53 * <p>Construct a fully configured instance.</p>
54 *
55 * @param mechanism {@link Mechanism} used to produce response for this mapping
56 * @param pattern URL matching pattern for this mapping
57 * @param processor Processor instance for this mapping
58 */
59 public MappingImpl(Mechanism mechanism, String pattern, Processor processor) {
60 setMechanism(mechanism);
61 setPattern(pattern);
62 setProcessor(processor);
63 }
64
65
66
67
68
69 /***
70 * <p>The {@link Mappings} instance that owns this mapping.</p>
71 */
72 private Mappings mappings = null;
73
74
75 /***
76 * <p>The non-wildcard part of the pattern for this mapping.</p>
77 */
78 private String match = null;
79
80
81 /***
82 * <p>The {@link Mechanism} used to produce response for this mapping.</p>
83 */
84 private Mechanism mechanism = null;
85
86
87 /***
88 * <p>The URL matching pattern for this mapping.</p>
89 */
90 private String pattern = null;
91
92
93 /***
94 * <p>Flag indicating we are doing prefix matching, versus extension
95 * mapping.</p>
96 */
97 private boolean prefix = true;
98
99
100 /***
101 * <p>The <code>Processor</code> instance for this mapping.</p>
102 */
103 private Processor processor = null;
104
105
106
107
108
109 /*** {@inheritDoc} */
110 public Mappings getMappings() {
111 return this.mappings;
112 }
113
114
115 /*** {@inheritDoc} */
116 public void setMappings(Mappings mappings) {
117 this.mappings = mappings;
118 }
119
120
121 /*** {@inheritDoc} */
122 public Mechanism getMechanism() {
123 return this.mechanism;
124 }
125
126
127 /*** {@inheritDoc} */
128 public void setMechanism(Mechanism mechanism) {
129 this.mechanism = mechanism;
130 }
131
132
133 /*** {@inheritDoc} */
134 public String getPattern() {
135 return this.pattern;
136 }
137
138
139 /*** {@inheritDoc} */
140 public void setPattern(String pattern) {
141
142 if (pattern == null) {
143 this.match = null;
144 this.pattern = null;
145 return;
146 } else if (pattern.endsWith("/*")) {
147 if (!pattern.startsWith("/")) {
148 throw new IllegalArgumentException(pattern);
149 }
150 this.match = pattern.substring(0, pattern.length() - 1);
151 this.pattern = pattern;
152 this.prefix = true;
153 } else if (pattern.startsWith("*.")) {
154 int period = pattern.lastIndexOf('.');
155 if (period != 1) {
156 throw new IllegalArgumentException(pattern);
157 }
158 this.match = pattern.substring(1);
159 this.pattern = pattern;
160 this.prefix = false;
161 } else {
162 throw new IllegalArgumentException(pattern);
163 }
164
165 }
166
167
168 /*** {@inheritDoc} */
169 public Processor getProcessor() {
170 return this.processor;
171 }
172
173
174 /*** {@inheritDoc} */
175 public void setProcessor(Processor processor) {
176 this.processor = processor;
177 }
178
179
180 /*** {@inheritDoc} */
181 public String mapResourceId(FacesContext context, String resourceId) {
182
183
184
185 String[] patterns = getMappings().getPatterns();
186 String pattern = null;
187 if ((patterns != null) && (patterns.length > 0)) {
188 pattern = patterns[getMappings().getPatternIndex()];
189 }
190
191
192 StringBuffer sb = new StringBuffer();
193 if (pattern != null) {
194 sb.append(context.getExternalContext().getRequestContextPath());
195 }
196 if ((pattern != null) && (pattern.endsWith("/*"))) {
197 sb.append(pattern.substring(0, pattern.length() - 2));
198 }
199 if (getPattern().endsWith("*")) {
200 sb.append(getPattern().substring(0, getPattern().length() - 2));
201 }
202 sb.append(resourceId);
203 if (getPattern().startsWith("*.")) {
204 sb.append(getPattern().substring(1));
205 }
206 if ((pattern != null) && (pattern.startsWith("*."))) {
207 sb.append(pattern.substring(1));
208 }
209
210
211 if (pattern == null) {
212
213
214 return context.getApplication().getViewHandler().getActionURL(context, sb.toString());
215 } else {
216
217
218 return sb.toString();
219 }
220
221 }
222
223
224 /*** {@inheritDoc} */
225 public String mapViewId(FacesContext context) {
226
227
228 String viewId = viewId(context);
229 if (viewId == null) {
230 return null;
231 }
232
233
234 if (prefix) {
235 if (viewId.startsWith(match) && !viewId.equals(match)) {
236 return viewId.substring(match.length() - 1);
237 } else {
238 return null;
239 }
240 } else {
241 if (viewId.endsWith(match) && !viewId.equals(match)) {
242 return viewId.substring(0, viewId.length() - match.length());
243 } else {
244 return null;
245 }
246 }
247
248 }
249
250
251
252
253
254 /***
255 * <p>Return the hash code for this object.</p>
256 */
257 public int hashCode() {
258 if (this.pattern == null) {
259 return 0;
260 } else {
261 return this.pattern.hashCode();
262 }
263 }
264
265
266 /***
267 * <p>Two {@link Mapping}s are equal if they have the same pattern.</p>
268 *
269 * @param object Object to which we are tested for equality
270 */
271 public boolean equals(Object object) {
272 if ((object == null) || !(object instanceof Mapping)) {
273 return false;
274 }
275 if (this.pattern == null) {
276 return ((Mapping) object).getPattern() == null;
277 } else {
278 return this.pattern.equals(((Mapping) object).getPattern());
279 }
280 }
281
282
283
284
285
286 /***
287 * <p>Extract and return the view identifier for this request, after
288 * stripping any replacement suffix if <code>FacesServlet</code> is
289 * being extension mapped.</p>
290 *
291 * @param context <code>FacesContext</code> for the current request
292 */
293 private String viewId(FacesContext context) {
294
295
296 String viewId = context.getViewRoot().getViewId();
297
298
299
300 String extension = mappings.getExtension();
301 if ((extension != null) && (viewId.endsWith(extension))) {
302 return viewId.substring(0, viewId.length() - extension.length());
303 }
304
305
306
307
308
309
310
311
312
313 String[] patterns = mappings.getPatterns();
314 if ((patterns == null) || (patterns.length < 1)) {
315 return viewId;
316 }
317 for (int i = 0; i < patterns.length; i++) {
318 if (!patterns[i].startsWith("*.")) {
319 continue;
320 }
321 String match = patterns[i].substring(1);
322 if (viewId.endsWith(match)) {
323 return viewId.substring(0, viewId.length() - match.length());
324 }
325 }
326
327
328 return viewId;
329
330 }
331
332 }