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