001package org.apache.turbine.modules.pages; 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 024import org.apache.commons.lang.StringUtils; 025import org.apache.commons.logging.Log; 026import org.apache.commons.logging.LogFactory; 027import org.apache.turbine.annotation.TurbineLoader; 028import org.apache.turbine.modules.Action; 029import org.apache.turbine.modules.ActionLoader; 030import org.apache.turbine.modules.Layout; 031import org.apache.turbine.modules.LayoutLoader; 032import org.apache.turbine.modules.Page; 033import org.apache.turbine.modules.Screen; 034import org.apache.turbine.modules.ScreenLoader; 035import org.apache.turbine.pipeline.PipelineData; 036import org.apache.turbine.util.RunData; 037 038/** 039 * When building sites using templates, Screens need only be defined 040 * for templates which require dynamic (database or object) data. 041 * 042 * <p> 043 * 044 * This page can be used on sites where the number of Screens can be 045 * much less than the number of templates. The templates can be 046 * grouped in directories with common layouts. Screen modules are 047 * then expected to be placed in packages corresponding with the 048 * templates' directories and follow a specific naming scheme. 049 * 050 * <p> 051 * 052 * The template parameter is parsed and and a Screen whose package 053 * matches the templates path and shares the same name minus any 054 * extension and beginning with a capital letter is searched for. If 055 * not found, a Screen in a package matching the template's path with 056 * name Default is searched for. If still not found, a Screen with 057 * name Default is looked for in packages corresponding to parent 058 * directories in the template's path until a match is found. 059 * 060 * <p> 061 * 062 * For example if data.getParameters().getString("template") returns 063 * /about_us/directions/driving.wm, the search follows 064 * about_us.directions.Driving, about_us.directions.Default, 065 * about_us.Default, Default, VelocitySiteScreen. 066 * 067 * <p> 068 * 069 * Only one Layout module is used, since it is expected that any 070 * dynamic content will be placed in navigations and screens. The 071 * layout template to be used is found in a similar way to the Screen. 072 * For example the following paths will be searched in the layouts 073 * subdirectory: /about_us/directions/driving.wm, 074 * /about_us/directions/default.wm, /about_us/default.wm, /default.wm. 075 * 076 * <p> 077 * 078 * This approach allows a site with largely static content to be 079 * updated and added to regularly by those with little Java 080 * experience. 081 * 082 * <p> 083 * 084 * The code is an almost a complete clone of the FreeMarkerSitePage 085 * written by John McNally. I've only modified it for Template use. 086 * 087 * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a> 088 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> 089 * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a> 090 * @version $Id: DefaultPage.java 1709648 2015-10-20 17:08:10Z tv $ 091 */ 092public class DefaultPage 093 extends Page 094{ 095 /** Logging */ 096 protected Log log = LogFactory.getLog(this.getClass()); 097 098 /** Injected loader instance */ 099 @TurbineLoader( Action.class ) 100 protected ActionLoader actionLoader; 101 102 /** Injected loader instance */ 103 @TurbineLoader( Screen.class ) 104 protected ScreenLoader screenLoader; 105 106 /** Injected loader instance */ 107 @TurbineLoader( Layout.class ) 108 protected LayoutLoader layoutLoader; 109 110 /** 111 * Builds the Page. 112 * 113 * @param pipelineData Turbine information. 114 * @exception Exception, a generic exception. 115 */ 116 @Override 117 public void doBuild(PipelineData pipelineData) 118 throws Exception 119 { 120 RunData data = getRunData(pipelineData); 121 // Template pages can use this to set up the context, so it is 122 // available to the Action and Screen. It does nothing here. 123 doBuildBeforeAction(pipelineData); 124 125 // If an action has been defined, execute it here. Actions 126 // can re-define the template definition. 127 if (data.hasAction()) 128 { 129 actionLoader.exec(pipelineData, data.getAction()); 130 } 131 132 // if a redirect was setup in data, don't do anything else 133 if (StringUtils.isNotEmpty(data.getRedirectURI())) 134 { 135 return; 136 } 137 138 // Template pages can use this to set up default templates and 139 // associated class modules. It does nothing here. 140 doBuildAfterAction(pipelineData); 141 142 String screenName = data.getScreen(); 143 144 log.debug("Building " + screenName); 145 146 // Ask the Screen for its Layout and then execute the Layout. 147 // The Screen can override the getLayout() method to re-define 148 // the Layout depending on data passed in via the 149 // data.parameters object. 150 Screen aScreen = screenLoader.getAssembler(screenName); 151 String layout = aScreen.getLayout(pipelineData); 152 153 // If the Layout has been set to be null, attempt to execute 154 // the Screen that has been defined. 155 if (layout != null) 156 { 157 layoutLoader.exec(pipelineData, layout); 158 } 159 else 160 { 161 screenLoader.exec(pipelineData, screenName); 162 } 163 164 // Do any post build actions (overridable by subclasses - 165 // does nothing here). 166 doPostBuild(pipelineData); 167 } 168 169 /** 170 * Can be used by template Pages to stuff the Context into the 171 * PipelineData so that it is available to the Action module and the 172 * Screen module via getContext(). It does nothing here. 173 * 174 * @param pipelineData Turbine information. 175 * @exception Exception, a generic exception. 176 */ 177 protected void doBuildBeforeAction(PipelineData pipelineData) 178 throws Exception 179 { 180 // do nothing by default 181 } 182 183 /** 184 * Can be overridden by template Pages to set up data needed to 185 * process a template. It does nothing here. 186 * 187 * @param pipelineData Turbine information. 188 * @exception Exception, a generic exception. 189 */ 190 protected void doBuildAfterAction(PipelineData pipelineData) 191 throws Exception 192 { 193 // do nothing by default 194 } 195 196 /** 197 * Can be overridden to perform actions when the request is 198 * fully processed. It does nothing here. 199 * 200 * @param pipelineData Turbine information. 201 * @exception Exception, a generic exception. 202 */ 203 protected void doPostBuild(PipelineData pipelineData) 204 throws Exception 205 { 206 // do nothing by default 207 } 208}