001: package org.apache.turbine.modules.pages;
002:
003: /*
004: * Copyright 2001-2005 The Apache Software Foundation.
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License")
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: import java.util.List;
020:
021: import org.apache.commons.lang.StringUtils;
022: import org.apache.commons.logging.Log;
023: import org.apache.commons.logging.LogFactory;
024:
025: import org.apache.ecs.Doctype;
026:
027: import org.apache.turbine.Turbine;
028: import org.apache.turbine.TurbineConstants;
029: import org.apache.turbine.modules.ActionLoader;
030: import org.apache.turbine.modules.LayoutLoader;
031: import org.apache.turbine.modules.Page;
032: import org.apache.turbine.modules.Screen;
033: import org.apache.turbine.modules.ScreenLoader;
034: import org.apache.turbine.util.RunData;
035: import org.apache.turbine.util.TurbineException;
036:
037: /**
038: * When building sites using templates, Screens need only be defined
039: * for templates which require dynamic (database or object) data.
040: *
041: * <p>
042: *
043: * This page can be used on sites where the number of Screens can be
044: * much less than the number of templates. The templates can be
045: * grouped in directories with common layouts. Screen modules are
046: * then expected to be placed in packages corresponding with the
047: * templates' directories and follow a specific naming scheme.
048: *
049: * <p>
050: *
051: * The template parameter is parsed and and a Screen whose package
052: * matches the templates path and shares the same name minus any
053: * extension and beginning with a capital letter is searched for. If
054: * not found, a Screen in a package matching the template's path with
055: * name Default is searched for. If still not found, a Screen with
056: * name Default is looked for in packages corresponding to parent
057: * directories in the template's path until a match is found.
058: *
059: * <p>
060: *
061: * For example if data.getParameters().getString("template") returns
062: * /about_us/directions/driving.wm, the search follows
063: * about_us.directions.Driving, about_us.directions.Default,
064: * about_us.Default, Default, VelocitySiteScreen.
065: *
066: * <p>
067: *
068: * Only one Layout module is used, since it is expected that any
069: * dynamic content will be placed in navigations and screens. The
070: * layout template to be used is found in a similar way to the Screen.
071: * For example the following paths will be searched in the layouts
072: * subdirectory: /about_us/directions/driving.wm,
073: * /about_us/directions/default.wm, /about_us/default.wm, /default.wm.
074: *
075: * <p>
076: *
077: * This approach allows a site with largely static content to be
078: * updated and added to regularly by those with little Java
079: * experience.
080: *
081: * <p>
082: *
083: * The code is an almost a complete clone of the FreeMarkerSitePage
084: * written by John McNally. I've only modified it for Template use.
085: *
086: * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
087: * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
088: * @version $Id: DefaultPage.java 264148 2005-08-29 14:21:04Z henning $
089: */
090: public class DefaultPage extends Page {
091: /** Logging */
092: protected Log log = LogFactory.getLog(this .getClass());
093:
094: /**
095: * Builds the Page.
096: *
097: * @param data Turbine information.
098: * @exception Exception, a generic exception.
099: */
100: public void doBuild(RunData data) throws Exception {
101: // Template pages can use this to set up the context, so it is
102: // available to the Action and Screen. It does nothing here.
103: doBuildBeforeAction(data);
104:
105: // If an action has been defined, execute it here. Actions
106: // can re-define the template definition.
107: if (data.hasAction()) {
108: ActionLoader.getInstance().exec(data, data.getAction());
109: }
110:
111: // if a redirect was setup in data, don't do anything else
112: if (StringUtils.isNotEmpty(data.getRedirectURI())) {
113: return;
114: }
115:
116: // Set the default doctype from the value given in
117: // TurbineResources.properties.
118: setDefaultDoctype(data);
119:
120: // Template pages can use this to set up default templates and
121: // associated class modules. It does nothing here.
122: doBuildAfterAction(data);
123:
124: String screenName = data.getScreen();
125:
126: log.debug("Building " + screenName);
127:
128: // Ask the Screen for its Layout and then execute the Layout.
129: // The Screen can override the getLayout() method to re-define
130: // the Layout depending on data passed in via the
131: // data.parameters object.
132: ScreenLoader sl = ScreenLoader.getInstance();
133: Screen aScreen = sl.getInstance(screenName);
134: String layout = aScreen.getLayout(data);
135:
136: // If the Layout has been set to be null, attempt to execute
137: // the Screen that has been defined.
138: if (layout != null) {
139: LayoutLoader.getInstance().exec(data, layout);
140: } else {
141: ScreenLoader.getInstance().exec(data, screenName);
142: }
143:
144: // Do any post build actions (overridable by subclasses -
145: // does nothing here).
146: doPostBuild(data);
147: }
148:
149: /**
150: * Can be used by template Pages to stuff the Context into the
151: * RunData so that it is available to the Action module and the
152: * Screen module via getContext(). It does nothing here.
153: *
154: * @param data Turbine information.
155: * @exception Exception, a generic exception.
156: */
157: protected void doBuildBeforeAction(RunData data) throws Exception {
158: }
159:
160: /**
161: * Can be overridden by template Pages to set up data needed to
162: * process a template. It does nothing here.
163: *
164: * @param data Turbine information.
165: * @exception Exception, a generic exception.
166: */
167: protected void doBuildAfterAction(RunData data) throws Exception {
168: }
169:
170: /**
171: * Can be overridden to perform actions when the request is
172: * fully processed. It does nothing here.
173: *
174: * @param data Turbine information.
175: * @exception Exception, a generic exception.
176: */
177: protected void doPostBuild(RunData data) throws Exception {
178: }
179:
180: /**
181: * Set the default Doctype. If Doctype is set to null, it will
182: * not be added. The default Doctype can be set in
183: * TurbineResources by using the single strings: Html40Strict,
184: * Html40Transitional, or Html40Frameset. Additionally the
185: * default can be supplied as two strings giving the dtd and uri.
186: *
187: * @param data Turbine information.
188: * @exception Exception, a generic exception.
189: */
190: private void setDefaultDoctype(RunData data) throws Exception {
191: String errMsg = "default.doctype property not set properly in TurbineResources.properties!";
192: List doctypeProperty = Turbine.getConfiguration().getList(
193: TurbineConstants.DEFAULT_DOCUMENT_TYPE_KEY);
194:
195: if (doctypeProperty != null) {
196: switch (doctypeProperty.size()) {
197: case 0: {
198: // Don't add a doctype.
199: break;
200: }
201: case 1: {
202: String doc = (String) doctypeProperty.get(0);
203: if (doc
204: .equalsIgnoreCase(TurbineConstants.DOCUMENT_TYPE_HTML40TRANSITIONAL)) {
205: data.getPage().setDoctype(
206: new Doctype.Html40Transitional());
207: } else if (doc
208: .equalsIgnoreCase(TurbineConstants.DOCUMENT_TYPE_HTML40STRICT)) {
209: data.getPage().setDoctype(
210: new Doctype.Html40Strict());
211: } else if (doc
212: .equalsIgnoreCase(TurbineConstants.DOCUMENT_TYPE_HTML40FRAMESET)) {
213: data.getPage().setDoctype(
214: new Doctype.Html40Frameset());
215: } else {
216: throw new TurbineException(errMsg);
217: }
218: break;
219: }
220: case 2: {
221: data
222: .getPage()
223: .setDoctype(
224: new Doctype()
225: .setIdentifier(
226: (String) doctypeProperty
227: .get(0))
228: .setUri(
229: (String) doctypeProperty
230: .get(1)));
231: break;
232: }
233: default: {
234: throw new TurbineException(errMsg);
235: }
236: }
237: }
238: }
239: }
|