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 com.noelios.restlet.application;
020:
021: import java.util.logging.Level;
022: import java.util.logging.Logger;
023:
024: import org.restlet.Application;
025: import org.restlet.Context;
026: import org.restlet.Filter;
027: import org.restlet.Restlet;
028: import org.restlet.data.Request;
029: import org.restlet.data.Response;
030: import org.restlet.data.Status;
031: import org.restlet.service.LogService;
032: import org.restlet.util.Helper;
033:
034: import com.noelios.restlet.LogFilter;
035:
036: /**
037: * Application implementation.
038: *
039: * @author Jerome Louvel (contact@noelios.com)
040: */
041: public class ApplicationHelper extends Helper {
042: /** The application to help. */
043: private Application application;
044:
045: /** The first Restlet. */
046: private Restlet first;
047:
048: /** The last Filter. */
049: private Filter last;
050:
051: /** The parent context, typically the component's context. */
052: private Context parentContext;
053:
054: /**
055: * Constructor.
056: *
057: * @param application
058: * The application to help.
059: * @param parentContext
060: * The parent context, typically the component's context.
061: */
062: public ApplicationHelper(Application application,
063: Context parentContext) {
064: this .application = application;
065: this .parentContext = parentContext;
066: this .first = null;
067: }
068:
069: /**
070: * Creates a new context.
071: *
072: * @param loggerName
073: * The JDK's logger name to use for contextual logging.
074: * @return The new context.
075: */
076: public Context createContext(String loggerName) {
077: return new ApplicationContext(getApplication(),
078: getParentContext(), Logger.getLogger(loggerName));
079: }
080:
081: /**
082: * Allows filtering before processing by the next Restlet. Does nothing by
083: * default.
084: *
085: * @param request
086: * The request to handle.
087: * @param response
088: * The response to update.
089: */
090: public void handle(Request request, Response response) {
091: // Add the application in request and response attributes
092: request.getAttributes().put(Application.KEY, this .application);
093: response.getAttributes().put(Application.KEY, this .application);
094:
095: if (getFirst() != null) {
096: // Dispatch the call to the first Restlet
097: getFirst().handle(request, response);
098: } else {
099: response.setStatus(Status.SERVER_ERROR_INTERNAL);
100: getApplication()
101: .getLogger()
102: .log(Level.SEVERE,
103: "The application wasn't properly started, it can't handle calls.");
104: }
105: }
106:
107: /**
108: * Returns the application to help.
109: *
110: * @return The application to help.
111: */
112: public Application getApplication() {
113: return this .application;
114: }
115:
116: /**
117: * Returns the parent context, typically the component's context.
118: *
119: * @return The parent context.
120: */
121: public Context getParentContext() {
122: return this .parentContext;
123: }
124:
125: /** Start hook. */
126: public void start() throws Exception {
127: // Addition of tunnel filter
128: if (getApplication().getTunnelService().isEnabled()) {
129: addFilter(createTunnelFilter(getApplication()));
130: }
131:
132: // Addition of status pages
133: if (getApplication().getStatusService().isEnabled()) {
134: addFilter(createStatusFilter(getApplication()));
135: }
136:
137: // Addition of decoder filter
138: if (getApplication().getDecoderService().isEnabled()) {
139: addFilter(createDecoderFilter(getApplication()));
140: }
141:
142: // Attach the Application's root Restlet
143: if (getFirst() == null) {
144: setFirst(getApplication().getRoot());
145: } else {
146: getLast().setNext(getApplication().getRoot());
147: }
148: }
149:
150: /**
151: * Adds a new filter to the chain.
152: *
153: * @param filter
154: * The filter to add.
155: */
156: private void addFilter(Filter filter) {
157: if (getLast() != null) {
158: getLast().setNext(filter);
159: setLast(filter);
160: } else {
161: setFirst(filter);
162: setLast(filter);
163: }
164: }
165:
166: /**
167: * Creates a new log filter. Allows overriding.
168: *
169: * @param context
170: * The context.
171: * @param logService
172: * The log service descriptor.
173: * @return The new log filter.
174: */
175: protected Filter createLogFilter(Context context,
176: LogService logService) {
177: return new LogFilter(context, logService);
178: }
179:
180: /**
181: * Creates a new decoder filter. Allows overriding.
182: *
183: * @param application
184: * The parent application.
185: * @return The new decoder filter.
186: */
187: protected Filter createDecoderFilter(Application application) {
188: return new Decoder(application.getContext(), true, false);
189: }
190:
191: /**
192: * Creates a new status filter. Allows overriding.
193: *
194: * @param application
195: * The parent application.
196: * @return The new status filter.
197: */
198: protected Filter createStatusFilter(Application application) {
199: return new ApplicationStatusFilter(application);
200: }
201:
202: /**
203: * Creates a new tunnel filter. Allows overriding.
204: *
205: * @param application
206: * The parent application.
207: * @return The new tunnel filter.
208: */
209: protected Filter createTunnelFilter(Application application) {
210: return new TunnelFilter(application);
211: }
212:
213: /** Stop callback. */
214: public void stop() throws Exception {
215:
216: }
217:
218: /**
219: * Returns the first Restlet.
220: *
221: * @return the first Restlet.
222: */
223: private Restlet getFirst() {
224: return this .first;
225: }
226:
227: /**
228: * Sets the first Restlet.
229: *
230: * @param first
231: * The first Restlet.
232: */
233: private void setFirst(Restlet first) {
234: this .first = first;
235: }
236:
237: /**
238: * Returns the last Filter.
239: *
240: * @return the last Filter.
241: */
242: private Filter getLast() {
243: return this .last;
244: }
245:
246: /**
247: * Sets the last Filter.
248: *
249: * @param last
250: * The last Filter.
251: */
252: private void setLast(Filter last) {
253: this.last = last;
254: }
255:
256: }
|