View Javadoc

1   package org.apache.turbine.modules.layouts;
2   
3   
4   /*
5    * Licensed to the Apache Software Foundation (ASF) under one
6    * or more contributor license agreements.  See the NOTICE file
7    * distributed with this work for additional information
8    * regarding copyright ownership.  The ASF licenses this file
9    * to you under the Apache License, Version 2.0 (the
10   * "License"); you may not use this file except in compliance
11   * with the License.  You may obtain a copy of the License at
12   *
13   *   http://www.apache.org/licenses/LICENSE-2.0
14   *
15   * Unless required by applicable law or agreed to in writing,
16   * software distributed under the License is distributed on an
17   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18   * KIND, either express or implied.  See the License for the
19   * specific language governing permissions and limitations
20   * under the License.
21   */
22  
23  
24  import java.io.StringReader;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  import org.apache.ecs.ConcreteElement;
29  import org.apache.fulcrum.xslt.XSLTServiceFacade;
30  import org.apache.turbine.TurbineConstants;
31  import org.apache.turbine.modules.Layout;
32  import org.apache.turbine.modules.Screen;
33  import org.apache.turbine.modules.ScreenLoader;
34  import org.apache.turbine.pipeline.PipelineData;
35  import org.apache.turbine.services.assemblerbroker.TurbineAssemblerBroker;
36  import org.apache.turbine.services.velocity.TurbineVelocity;
37  import org.apache.turbine.util.RunData;
38  import org.apache.turbine.util.template.TemplateNavigation;
39  import org.apache.velocity.context.Context;
40  
41  /**
42   * This Layout module allows Velocity XML templates to be used as layouts.
43   * <br><br>
44   * Once the (XML) screen and navigation templates have been inserted into
45   * the layout template the result is transformed with a XSL stylesheet.
46   * The stylesheet (with the same name than the screen template) is loaded
47   * and executed by the XSLT service, so it is important that you correctly
48   * set up your XSLT service.  If the named stylsheet does not exist the
49   * default.xsl stylesheet is executed.  If default.xsl does not exist
50   * the XML is merely echoed.
51   * <br><br>
52   * Since dynamic content is supposed to be primarily located in
53   * screens and navigations there should be relatively few reasons to
54   * subclass this Layout.
55   *
56   * @author <a href="mailto:leon@opticode.co.za">Leon Messerschmidt</a>
57   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
58   * @version $Id: VelocityXslLayout.java 1066558 2011-02-02 18:12:40Z ludwig $
59   */
60  public class VelocityXslLayout extends Layout
61  {
62      /** Logging */
63      private static Log log = LogFactory.getLog(VelocityXslLayout.class);
64  
65      /** The prefix for lookup up layout pages */
66      private String prefix = Layout.PREFIX + "/";
67  
68      private ScreenLoader screenLoader;
69  
70      /**
71       * Default constructor
72       */
73      public VelocityXslLayout()
74      {
75          super();
76  
77          this.screenLoader = (ScreenLoader)TurbineAssemblerBroker.getLoader(Screen.NAME);
78      }
79  
80      /**
81       * Build the layout.  Also sets the ContentType and Locale headers
82       * of the HttpServletResponse object.
83       * @deprecated Use PipelineData version instead.
84       * @param data Turbine information.
85       * @exception Exception a generic exception.
86       */
87      @Deprecated
88      @Override
89      public void doBuild(RunData data)
90          throws Exception
91      {
92          // Get the context needed by Velocity.
93          Context context = TurbineVelocity.getContext(data);
94  
95          data.getResponse().setContentType("text/html");
96  
97          String screenName = data.getScreen();
98  
99          log.debug("Loading Screen " + screenName);
100 
101         // First, generate the screen and put it in the context so
102         // we can grab it the layout template.
103         ConcreteElement results =
104             screenLoader.eval(data, screenName);
105 
106         String returnValue = (results == null) ? "" : results.toString();
107 
108         // variable for the screen in the layout template
109         context.put(TurbineConstants.SCREEN_PLACEHOLDER, returnValue);
110 
111         // variable to reference the navigation screen in the layout template
112         context.put(TurbineConstants.NAVIGATION_PLACEHOLDER,
113                     new TemplateNavigation(data));
114 
115         // Grab the layout template set in the VelocityPage.
116         // If null, then use the default layout template
117         // (done by the TemplateInfo object)
118         String templateName = data.getTemplateInfo().getLayoutTemplate();
119 
120         log.debug("Now trying to render layout " + templateName);
121 
122         // Now, generate the layout template.
123         String temp = TurbineVelocity.handleRequest(context,
124                 prefix + templateName);
125 
126         // Finally we do a transformation and send the result
127         // back to the browser
128         XSLTServiceFacade.transform(
129             data.getTemplateInfo().getScreenTemplate(),
130                 new StringReader(temp), data.getResponse().getWriter());
131     }
132 
133     /**
134      * Build the layout.  Also sets the ContentType and Locale headers
135      * of the HttpServletResponse object.
136      *
137      * @param data Turbine information.
138      * @exception Exception a generic exception.
139      */
140     @Override
141     public void doBuild(PipelineData pipelineData)
142         throws Exception
143     {
144         RunData data = getRunData(pipelineData);
145         // Get the context needed by Velocity.
146         Context context = TurbineVelocity.getContext(pipelineData);
147 
148         data.getResponse().setContentType("text/html");
149 
150         String screenName = data.getScreen();
151 
152         log.debug("Loading Screen " + screenName);
153 
154         // First, generate the screen and put it in the context so
155         // we can grab it the layout template.
156         ConcreteElement results =
157             screenLoader.eval(pipelineData, screenName);
158 
159         String returnValue = (results == null) ? "" : results.toString();
160 
161         // variable for the screen in the layout template
162         context.put(TurbineConstants.SCREEN_PLACEHOLDER, returnValue);
163 
164         // variable to reference the navigation screen in the layout template
165         context.put(TurbineConstants.NAVIGATION_PLACEHOLDER,
166                     new TemplateNavigation(data));
167 
168         // Grab the layout template set in the VelocityPage.
169         // If null, then use the default layout template
170         // (done by the TemplateInfo object)
171         String templateName = data.getTemplateInfo().getLayoutTemplate();
172 
173         log.debug("Now trying to render layout " + templateName);
174 
175         // Now, generate the layout template.
176         String temp = TurbineVelocity.handleRequest(context,
177                 prefix + templateName);
178 
179         // Finally we do a transformation and send the result
180         // back to the browser
181         XSLTServiceFacade.transform(
182             data.getTemplateInfo().getScreenTemplate(),
183                 new StringReader(temp), data.getResponse().getWriter());
184     }
185 }