Source Code Cross Referenced for Router.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.lang.reflect.Constructor;
022:        import java.util.logging.Level;
023:
024:        import org.restlet.data.Request;
025:        import org.restlet.data.Response;
026:        import org.restlet.data.Status;
027:        import org.restlet.resource.Resource;
028:        import org.restlet.util.RouteList;
029:
030:        /**
031:         * Restlet routing calls to one of the attached routes. Each route can compute
032:         * an affinity score for each call depending on various criteria. The attach()
033:         * method allow the creation of routes based on URI patterns matching the
034:         * beginning of a the resource reference's remaining part.<br>
035:         * <br>
036:         * In addition, several routing modes are supported, implementing various
037:         * algorithms:
038:         * <ul>
039:         * <li>Best match (default)</li>
040:         * <li>First match</li>
041:         * <li>Last match</li>
042:         * <li>Random match</li>
043:         * <li>Round robin</li>
044:         * <li>Custom</li>
045:         * </ul>
046:         * <br>
047:         * Note that for routes using URI patterns will update the resource reference's
048:         * base reference during the routing if they are selected. It is also important
049:         * to know that the routing is very strict about path separators in your URI
050:         * patterns. Finally, you can modify the list of routes while handling incoming
051:         * calls as the delegation code is ensured to be thread-safe.
052:         * 
053:         * @see <a href="http://www.restlet.org/documentation/1.0/tutorial#part11">Tutorial: Routers and
054:         *      hierarchical URIs</a>
055:         * @author Jerome Louvel (contact@noelios.com)
056:         */
057:        public class Router extends Restlet {
058:            /**
059:             * Each call will be routed to the route with the best score, if the
060:             * required score is reached.
061:             */
062:            public static final int BEST = 1;
063:
064:            /**
065:             * Each call is routed to the first route if the required score is reached.
066:             * If the required score is not reached, then the route is skipped and the
067:             * next one is considered.
068:             */
069:            public static final int FIRST = 2;
070:
071:            /**
072:             * Each call will be routed to the last route if the required score is
073:             * reached. If the required score is not reached, then the route is skipped
074:             * and the previous one is considered.
075:             */
076:            public static final int LAST = 3;
077:
078:            /**
079:             * Each call is be routed to the next route target if the required score is
080:             * reached. The next route is relative to the previous call routed (round
081:             * robin mode). If the required score is not reached, then the route is
082:             * skipped and the next one is considered. If the last route is reached, the
083:             * first route will be considered.
084:             */
085:            public static final int NEXT = 4;
086:
087:            /**
088:             * Each call will be randomly routed to one of the routes that reached the
089:             * required score. If the random route selected is not a match then the
090:             * immediate next route is evaluated until one matching route is found. If
091:             * we get back to the inital random route selected with no match, then we
092:             * return null.
093:             */
094:            public static final int RANDOM = 5;
095:
096:            /**
097:             * Each call will be routed according to a custom mode.
098:             */
099:            public static final int CUSTOM = 6;
100:
101:            /** Finder class to instantiate. */
102:            private Class<? extends Finder> finderClass;
103:
104:            /** The modifiable list of routes. */
105:            private RouteList routes;
106:
107:            /** The default route tested if no other one was available. */
108:            private Route defaultRoute;
109:
110:            /** The routing mode. */
111:            private int routingMode;
112:
113:            /** The minimum score required to have a match. */
114:            private float requiredScore;
115:
116:            /**
117:             * The maximum number of attempts if no attachment could be matched on the
118:             * first attempt.
119:             */
120:            private int maxAttempts;
121:
122:            /** The delay (in milliseconds) before a new attempt. */
123:            private long retryDelay;
124:
125:            /**
126:             * Constructor. Note that usage of this constructor is not recommended as
127:             * the Router won't have a proper context set. In general you will prefer to
128:             * use the other constructor and pass it the parent application's context or
129:             * eventually the parent component's context if you don't use applications.
130:             */
131:            public Router() {
132:                this (null);
133:            }
134:
135:            /**
136:             * Constructor.
137:             * 
138:             * @param context
139:             *            The context.
140:             */
141:            public Router(Context context) {
142:                super (context);
143:                this .routes = null;
144:                this .defaultRoute = null;
145:                this .finderClass = Finder.class;
146:                this .routingMode = BEST;
147:                this .requiredScore = 0.5F;
148:                this .maxAttempts = 1;
149:                this .retryDelay = 500L;
150:            }
151:
152:            /**
153:             * Attaches a target Restlet to this router with an empty URI pattern. A new
154:             * route will be added routing to the target when any call is received.
155:             * 
156:             * @param target
157:             *            The target Restlet to attach.
158:             * @return The created route.
159:             */
160:            public Route attach(Restlet target) {
161:                return attach("", target);
162:            }
163:
164:            /**
165:             * Attaches a target Resource class to this router based on a given URI
166:             * pattern. A new route will be added routing to the target when calls with
167:             * a URI matching the pattern will be received.
168:             * 
169:             * @param uriPattern
170:             *            The URI pattern that must match the relative part of the
171:             *            resource URI.
172:             * @param targetClass
173:             *            The target Resource class to attach.
174:             * @return The created route.
175:             */
176:            public Route attach(String uriPattern,
177:                    Class<? extends Resource> targetClass) {
178:                return attach(uriPattern, createFinder(targetClass));
179:            }
180:
181:            /**
182:             * Creates a new finder instance based on the "targetClass" property.
183:             * 
184:             * @param targetClass
185:             *            The target Resource class to attach.
186:             * @return The new finder instance.
187:             */
188:            private Finder createFinder(Class<? extends Resource> targetClass) {
189:                Finder result = null;
190:
191:                if (getFinderClass() != null) {
192:                    try {
193:                        Constructor<? extends Finder> constructor = getFinderClass()
194:                                .getConstructor(Context.class, Class.class);
195:
196:                        if (constructor != null) {
197:                            result = constructor.newInstance(getContext(),
198:                                    targetClass);
199:                        }
200:                    } catch (Exception e) {
201:                        getLogger().log(Level.WARNING,
202:                                "Exception while instantiating the finder.", e);
203:                    }
204:                }
205:
206:                return result;
207:            }
208:
209:            /**
210:             * Attaches a target Restlet to this router based on a given URI pattern. A
211:             * new route will be added routing to the target when calls with a URI
212:             * matching the pattern will be received.
213:             * 
214:             * @param uriPattern
215:             *            The URI pattern that must match the relative part of the
216:             *            resource URI.
217:             * @param target
218:             *            The target Restlet to attach.
219:             * @return The created route.
220:             */
221:            public Route attach(String uriPattern, Restlet target) {
222:                Route result = createRoute(uriPattern, target);
223:                getRoutes().add(result);
224:                return result;
225:            }
226:
227:            /**
228:             * Attaches a Resource class to this router as the default target to invoke
229:             * when no route matches. It actually sets a default route that scores all
230:             * calls to 1.0.
231:             * 
232:             * @param defaultTargetClass
233:             *            The target Resource class to attach.
234:             * @return The created route.
235:             */
236:            public Route attachDefault(
237:                    Class<? extends Resource> defaultTargetClass) {
238:                return attachDefault(createFinder(defaultTargetClass));
239:            }
240:
241:            /**
242:             * Attaches a Restlet to this router as the default target to invoke when no
243:             * route matches. It actually sets a default route that scores all calls to
244:             * 1.0.
245:             * 
246:             * @param defaultTarget
247:             *            The Restlet to use as the default target.
248:             * @return The created route.
249:             */
250:            public Route attachDefault(Restlet defaultTarget) {
251:                Route result = createRoute("", defaultTarget);
252:                setDefaultRoute(result);
253:                return result;
254:            }
255:
256:            /**
257:             * Creates a new route for the given URI pattern and target.
258:             * 
259:             * @param uriPattern
260:             *            The URI pattern that must match the relative part of the
261:             *            resource URI.
262:             * @param target
263:             *            The target Restlet to attach.
264:             * @return The created route.
265:             */
266:            protected Route createRoute(String uriPattern, Restlet target) {
267:                return new Route(this , uriPattern, target);
268:            }
269:
270:            /**
271:             * Detaches the target from this router. All routes routing to this target
272:             * Restlet are removed from the list of routes and the default route is set
273:             * to null.
274:             * 
275:             * @param target
276:             *            The target Restlet to detach.
277:             */
278:            public void detach(Restlet target) {
279:                getRoutes().removeAll(target);
280:                if ((getDefaultRoute() != null)
281:                        && (getDefaultRoute().getNext() == target))
282:                    setDefaultRoute(null);
283:            }
284:
285:            /**
286:             * Returns the matched route according to a custom algorithm. To use in
287:             * combination of the RouterMode.CUSTOM enumeration. The default
288:             * implementation (to be overriden), returns null.
289:             * 
290:             * @param request
291:             *            The request to handle.
292:             * @param response
293:             *            The response to update.
294:             * @return The matched route if available or null.
295:             */
296:            protected Route getCustom(Request request, Response response) {
297:                return null;
298:            }
299:
300:            /**
301:             * Returns the default route to test if no other one was available after
302:             * retrying the maximum number of attemps.
303:             * 
304:             * @return The default route tested if no other one was available.
305:             */
306:            public Route getDefaultRoute() {
307:                return this .defaultRoute;
308:            }
309:
310:            /**
311:             * Returns the maximum number of attempts if no attachment could be matched
312:             * on the first attempt. This is useful when the attachment scoring is
313:             * dynamic and therefore could change on a retry. The default value is set
314:             * to 1.
315:             * 
316:             * @return The maximum number of attempts if no attachment could be matched
317:             *         on the first attempt.
318:             */
319:            public int getMaxAttempts() {
320:                return this .maxAttempts;
321:            }
322:
323:            /**
324:             * Returns the next Restlet if available.
325:             * 
326:             * @param request
327:             *            The request to handle.
328:             * @param response
329:             *            The response to update.
330:             * @return The next Restlet if available or null.
331:             */
332:            public Restlet getNext(Request request, Response response) {
333:                Route result = null;
334:
335:                for (int i = 0; (result == null) && (i < getMaxAttempts()); i++) {
336:                    if (i > 0) {
337:                        // Before attempting another time, let's
338:                        // sleep during the "retryDelay" set.
339:                        try {
340:                            Thread.sleep(getRetryDelay());
341:                        } catch (InterruptedException e) {
342:                        }
343:                    }
344:
345:                    if (this .routes != null) {
346:                        // Select the routing mode
347:                        switch (getRoutingMode()) {
348:                        case BEST:
349:                            result = getRoutes().getBest(request, response,
350:                                    getRequiredScore());
351:                            break;
352:
353:                        case FIRST:
354:                            result = getRoutes().getFirst(request, response,
355:                                    getRequiredScore());
356:                            break;
357:
358:                        case LAST:
359:                            result = getRoutes().getLast(request, response,
360:                                    getRequiredScore());
361:                            break;
362:
363:                        case NEXT:
364:                            result = getRoutes().getNext(request, response,
365:                                    getRequiredScore());
366:                            break;
367:
368:                        case RANDOM:
369:                            result = getRoutes().getRandom(request, response,
370:                                    getRequiredScore());
371:                            break;
372:
373:                        case CUSTOM:
374:                            result = getCustom(request, response);
375:                            break;
376:                        }
377:                    }
378:                }
379:
380:                if (result == null) {
381:                    // If nothing matched in the routes list, check the default
382:                    // route
383:                    if ((getDefaultRoute() != null)
384:                            && (getDefaultRoute().score(request, response) >= getRequiredScore())) {
385:                        result = getDefaultRoute();
386:                    } else {
387:                        // No route could be found
388:                        response.setStatus(Status.CLIENT_ERROR_NOT_FOUND);
389:                    }
390:                }
391:
392:                return result;
393:            }
394:
395:            /**
396:             * Returns the minimum score required to have a match.
397:             * 
398:             * @return The minimum score required to have a match.
399:             */
400:            public float getRequiredScore() {
401:                return this .requiredScore;
402:            }
403:
404:            /**
405:             * Returns the delay (in seconds) before a new attempt. The default value is
406:             * 500 ms.
407:             * 
408:             * @return The delay (in seconds) before a new attempt.
409:             */
410:            public long getRetryDelay() {
411:                return this .retryDelay;
412:            }
413:
414:            /**
415:             * Returns the modifiable list of routes.
416:             * 
417:             * @return The modifiable list of routes.
418:             */
419:            public RouteList getRoutes() {
420:                if (this .routes == null)
421:                    this .routes = new RouteList();
422:                return this .routes;
423:            }
424:
425:            /**
426:             * Returns the routing mode.
427:             * 
428:             * @return The routing mode.
429:             */
430:            public int getRoutingMode() {
431:                return this .routingMode;
432:            }
433:
434:            /**
435:             * Handles a call by invoking the next Restlet if it is available.
436:             * 
437:             * @param request
438:             *            The request to handle.
439:             * @param response
440:             *            The response to update.
441:             */
442:            public void handle(Request request, Response response) {
443:                init(request, response);
444:
445:                Restlet next = getNext(request, response);
446:                if (next != null) {
447:                    next.handle(request, response);
448:                } else {
449:                    response.setStatus(Status.CLIENT_ERROR_NOT_FOUND);
450:                }
451:            }
452:
453:            /**
454:             * Sets the default route tested if no other one was available.
455:             * 
456:             * @param defaultRoute
457:             *            The default route tested if no other one was available.
458:             */
459:            public void setDefaultRoute(Route defaultRoute) {
460:                this .defaultRoute = defaultRoute;
461:            }
462:
463:            /**
464:             * Sets the maximum number of attempts if no attachment could be matched on
465:             * the first attempt. This is useful when the attachment scoring is dynamic
466:             * and therefore could change on a retry.
467:             * 
468:             * @param maxAttempts
469:             *            The maximum number of attempts.
470:             */
471:            public void setMaxAttempts(int maxAttempts) {
472:                this .maxAttempts = maxAttempts;
473:            }
474:
475:            /**
476:             * Sets the score required to have a match.
477:             * 
478:             * @param score
479:             *            The score required to have a match.
480:             */
481:            public void setRequiredScore(float score) {
482:                this .requiredScore = score;
483:            }
484:
485:            /**
486:             * Sets the delay (in seconds) before a new attempt.
487:             * 
488:             * @param retryDelay
489:             *            The delay (in seconds) before a new attempt.
490:             */
491:            public void setRetryDelay(long retryDelay) {
492:                this .retryDelay = retryDelay;
493:            }
494:
495:            /**
496:             * Sets the routing mode.
497:             * 
498:             * @param routingMode
499:             *            The routing mode.
500:             */
501:            public void setRoutingMode(int routingMode) {
502:                this .routingMode = routingMode;
503:            }
504:
505:            /**
506:             * Returns the finder class to instantiate.
507:             * 
508:             * @return the finder class to instantiate.
509:             */
510:            public Class<? extends Finder> getFinderClass() {
511:                return this .finderClass;
512:            }
513:
514:            /**
515:             * Sets the finder class to instantiate.
516:             * 
517:             * @param finderClass
518:             *            The finder class to instantiate.
519:             */
520:            public void setFinderClass(Class<? extends Finder> finderClass) {
521:                this.finderClass = finderClass;
522:            }
523:
524:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.