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.service.ConnectorService;
024: import org.restlet.service.ConverterService;
025: import org.restlet.service.DecoderService;
026: import org.restlet.service.MetadataService;
027: import org.restlet.service.StatusService;
028: import org.restlet.service.TunnelService;
029: import org.restlet.util.Engine;
030: import org.restlet.util.Helper;
031:
032: /**
033: * Restlet that can be attached to one or more VirtualHosts. Applications are
034: * guaranteed to receive calls with their base reference set relatively to the
035: * VirtualHost that served them. This class is both a descriptor able to create
036: * the root Restlet and the actual Restlet that can be attached to one or more
037: * VirtualHost instances.<br>
038: * <br>
039: * Applications also have many useful Services associated. They are available as
040: * properties that can be eventually overriden:
041: * <ul>
042: * <li>"connectorService" to manage client and server connectors.</li>
043: * <li>"converterService" to convert message entities into higher-level
044: * objects.</li>
045: * <li>"decoderService" to automatically decode or decompress request entities.</li>
046: * <li>"metadataService" to provide access to metadata and their associated
047: * extension names.</li>
048: * <li>"statusService" to provide common representations for exception status.</li>
049: * <li>"tunnelService" to tunnel method names or client preferences via query
050: * parameters.</li>
051: * </ul>
052: * <br>
053: * If you need to retrieve the reference to an Application from one of its
054: * contained Restlets, you can use the {@link #KEY} constant to lookup the
055: * Context.attributes property.
056: *
057: * @author Jerome Louvel (contact@noelios.com)
058: */
059: public abstract class Application extends Restlet {
060: /**
061: * Name of the attribute key containing a reference to the current
062: * application.
063: */
064: public static final String KEY = "org.restlet.application";
065:
066: /** The display name. */
067: private String name;
068:
069: /** The description. */
070: private String description;
071:
072: /** The author(s). */
073: private String author;
074:
075: /** The owner(s). */
076: private String owner;
077:
078: /** The root Restlet. */
079: private Restlet root;
080:
081: /** The connector service. */
082: private ConnectorService connectorService;
083:
084: /** The converter service. */
085: private ConverterService converterService;
086:
087: /** The decoder service. */
088: private DecoderService decoderService;
089:
090: /** The local service. */
091: private MetadataService metadataService;
092:
093: /** The status service. */
094: private StatusService statusService;
095:
096: /** The tunnel service. */
097: private TunnelService tunnelService;
098:
099: /** The helper provided by the implementation. */
100: private Helper helper;
101:
102: /**
103: * Constructor. Note that usage of this constructor is not recommended as
104: * your application won't have access to the parent component context. For
105: * example, no dispatching will be possible as it requires access to the
106: * component's client connectors.
107: */
108: public Application() {
109: this ((Context) null);
110: }
111:
112: /**
113: * Constructor.
114: *
115: * @param parentContext
116: * The parent context. Typically the component's context.
117: */
118: public Application(Context parentContext) {
119: super (null);
120:
121: if (Engine.getInstance() != null) {
122: this .helper = Engine.getInstance().createHelper(this ,
123: parentContext);
124:
125: // Compose the logger name
126: String applicationName = (getName() == null) ? Integer
127: .toString(hashCode()) : getName();
128: String loggerName = Application.class.getCanonicalName()
129: + "." + applicationName;
130:
131: // Create the application context
132: setContext(this .helper.createContext(loggerName));
133: }
134:
135: this .name = null;
136: this .description = null;
137: this .author = null;
138: this .owner = null;
139: this .root = null;
140: this .connectorService = null;
141: this .decoderService = null;
142: this .metadataService = null;
143: this .statusService = null;
144: this .tunnelService = null;
145: }
146:
147: /**
148: * Creates a root Restlet that will receive all incoming calls. In general,
149: * instances of Router, Filter or Handler classes will be used as initial
150: * application Restlet. The default implementation returns null by default.
151: * This method is intended to be overriden by subclasses.
152: *
153: * @return The root Restlet.
154: */
155: public abstract Restlet createRoot();
156:
157: /**
158: * Returns the author(s).
159: *
160: * @return The author(s).
161: */
162: public String getAuthor() {
163: return this .author;
164: }
165:
166: /**
167: * Returns the connector service.
168: *
169: * @return The connector service.
170: */
171: public ConnectorService getConnectorService() {
172: if (this .connectorService == null)
173: this .connectorService = new ConnectorService();
174: return this .connectorService;
175: }
176:
177: /**
178: * Returns the converter service.
179: *
180: * @return The converter service.
181: */
182: public ConverterService getConverterService() {
183: if (this .converterService == null)
184: this .converterService = new ConverterService();
185: return this .converterService;
186: }
187:
188: /**
189: * Returns the decoder service. This service is enabled by default.
190: *
191: * @return The decoderservice.
192: */
193: public DecoderService getDecoderService() {
194: if (this .decoderService == null)
195: this .decoderService = new DecoderService(true);
196: return this .decoderService;
197: }
198:
199: /**
200: * Returns the description.
201: *
202: * @return The description
203: */
204: public String getDescription() {
205: return this .description;
206: }
207:
208: /**
209: * Returns the helper provided by the implementation.
210: *
211: * @return The helper provided by the implementation.
212: */
213: private Helper getHelper() {
214: return this .helper;
215: }
216:
217: /**
218: * Returns the metadata service.
219: *
220: * @return The metadata service.
221: */
222: public MetadataService getMetadataService() {
223: if (this .metadataService == null)
224: this .metadataService = new MetadataService();
225: return this .metadataService;
226: }
227:
228: /**
229: * Returns the display name.
230: *
231: * @return The display name.
232: */
233: public String getName() {
234: return this .name;
235: }
236:
237: /**
238: * Returns the owner(s).
239: *
240: * @return The owner(s).
241: */
242: public String getOwner() {
243: return this .owner;
244: }
245:
246: /**
247: * Returns the root Restlet. Invokes the createRoot() method if no Restlet
248: * exists.
249: *
250: * @return The root Restlet.
251: */
252: public Restlet getRoot() {
253: if (this .root == null) {
254: this .root = createRoot();
255: }
256:
257: return this .root;
258: }
259:
260: /**
261: * Returns the status service. This service is enabled by default.
262: *
263: * @return The status service.
264: */
265: public StatusService getStatusService() {
266: if (this .statusService == null)
267: this .statusService = new StatusService(true);
268: return this .statusService;
269: }
270:
271: /**
272: * Returns the tunnel service. This service is enabled by default.
273: *
274: * @return The tunnel service.
275: */
276: public TunnelService getTunnelService() {
277: if (this .tunnelService == null)
278: this .tunnelService = new TunnelService(true, true, true);
279: return this .tunnelService;
280: }
281:
282: /**
283: * Handles a call.
284: *
285: * @param request
286: * The request to handle.
287: * @param response
288: * The response to update.
289: */
290: public void handle(Request request, Response response) {
291: init(request, response);
292: if (getHelper() != null)
293: getHelper().handle(request, response);
294: }
295:
296: /**
297: * Sets the author(s).
298: *
299: * @param author
300: * The author(s).
301: */
302: public void setAuthor(String author) {
303: this .author = author;
304: }
305:
306: /**
307: * Sets the description.
308: *
309: * @param description
310: * The description.
311: */
312: public void setDescription(String description) {
313: this .description = description;
314: }
315:
316: /**
317: * Sets the display name.
318: *
319: * @param name
320: * The display name.
321: */
322: public void setName(String name) {
323: this .name = name;
324: }
325:
326: /**
327: * Sets the owner(s).
328: *
329: * @param owner
330: * The owner(s).
331: */
332: public void setOwner(String owner) {
333: this .owner = owner;
334: }
335:
336: @Override
337: public void start() throws Exception {
338: if (isStopped()) {
339: super .start();
340: if (getHelper() != null)
341: getHelper().start();
342: }
343: }
344:
345: @Override
346: public void stop() throws Exception {
347: if (isStarted()) {
348: if (getHelper() != null)
349: getHelper().stop();
350: super .stop();
351: }
352: }
353:
354: /**
355: * Sets the connector service.
356: *
357: * @param connectorService
358: * The connector service.
359: */
360: public void setConnectorService(ConnectorService connectorService) {
361: this .connectorService = connectorService;
362: }
363:
364: /**
365: * Sets the converter service.
366: *
367: * @param converterService
368: * The converter service.
369: */
370: public void setConverterService(ConverterService converterService) {
371: this .converterService = converterService;
372: }
373:
374: /**
375: * Sets the decoder service.
376: *
377: * @param decoderService
378: * The decoder service.
379: */
380: public void setDecoderService(DecoderService decoderService) {
381: this .decoderService = decoderService;
382: }
383:
384: /**
385: * Sets the metadata service.
386: *
387: * @param metadataService
388: * The metadata service.
389: */
390: public void setMetadataService(MetadataService metadataService) {
391: this .metadataService = metadataService;
392: }
393:
394: /**
395: * Sets the status service.
396: *
397: * @param statusService
398: * The status service.
399: */
400: public void setStatusService(StatusService statusService) {
401: this .statusService = statusService;
402: }
403:
404: /**
405: * Sets the tunnel service.
406: *
407: * @param tunnelService
408: * The tunnel service.
409: */
410: public void setTunnelService(TunnelService tunnelService) {
411: this.tunnelService = tunnelService;
412: }
413:
414: }
|