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.lang3.StringUtils; 025import org.apache.logging.log4j.LogManager; 026import org.apache.logging.log4j.Logger; 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$ 091 */ 092public class DefaultPage implements Page 093{ 094 /** Logging */ 095 protected final Logger log = LogManager.getLogger(this.getClass()); 096 097 /** Injected loader instance */ 098 @TurbineLoader( Action.class ) 099 protected ActionLoader actionLoader; 100 101 /** Injected loader instance */ 102 @TurbineLoader( Screen.class ) 103 protected ScreenLoader screenLoader; 104 105 /** Injected loader instance */ 106 @TurbineLoader( Layout.class ) 107 protected LayoutLoader layoutLoader; 108 109 /** 110 * Builds the Page. 111 * 112 * @param pipelineData Turbine information. 113 * @throws Exception a generic exception. 114 */ 115 @Override 116 public void doBuild(PipelineData pipelineData) 117 throws Exception 118 { 119 RunData data = pipelineData.getRunData(); 120 // Template pages can use this to set up the context, so it is 121 // available to the Action and Screen. It does nothing here. 122 doBuildBeforeAction(pipelineData); 123 124 // If an action has been defined, execute it here. Actions 125 // can re-define the template definition. 126 if (data.hasAction()) 127 { 128 actionLoader.exec(pipelineData, data.getAction()); 129 } 130 131 // if a redirect was setup in data, don't do anything else 132 if (StringUtils.isNotEmpty(data.getRedirectURI())) 133 { 134 return; 135 } 136 137 // Template pages can use this to set up default templates and 138 // associated class modules. It does nothing here. 139 doBuildAfterAction(pipelineData); 140 141 String screenName = data.getScreen(); 142 143 log.debug("Building {}", screenName); 144 145 // Ask the Screen for its Layout and then execute the Layout. 146 // The Screen can override the getLayout() method to re-define 147 // the Layout depending on data passed in via the 148 // data.parameters object. 149 Screen aScreen = screenLoader.getAssembler(screenName); 150 String layout = aScreen.getLayout(pipelineData); 151 152 // If the Layout has been set to be null, attempt to execute 153 // the Screen that has been defined. 154 if (layout != null) 155 { 156 layoutLoader.exec(pipelineData, layout); 157 } 158 else 159 { 160 screenLoader.exec(pipelineData, screenName); 161 } 162 163 // Do any post build actions (overridable by subclasses - 164 // does nothing here). 165 doPostBuild(pipelineData); 166 } 167 168 /** 169 * Can be used by template Pages to stuff the Context into the 170 * PipelineData so that it is available to the Action module and the 171 * Screen module via getContext(). It does nothing here. 172 * 173 * @param pipelineData Turbine information. 174 * @throws Exception a generic exception. 175 */ 176 protected void doBuildBeforeAction(PipelineData pipelineData) 177 throws Exception 178 { 179 // do nothing by default 180 } 181 182 /** 183 * Can be overridden by template Pages to set up data needed to 184 * process a template. It does nothing here. 185 * 186 * @param pipelineData Turbine information. 187 * @throws Exception a generic exception. 188 */ 189 protected void doBuildAfterAction(PipelineData pipelineData) 190 throws Exception 191 { 192 // do nothing by default 193 } 194 195 /** 196 * Can be overridden to perform actions when the request is 197 * fully processed. It does nothing here. 198 * 199 * @param pipelineData Turbine information. 200 * @throws Exception a generic exception. 201 */ 202 protected void doPostBuild(PipelineData pipelineData) 203 throws Exception 204 { 205 // do nothing by default 206 } 207}