Source Code Cross Referenced for Route.java in  » Web-Services » restlet-1.0.8 » org » restlet » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Services » restlet 1.0.8 » org.restlet 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2005-2007 Noelios Consulting.
003:         * 
004:         * The contents of this file are subject to the terms of the Common Development
005:         * and Distribution License (the "License"). You may not use this file except in
006:         * compliance with the License.
007:         * 
008:         * You can obtain a copy of the license at
009:         * http://www.opensource.org/licenses/cddl1.txt See the License for the specific
010:         * language governing permissions and limitations under the License.
011:         * 
012:         * When distributing Covered Code, include this CDDL HEADER in each file and
013:         * include the License file at http://www.opensource.org/licenses/cddl1.txt If
014:         * applicable, add the following below this CDDL HEADER, with the fields
015:         * enclosed by brackets "[]" replaced with your own identifying information:
016:         * Portions Copyright [yyyy] [name of copyright owner]
017:         */
018:
019:        package org.restlet;
020:
021:        import java.util.ArrayList;
022:        import java.util.List;
023:        import java.util.logging.Level;
024:        import java.util.regex.Pattern;
025:
026:        import org.restlet.data.Cookie;
027:        import org.restlet.data.Form;
028:        import org.restlet.data.Reference;
029:        import org.restlet.data.Request;
030:        import org.restlet.data.Response;
031:        import org.restlet.data.Status;
032:        import org.restlet.util.Series;
033:        import org.restlet.util.Template;
034:        import org.restlet.util.Variable;
035:
036:        /**
037:         * Filter scoring the affinity of calls with the attached Restlet. The score is
038:         * used by an associated Router in order to determine the most appropriate
039:         * Restlet for a given call. The routing is based on a reference template. It
040:         * also supports the extraction of some attributes from a call. Multiple
041:         * extractions can be defined, based on the query string of the resource
042:         * reference, on the request form (ex: posted from a browser) or on cookies.
043:         * 
044:         * @see org.restlet.util.Template
045:         * @author Jerome Louvel (contact@noelios.com)
046:         */
047:        public class Route extends Filter {
048:            /** Internal class holding extraction information. */
049:            private static final class ExtractInfo {
050:                /** Target attribute name. */
051:                protected String attribute;
052:
053:                /** Name of the parameter to look for. */
054:                protected String parameter;
055:
056:                /** Indicates how to handle repeating values. */
057:                protected boolean first;
058:
059:                /**
060:                 * Constructor.
061:                 * 
062:                 * @param attribute
063:                 *            Target attribute name.
064:                 * @param parameter
065:                 *            Name of the parameter to look for.
066:                 * @param first
067:                 *            Indicates how to handle repeating values.
068:                 */
069:                public ExtractInfo(String attribute, String parameter,
070:                        boolean first) {
071:                    this .attribute = attribute;
072:                    this .parameter = parameter;
073:                    this .first = first;
074:                }
075:            }
076:
077:            /** Internal class holding validation information. */
078:            private static final class ValidateInfo {
079:                /** Name of the attribute to look for. */
080:                protected String attribute;
081:
082:                /** Indicates if the attribute presence is required. */
083:                protected boolean required;
084:
085:                /** Format of the attribute value, using Regex pattern syntax. */
086:                protected String format;
087:
088:                /**
089:                 * Constructor.
090:                 * 
091:                 * @param attribute
092:                 *            Name of the attribute to look for.
093:                 * @param required
094:                 *            Indicates if the attribute presence is required.
095:                 * @param format
096:                 *            Format of the attribute value, using Regex pattern syntax.
097:                 */
098:                public ValidateInfo(String attribute, boolean required,
099:                        String format) {
100:                    this .attribute = attribute;
101:                    this .required = required;
102:                    this .format = format;
103:                }
104:            }
105:
106:            /** The parent router. */
107:            private Router router;
108:
109:            /** The list of attribute validations. */
110:            private List<ValidateInfo> validations;
111:
112:            /** The list of cookies to extract. */
113:            private List<ExtractInfo> cookieExtracts;
114:
115:            /** The list of query parameters to extract. */
116:            private List<ExtractInfo> queryExtracts;
117:
118:            /** The list of request entity parameters to extract. */
119:            private List<ExtractInfo> entityExtracts;
120:
121:            /** The reference template to match. */
122:            private Template template;
123:
124:            /**
125:             * Constructor behaving as a simple extractor filter.
126:             * 
127:             * @param next
128:             *            The next Restlet.
129:             */
130:            public Route(Restlet next) {
131:                this (null, (Template) null, next);
132:            }
133:
134:            /**
135:             * Constructor.
136:             * 
137:             * @param router
138:             *            The parent router.
139:             * @param uriTemplate
140:             *            The URI template.
141:             * @param next
142:             *            The next Restlet.
143:             */
144:            public Route(Router router, String uriTemplate, Restlet next) {
145:                this (router, new Template(router.getLogger(), uriTemplate,
146:                        Template.MODE_STARTS_WITH, Variable.TYPE_URI_SEGMENT,
147:                        "", true, false), next);
148:            }
149:
150:            /**
151:             * Constructor.
152:             * 
153:             * @param router
154:             *            The parent router.
155:             * @param template
156:             *            The URI template.
157:             * @param next
158:             *            The next Restlet.
159:             */
160:            public Route(Router router, Template template, Restlet next) {
161:                super (router == null ? null : router.getContext(), next);
162:                this .router = router;
163:                this .cookieExtracts = null;
164:                this .queryExtracts = null;
165:                this .entityExtracts = null;
166:                this .template = template;
167:                this .validations = null;
168:            }
169:
170:            /**
171:             * Allows filtering before its handling by the target Restlet. Does nothing
172:             * by default.
173:             * 
174:             * @param request
175:             *            The request to filter.
176:             * @param response
177:             *            The response to filter.
178:             */
179:            protected void beforeHandle(Request request, Response response) {
180:                // 1 - Parse the template variables and adjust the base reference
181:                if (getTemplate() != null) {
182:                    String remainingPart = request.getResourceRef()
183:                            .getRemainingPart();
184:                    int matchedLength = getTemplate().parse(remainingPart,
185:                            request);
186:
187:                    if (getLogger().isLoggable(Level.FINER)) {
188:                        getLogger().finer(
189:                                "Attempting to match this pattern: "
190:                                        + getTemplate().getPattern() + " >> "
191:                                        + matchedLength);
192:                    }
193:
194:                    if (matchedLength != -1) {
195:                        // Updates the context
196:                        String matchedPart = remainingPart.substring(0,
197:                                matchedLength);
198:                        Reference baseRef = request.getResourceRef()
199:                                .getBaseRef();
200:
201:                        if (baseRef == null) {
202:                            baseRef = new Reference(matchedPart);
203:                        } else {
204:                            baseRef = new Reference(baseRef.toString(false,
205:                                    false)
206:                                    + matchedPart);
207:                        }
208:
209:                        request.getResourceRef().setBaseRef(baseRef);
210:
211:                        if (getLogger().isLoggable(Level.FINE)) {
212:                            getLogger().fine(
213:                                    "New base URI: "
214:                                            + request.getResourceRef()
215:                                                    .getBaseRef());
216:                            getLogger().fine(
217:                                    "New remaining part: "
218:                                            + request.getResourceRef()
219:                                                    .getRemainingPart());
220:                        }
221:
222:                        if (getLogger().isLoggable(Level.FINE)) {
223:                            getLogger()
224:                                    .fine(
225:                                            "Delegating the call to the target Restlet");
226:                        }
227:                    } else {
228:                        response.setStatus(Status.CLIENT_ERROR_NOT_FOUND);
229:                    }
230:                }
231:
232:                // 2 - Extract the attributes from form parameters (query, cookies,
233:                // entity).
234:                extractAttributes(request, response);
235:
236:                // 3 - Validate the attributes extracted (or others)
237:                validateAttributes(request, response);
238:            }
239:
240:            /**
241:             * Extracts the attributes value from the request.
242:             * 
243:             * @param request
244:             *            The request to process.
245:             * @param response
246:             *            The response to process.
247:             */
248:            private void extractAttributes(Request request, Response response) {
249:                // Extract the query parameters
250:                if (this .queryExtracts != null) {
251:                    Form form = request.getResourceRef().getQueryAsForm();
252:
253:                    if (form != null) {
254:                        for (ExtractInfo ei : getQueryExtracts()) {
255:                            if (ei.first) {
256:                                request.getAttributes().put(ei.attribute,
257:                                        form.getFirstValue(ei.parameter));
258:                            } else {
259:                                request.getAttributes().put(ei.attribute,
260:                                        form.subList(ei.parameter));
261:                            }
262:                        }
263:                    }
264:                }
265:
266:                // Extract the request entity parameters
267:                if (this .entityExtracts != null) {
268:                    Form form = request.getEntityAsForm();
269:
270:                    if (form != null) {
271:                        for (ExtractInfo ei : getEntityExtracts()) {
272:                            if (ei.first) {
273:                                request.getAttributes().put(ei.attribute,
274:                                        form.getFirstValue(ei.parameter));
275:                            } else {
276:                                request.getAttributes().put(ei.attribute,
277:                                        form.subList(ei.parameter));
278:                            }
279:                        }
280:                    }
281:                }
282:
283:                // Extract the cookie parameters
284:                if (this .cookieExtracts != null) {
285:                    Series<Cookie> cookies = request.getCookies();
286:
287:                    if (cookies != null) {
288:                        for (ExtractInfo ei : getCookieExtracts()) {
289:                            if (ei.first) {
290:                                request.getAttributes().put(ei.attribute,
291:                                        cookies.getFirstValue(ei.parameter));
292:                            } else {
293:                                request.getAttributes().put(ei.attribute,
294:                                        cookies.subList(ei.parameter));
295:                            }
296:                        }
297:                    }
298:                }
299:            }
300:
301:            /**
302:             * Extracts an attribute from the request cookies.
303:             * 
304:             * @param attribute
305:             *            The name of the request attribute to set.
306:             * @param cookieName
307:             *            The name of the cookies to extract.
308:             * @param first
309:             *            Indicates if only the first cookie should be set. Otherwise as
310:             *            a List instance might be set in the attribute value.
311:             * @return The current Filter.
312:             */
313:            public Route extractCookie(String attribute, String cookieName,
314:                    boolean first) {
315:                getCookieExtracts().add(
316:                        new ExtractInfo(attribute, cookieName, first));
317:                return this ;
318:            }
319:
320:            /**
321:             * Extracts an attribute from the request entity form.
322:             * 
323:             * @param attribute
324:             *            The name of the request attribute to set.
325:             * @param parameter
326:             *            The name of the entity form parameter to extract.
327:             * @param first
328:             *            Indicates if only the first cookie should be set. Otherwise as
329:             *            a List instance might be set in the attribute value.
330:             * @return The current Filter.
331:             */
332:            public Route extractEntity(String attribute, String parameter,
333:                    boolean first) {
334:                getEntityExtracts().add(
335:                        new ExtractInfo(attribute, parameter, first));
336:                return this ;
337:            }
338:
339:            /**
340:             * Extracts an attribute from the query string of the resource reference.
341:             * 
342:             * @param attribute
343:             *            The name of the request attribute to set.
344:             * @param parameter
345:             *            The name of the query string parameter to extract.
346:             * @param first
347:             *            Indicates if only the first cookie should be set. Otherwise as
348:             *            a List instance might be set in the attribute value.
349:             * @return The current Filter.
350:             */
351:            public Route extractQuery(String attribute, String parameter,
352:                    boolean first) {
353:                getQueryExtracts().add(
354:                        new ExtractInfo(attribute, parameter, first));
355:                return this ;
356:            }
357:
358:            /**
359:             * Returns the list of query extracts.
360:             * 
361:             * @return The list of query extracts.
362:             */
363:            private List<ExtractInfo> getCookieExtracts() {
364:                if (this .cookieExtracts == null)
365:                    this .cookieExtracts = new ArrayList<ExtractInfo>();
366:                return this .cookieExtracts;
367:            }
368:
369:            /**
370:             * Returns the list of query extracts.
371:             * 
372:             * @return The list of query extracts.
373:             */
374:            private List<ExtractInfo> getEntityExtracts() {
375:                if (this .entityExtracts == null)
376:                    this .entityExtracts = new ArrayList<ExtractInfo>();
377:                return this .entityExtracts;
378:            }
379:
380:            /**
381:             * Returns the list of query extracts.
382:             * 
383:             * @return The list of query extracts.
384:             */
385:            private List<ExtractInfo> getQueryExtracts() {
386:                if (this .queryExtracts == null)
387:                    this .queryExtracts = new ArrayList<ExtractInfo>();
388:                return this .queryExtracts;
389:            }
390:
391:            /**
392:             * Returns the parent router.
393:             * 
394:             * @return The parent router.
395:             */
396:            public Router getRouter() {
397:                return this .router;
398:            }
399:
400:            /**
401:             * Returns the reference template to match.
402:             * 
403:             * @return The reference template to match.
404:             */
405:            public Template getTemplate() {
406:                return this .template;
407:            }
408:
409:            /**
410:             * Returns the list of attribute validations.
411:             * 
412:             * @return The list of attribute validations.
413:             */
414:            private List<ValidateInfo> getValidations() {
415:                if (this .validations == null)
416:                    this .validations = new ArrayList<ValidateInfo>();
417:                return this .validations;
418:            }
419:
420:            /**
421:             * Returns the score for a given call (between 0 and 1.0).
422:             * 
423:             * @param request
424:             *            The request to score.
425:             * @param response
426:             *            The response to score.
427:             * @return The score for a given call (between 0 and 1.0).
428:             */
429:            public float score(Request request, Response response) {
430:                float result = 0F;
431:
432:                if ((getRouter() != null) && (request.getResourceRef() != null)
433:                        && (getTemplate() != null)) {
434:                    String remainingPart = request.getResourceRef()
435:                            .getRemainingPart();
436:                    if (remainingPart != null) {
437:                        int matchedLength = getTemplate().match(remainingPart);
438:
439:                        if (matchedLength != -1) {
440:                            float totalLength = remainingPart.length();
441:
442:                            if (totalLength > 0.0F) {
443:                                result = getRouter().getRequiredScore()
444:                                        + (1.0F - getRouter()
445:                                                .getRequiredScore())
446:                                        * (((float) matchedLength) / totalLength);
447:                            } else {
448:                                result = 1.0F;
449:                            }
450:                        }
451:                    }
452:
453:                    if (getLogger().isLoggable(Level.FINER)) {
454:                        getLogger().finer(
455:                                "Call score for the \""
456:                                        + getTemplate().getPattern()
457:                                        + "\" URI pattern: " + result);
458:                    }
459:                }
460:
461:                return result;
462:            }
463:
464:            /**
465:             * Sets the reference template to match.
466:             * 
467:             * @param template
468:             *            The reference template to match.
469:             */
470:            public void setTemplate(Template template) {
471:                this .template = template;
472:            }
473:
474:            /**
475:             * Checks the request attributes for presence, format, etc. If the check
476:             * fails, then a response status CLIENT_ERROR_BAD_REQUEST is returned with
477:             * the proper status description.
478:             * 
479:             * @param attribute
480:             *            Name of the attribute to look for.
481:             * @param required
482:             *            Indicates if the attribute presence is required.
483:             * @param format
484:             *            Format of the attribute value, using Regex pattern syntax.
485:             */
486:            public void validate(String attribute, boolean required,
487:                    String format) {
488:                getValidations().add(
489:                        new ValidateInfo(attribute, required, format));
490:            }
491:
492:            /**
493:             * Validates the attributes from the request.
494:             * 
495:             * @param request
496:             *            The request to process.
497:             * @param response
498:             *            The response to process.
499:             */
500:            private void validateAttributes(Request request, Response response) {
501:                if (this .validations != null) {
502:                    for (ValidateInfo validate : getValidations()) {
503:                        if (validate.required
504:                                && !request.getAttributes().containsKey(
505:                                        validate.attribute)) {
506:                            response
507:                                    .setStatus(
508:                                            Status.CLIENT_ERROR_BAD_REQUEST,
509:                                            "Unable to find the \""
510:                                                    + validate.attribute
511:                                                    + "\" attribute in the request. Please check your request.");
512:                        } else if (validate.format != null) {
513:                            Object value = request.getAttributes().get(
514:                                    validate.attribute);
515:                            if (value == null) {
516:                                response
517:                                        .setStatus(
518:                                                Status.CLIENT_ERROR_BAD_REQUEST,
519:                                                "Unable to validate the \""
520:                                                        + validate.attribute
521:                                                        + "\" attribute with a null value. Please check your request.");
522:                            } else {
523:                                if (!Pattern.matches(validate.format, value
524:                                        .toString())) {
525:                                    response
526:                                            .setStatus(
527:                                                    Status.CLIENT_ERROR_BAD_REQUEST,
528:                                                    "Unable to validate the value of the \""
529:                                                            + validate.attribute
530:                                                            + "\" attribute. The expected format is: "
531:                                                            + validate.format
532:                                                            + " (Java Regex). Please check your request.");
533:                                }
534:                            }
535:                        }
536:                    }
537:                }
538:            }
539:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.