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 org.restlet.data.Request;
022: import org.restlet.data.Response;
023: import org.restlet.data.Status;
024: import org.restlet.resource.Resource;
025:
026: /**
027: * Restlet filtering calls before passing them to an attached Restlet. The
028: * purpose is to do some pre-processing or post-processing on the calls going
029: * through it before or after they are actually handled by an attached Restlet.
030: * Also note that you can attach and detach targets while handling incoming
031: * calls as the filter is ensured to be thread-safe.
032: *
033: * @author Jerome Louvel (contact@noelios.com)
034: */
035: public abstract class Filter extends Restlet {
036: /** The next Restlet. */
037: private Restlet next;
038:
039: /**
040: * Constructor.
041: */
042: public Filter() {
043: this (null);
044: }
045:
046: /**
047: * Constructor.
048: *
049: * @param context
050: * The context.
051: */
052: public Filter(Context context) {
053: this (context, null);
054: }
055:
056: /**
057: * Constructor.
058: *
059: * @param context
060: * The context.
061: * @param next
062: * The next Restlet.
063: */
064: public Filter(Context context, Restlet next) {
065: super (context);
066: this .next = next;
067: }
068:
069: /**
070: * Allows filtering after processing by the next Restlet. Does nothing by
071: * default.
072: *
073: * @param request
074: * The request to handle.
075: * @param response
076: * The response to update.
077: */
078: protected void afterHandle(Request request, Response response) {
079: // To be overriden
080: }
081:
082: /**
083: * Allows filtering before processing by the next Restlet. Does nothing by
084: * default.
085: *
086: * @param request
087: * The request to handle.
088: * @param response
089: * The response to update.
090: */
091: protected void beforeHandle(Request request, Response response) {
092: // To be overriden
093: }
094:
095: /**
096: * Handles the call by distributing it to the next Restlet.
097: *
098: * @param request
099: * The request to handle.
100: * @param response
101: * The response to update.
102: */
103: protected void doHandle(Request request, Response response) {
104: if (getNext() != null) {
105: getNext().handle(request, response);
106: } else {
107: response.setStatus(Status.CLIENT_ERROR_NOT_FOUND);
108: }
109: }
110:
111: /**
112: * Returns the next Restlet.
113: *
114: * @return The next Restlet or null.
115: */
116: public Restlet getNext() {
117: return this .next;
118: }
119:
120: /**
121: * Handles a call by first invoking the beforeHandle() method for
122: * pre-filtering, then distributing the call to the next Restlet via the
123: * doHandle() method. When the handling is completed, it finally invokes the
124: * afterHandle() method for post-filtering.
125: *
126: * @param request
127: * The request to handle.
128: * @param response
129: * The response to update.
130: */
131: public final void handle(Request request, Response response) {
132: init(request, response);
133: beforeHandle(request, response);
134: doHandle(request, response);
135: afterHandle(request, response);
136: }
137:
138: /**
139: * Indicates if there is a next Restlet.
140: *
141: * @return True if there is a next Restlet.
142: */
143: public boolean hasNext() {
144: return getNext() != null;
145: }
146:
147: /**
148: * Sets the next Restlet.
149: *
150: * @param next
151: * The next Restlet.
152: */
153: public void setNext(Restlet next) {
154: this .next = next;
155: }
156:
157: /**
158: * Sets the next Restlet as a Finder for a given Resource class. When the
159: * call is delegated to the Finder instance, a new instance of the Resource
160: * class will be created and will actually handle the request.
161: *
162: * @param targetClass
163: * The target Resource class to attach.
164: */
165: public void setNext(Class<? extends Resource> targetClass) {
166: setNext(new Finder(getContext(), targetClass));
167: }
168:
169: }
|