001 package org.apache.turbine.modules.layouts; 002 003 004 /* 005 * Licensed to the Apache Software Foundation (ASF) under one 006 * or more contributor license agreements. See the NOTICE file 007 * distributed with this work for additional information 008 * regarding copyright ownership. The ASF licenses this file 009 * to you under the Apache License, Version 2.0 (the 010 * "License"); you may not use this file except in compliance 011 * with the License. You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, 016 * software distributed under the License is distributed on an 017 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 018 * KIND, either express or implied. See the License for the 019 * specific language governing permissions and limitations 020 * under the License. 021 */ 022 023 024 import java.io.StringReader; 025 026 import org.apache.commons.logging.Log; 027 import org.apache.commons.logging.LogFactory; 028 import org.apache.ecs.ConcreteElement; 029 import org.apache.fulcrum.xslt.XSLTServiceFacade; 030 import org.apache.turbine.TurbineConstants; 031 import org.apache.turbine.modules.Layout; 032 import org.apache.turbine.modules.Screen; 033 import org.apache.turbine.modules.ScreenLoader; 034 import org.apache.turbine.pipeline.PipelineData; 035 import org.apache.turbine.services.assemblerbroker.TurbineAssemblerBroker; 036 import org.apache.turbine.services.velocity.TurbineVelocity; 037 import org.apache.turbine.util.RunData; 038 import org.apache.turbine.util.template.TemplateNavigation; 039 import org.apache.velocity.context.Context; 040 041 /** 042 * This Layout module allows Velocity XML templates to be used as layouts. 043 * <br><br> 044 * Once the (XML) screen and navigation templates have been inserted into 045 * the layout template the result is transformed with a XSL stylesheet. 046 * The stylesheet (with the same name than the screen template) is loaded 047 * and executed by the XSLT service, so it is important that you correctly 048 * set up your XSLT service. If the named stylsheet does not exist the 049 * default.xsl stylesheet is executed. If default.xsl does not exist 050 * the XML is merely echoed. 051 * <br><br> 052 * Since dynamic content is supposed to be primarily located in 053 * screens and navigations there should be relatively few reasons to 054 * subclass this Layout. 055 * 056 * @author <a href="mailto:leon@opticode.co.za">Leon Messerschmidt</a> 057 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> 058 * @version $Id: VelocityXslLayout.java 1066558 2011-02-02 18:12:40Z ludwig $ 059 */ 060 public class VelocityXslLayout extends Layout 061 { 062 /** Logging */ 063 private static Log log = LogFactory.getLog(VelocityXslLayout.class); 064 065 /** The prefix for lookup up layout pages */ 066 private String prefix = Layout.PREFIX + "/"; 067 068 private ScreenLoader screenLoader; 069 070 /** 071 * Default constructor 072 */ 073 public VelocityXslLayout() 074 { 075 super(); 076 077 this.screenLoader = (ScreenLoader)TurbineAssemblerBroker.getLoader(Screen.NAME); 078 } 079 080 /** 081 * Build the layout. Also sets the ContentType and Locale headers 082 * of the HttpServletResponse object. 083 * @deprecated Use PipelineData version instead. 084 * @param data Turbine information. 085 * @exception Exception a generic exception. 086 */ 087 @Deprecated 088 @Override 089 public void doBuild(RunData data) 090 throws Exception 091 { 092 // Get the context needed by Velocity. 093 Context context = TurbineVelocity.getContext(data); 094 095 data.getResponse().setContentType("text/html"); 096 097 String screenName = data.getScreen(); 098 099 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 }