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; 026 027/** 028 * <h1>Web Module Extensibility.</h1> This sample is demonstrating how existing web modules can be extended. To extend 029 * another module you should use the {@code base=BaseModule} in the {@code NuxeoWebModule} directive in 030 * {@code MANIFEST.MF} file. This way the new module will inherit all templates and resources defined in the base 031 * module. You can thus create a chain of inherited web modules. 032 * <p> 033 * Here is how template resolution will be impacted by the module inheritance: <br> 034 * <i>If a template T is not found in skin directory of derived module then search the template inside the base module 035 * and so on until a template is found or no more base module exists.</i> The view resolution is similar to the template 036 * one but it will use the {@code WebObject} inheritance too: <br> 037 * <i></i> <br> 038 * <b>Note</b> that only the <i>skin</i> directory is stacked over the one in the base module. The other directories in 039 * the module are not inheritable. 040 * <p> 041 * Also, resource types defined by the base module will become visible in the derived one. 042 * <p> 043 * In this example you will also find a very useful feature of WebEngine: the builtin <b>view service adapter</b>. This 044 * adapter can be used on any web object to locate any view declared on that object. Let's say we define a view named 045 * <i>info</i> for the <i>Document</i> WebObject type. And the following request path will point to a Document 046 * WebObject: {@code /my/doc}. Then to display the <i>info</i> view we can use the builtin views adapter this way: 047 * {@code /my/doc/@views/info}. 048 * <p> 049 * Obviously, you can redefine the WebObject corresponding to your document type and add a new method that will dispatch 050 * the view <info>info</info> using a pretty path like {@code /my/doc/info}. But this involves changing code. If you 051 * don't want this then the views adapter will be your friend. 052 * <p> 053 * <p> 054 * This example will extend the resource defined in sample4 and will reuse and add more templates. Look into template 055 * files to see how base module templates are reused. 056 * <h1>Managing links.</h1> 057 * <p> 058 * Almost any template page will contain links to other pages in your application. These links are usually absolute 059 * paths to other WebObjects or WebAdapters (including parameters if any). Maintaining these links when application 060 * object changes is painful when you are using modular applications (that may contribute new views or templates). 061 * <p> 062 * WebEngine is providing a flexible way to ease link management. First, you should define all of your links in 063 * <i>module.xml</i> configuration file. A Link is described by a target URL, an enablement condition, and one or more 064 * categories that can be used to organize links. 065 * <ul> 066 * Here are the possible conditions that you can use on links: 067 * <li>type - represent the target Web Object type. If present the link will be enabled only in the context of such an 068 * object. 069 * <li>adapter - represent the target Web Adapter name. If present the link will be enabled only if the active adapter 070 * is the same as this one. 071 * <li>facet - a set of facets that the target web object must have in order to enable the link. 072 * <li>guard - a guard to be tested in order to enable the link. This is using the guard mechanism of WebEngine. 073 * </ul> 074 * If several conditions are specified an {@code AND} will be used between them. 075 * <p> 076 * Apart conditions you can <i>group</i> links in categories. Using categories and conditions you can quickly find in a 077 * template which are all enabled links that are part of a category. This way, you can control which links are written 078 * in the template without needing to do conditional code to check the context if links are enabled. 079 * <p> 080 * Conditions and categories manage thus where and when your links are displayed in a page. Apart this you also want to 081 * have a target URL for each link. 082 * <ul> 083 * You have two choices in specifying such a target URL: 084 * <li>define a custom link handler using the {@code handler</handler> link attribute.} The handler will be invoked each 085 * time the link code need to be written in the output stream so that it can programatically generate the link code. 086 * <li>use the builtin link handler. The builtin link handler will append the {@code path} attribute you specified in 087 * link definition to the current WebObject path on the request. This behavior is good enough for most of the use cases. 088 * <li> 089 * </ul> 090 * <p> 091 * <p> 092 * This example will demonstrate how links work. Look into {@code module.xml} for link definitions and then in 093 * {@code skin/views/Document/index.ftl} on how they are used in the template. 094 * 095 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 096 */ 097@WebObject(type = "Repository") 098@Produces("text/html;charset=UTF-8") 099public class ExtendedDocumentsObject extends DocumentsObject { 100 /** 101 * We are reusing bindings declared in the main class from sample5 and only add a new one. 102 */ 103 @Path("info") 104 @GET 105 public Object getInfo() { 106 return "This is the 'info' segment added by the derived module"; 107 } 108 109}