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}