001/*
002 * (C) Copyright 2006 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Bogdan Stefanescu
018 */
019package org.nuxeo.ecm.webengine.samples;
020
021import javax.ws.rs.GET;
022import javax.ws.rs.Path;
023import javax.ws.rs.Produces;
024
025import org.nuxeo.ecm.webengine.model.WebObject;
026import org.nuxeo.ecm.webengine.model.impl.DefaultObject;
027
028/**
029 * WebEngine Object Model. This sample explains the basics of Nuxeo WebEngine Object Model.
030 * <p>
031 * <h3>Resource Model</h3> Resources are objects used to serve the request. WebEngine Resources are always stateless (a
032 * new instance is created on each request). There are three types of resources defined by WebEngine:
033 * <ul>
034 * <li>Module Resource - this is the Web Module entry point as we've seen in sample3. This is the root resource. The
035 * other type of resources are JAX-RS sub-resources. A WebModule entry point is a special kind of WebObject having as
036 * type name the module name.
037 * <li>Web Object - this represents an object that can be requested via HTTP methods. This resource is usually wrapping
038 * some internal object to expose it as a JAX-RS resource.
039 * <li>Web Adapter - this is a special kind of resource that can be used to adapt Web Objects to application-specific
040 * needs.
041 * <p>
042 * These adapters are useful to add new functionalities on Web Objects without breaking application modularity or adding
043 * new methods on resources. This is helping in creating extensible applications, in keeping the code cleaner and in
044 * focusing better on the REST approach of the application. For example let say you defined a DocumentObject which will
045 * expose documents as JAX-RS resources. A JAX-RS resources will be able to respond to any HTTP method like GET, POST,
046 * PUT, DELETE. So let say we use:
047 * <ul>
048 * <li> {@code GET} to get a view on the DocumentObject
049 * <li> {@code POST} to create a DocumentObject
050 * <li> {@code PUT} to update a document object
051 * <li> {@code DELETE} to delete a DocumentObject.
052 * </ul>
053 * But what if I want to put a lock on the document? Or to query the lock state? or to remove the lock? Or more, to
054 * create a document version? or to get a document version? A simple way is to add new methods on the DocumentObject
055 * resource that will handle requests top lock, unlock, version etc. Somethig like {@code @GET @Path("lock") getLock()}
056 * or {@code @POST @Path("lock") postLock()}. But this approach is not flexible because you cannot easily add new
057 * functionalities on existing resources in a dynamic way. And also, doing so, you will end up with a cluttered code,
058 * having many methods for each new aspect of the Web Object you need to handle. To solve this problem, WebEngine is
059 * defining Web Adapters, so that they can be used to add new functionality on existing objects. For example, to handle
060 * the lock actions on an Web Object we will define a new class LockAdapter which will implement the {@code GET},
061 * {@code POST}, {@code DELETE} methods to manage the lock functionality on the target Web Object. Adapters are
062 * specified using an '@' prefix on the segment in an HTTP request path. This is needed by WebEngine to differentiate
063 * Web Objects from Web Adapters. Thus in our lock example to request the lock adapter on an object you will use a
064 * request path of like the following: {@code GET /my/document/@lock} or {@code POST /my/document/@lock} etc.
065 * <p>
066 * When defining a Web Adapter you can specify on which type of Web Object it may be used. (this is done using
067 * annotations)
068 * </ul>
069 * All WebEngine resources have a type, a super type, an optional set of facets and an optional guard (these are
070 * declared using annotations) By using types and super types you can create hierarchies or resources, so that derived
071 * resource types will inherit attributes of the super types.
072 * <p>
073 * There is a builtin adapter that is managing Web Objects views. The adapter name is {@code @views}. You will see in
074 * the view model an example on how to use it.
075 * <p>
076 * Thus, request paths will be resolved to a resource chain usually of the form: WebModule -> WebObject -> ... ->
077 * WebObject [ -> WebAdapter ]. <br>
078 * Each of these resource objects will be <i>served</i> using the <i>sub-resource</i> mechanism of JAX-RS until the last
079 * resource is reached. The last resource will usually return a view to be rendered or a redirection response. The
080 * request resource chain is exposed by the WebContext object, so that one can programatically retrieve any resource
081 * from the chain. In a given resource chain there will be always 2 special resources: a <b>root</b> and a <b>target</b>
082 * resource The root resource is exposed in templates as the {@code Root} object and the target one as the contextual
083 * object: {@code This}. <br>
084 * <b>Note</b> that the root resource is not necessarily the first one, and the target resource is not necessarily the
085 * last one! More, the root and the target resources are never WebAdapters. They can be only WebObjects or WebModule
086 * entry points (that are aspecial kind of WebObjects).
087 * <p>
088 * The root resource is by default the module entry point (i.e. the first resource in the chain) but can be
089 * programatically set to point to any other WebObject from the chain.
090 * <p>
091 * The target resource will be always the last WebObject resource from the chain (so any trailing WebAdapters are
092 * excluded). This means in the chain: {@code /my/space/doc/@lock}, the root will be by default {@code my} which is the
093 * module entry point, and the target resource will be {@code doc}. So it means that the {@code $This} object exposed to
094 * templates (and/or views) will never points to the adapter {@code @lock} - but to the last WebObject in the chain. So
095 * when an adapter view is rendered the {@code $This} variable will point to the adapted WebObject and not to the
096 * adapter itself. In that case you can retrieve the adapter using {@code $This.activeAdapter}. This is an important
097 * aspect in order to correctly understand the behavior of the {@code $This} object exposed in templates.
098 * <p>
099 * <h3>View Model</h3> The view model is an extension of the template model we discussed in the previous sample. The
100 * difference between views and templates is that views are always attached to an Web Object. Also, the view file
101 * resolution is a bit different from template files. Templates are all living in {@code skin} directory. Views may live
102 * in two places:}
103 * <ul>
104 * <li>in the skin/views/${type-name} folders where type-name is the resource type name the view is applying on. This
105 * location will be consulted first when a view file is resolved, so it can be used by derived modules to replace views
106 * on already defined objects.
107 * <li>in the same folder (e.g. java package) as the resource class. This location is useful to defining views inside
108 * JARs along with resource classes.
109 * </ul>
110 * Another specific property of views is that they are inherited from resource super types. For example if you have a
111 * resource of type {@code Base} and a resource of type {@code Derived} then all views defined on type {@code Base}
112 * apply on type {@code Derived} too. You may override these views by redefining them on type {@code Derived} <br>
113 * Another difference between templates and views is that views may vary depending on the response media-type. A view is
114 * identified by an ID. The view file name is computed as follow:
115 *
116 * <pre>
117 * view_id + [-media_type_id] + ".ftl"
118 * </pre>
119 *
120 * The {@code media_type_id} is optional and will be empty for media-types not explicitly bound to an ID in modules.xml
121 * configuration file. For example, to dynamically change the view file corresponding to a view having the ID
122 * {@code index} when the response media-type is {@code application/atom+xml} you can define a mapping of this media
123 * type to the media_type_id {@code atom} and then you can use the file name {@code index-atom.ftl} to specify a
124 * specific index view when {@code atom} output is required.
125 *
126 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
127 */
128@WebObject(type = "Basics")
129@Produces("text/html;charset=UTF-8")
130public class BasicsObject extends DefaultObject {
131
132    /**
133     * Get the index view. The view file name is computed as follows: index[-media_type_id].ftl First the
134     * skin/views/Basics is searched for that file then the current directory. (The type of a module is the same as its
135     * name)
136     */
137    @GET
138    public Object doGet() {
139        return getView("index");
140    }
141
142    /**
143     * Get the WebObject (i.e. a JAX-RS sub-resource) bound to "users". Look into "users" directory for the UserManager
144     * WebObject. The location of WebObjects is not explictely specified by the programmer. The module directory will be
145     * automatically scanned for WebObject and WebAdapters.
146     */
147    @Path("users")
148    public Object getUserManager() {
149        // create a new instance of an WebObject which type is "UserManager" and push this object on the request chain
150        return newObject("UserManager");
151    }
152
153}