View Javadoc

1   package org.apache.turbine.modules.pages;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.List;
23  
24  import org.apache.commons.lang.StringUtils;
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  
28  import org.apache.ecs.Doctype;
29  
30  import org.apache.turbine.Turbine;
31  import org.apache.turbine.TurbineConstants;
32  import org.apache.turbine.modules.ActionLoader;
33  import org.apache.turbine.modules.LayoutLoader;
34  import org.apache.turbine.modules.Page;
35  import org.apache.turbine.modules.Screen;
36  import org.apache.turbine.modules.ScreenLoader;
37  import org.apache.turbine.util.RunData;
38  import org.apache.turbine.util.TurbineException;
39  
40  /***
41   * When building sites using templates, Screens need only be defined
42   * for templates which require dynamic (database or object) data.
43   *
44   * <p>
45   *
46   * This page can be used on sites where the number of Screens can be
47   * much less than the number of templates.  The templates can be
48   * grouped in directories with common layouts.  Screen modules are
49   * then expected to be placed in packages corresponding with the
50   * templates' directories and follow a specific naming scheme.
51   *
52   * <p>
53   *
54   * The template parameter is parsed and and a Screen whose package
55   * matches the templates path and shares the same name minus any
56   * extension and beginning with a capital letter is searched for.  If
57   * not found, a Screen in a package matching the template's path with
58   * name Default is searched for.  If still not found, a Screen with
59   * name Default is looked for in packages corresponding to parent
60   * directories in the template's path until a match is found.
61   *
62   * <p>
63   *
64   * For example if data.getParameters().getString("template") returns
65   * /about_us/directions/driving.wm, the search follows
66   * about_us.directions.Driving, about_us.directions.Default,
67   * about_us.Default, Default, VelocitySiteScreen.
68   *
69   * <p>
70   *
71   * Only one Layout module is used, since it is expected that any
72   * dynamic content will be placed in navigations and screens.  The
73   * layout template to be used is found in a similar way to the Screen.
74   * For example the following paths will be searched in the layouts
75   * subdirectory: /about_us/directions/driving.wm,
76   * /about_us/directions/default.wm, /about_us/default.wm, /default.wm.
77   *
78   * <p>
79   *
80   * This approach allows a site with largely static content to be
81   * updated and added to regularly by those with little Java
82   * experience.
83   *
84   * <p>
85   *
86   * The code is an almost a complete clone of the FreeMarkerSitePage
87   * written by John McNally.  I've only modified it for Template use.
88   *
89   * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
90   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
91   * @version $Id: DefaultPage.java 534527 2007-05-02 16:10:59Z tv $
92   */
93  public class DefaultPage
94      extends Page
95  {
96      /*** Logging */
97      protected Log log = LogFactory.getLog(this.getClass());
98  
99      /***
100      * Builds the Page.
101      *
102      * @param data Turbine information.
103      * @exception Exception, a generic exception.
104      */
105     public void doBuild(RunData data)
106             throws Exception
107     {
108         // Template pages can use this to set up the context, so it is
109         // available to the Action and Screen.  It does nothing here.
110         doBuildBeforeAction(data);
111 
112         // If an action has been defined, execute it here.  Actions
113         // can re-define the template definition.
114         if (data.hasAction())
115         {
116             ActionLoader.getInstance().exec(data, data.getAction());
117         }
118 
119         // if a redirect was setup in data, don't do anything else
120         if (StringUtils.isNotEmpty(data.getRedirectURI()))
121         {
122             return;
123         }
124 
125         // Set the default doctype from the value given in
126         // TurbineResources.properties.
127         setDefaultDoctype(data);
128 
129         // Template pages can use this to set up default templates and
130         // associated class modules.  It does nothing here.
131         doBuildAfterAction(data);
132 
133         String screenName = data.getScreen();
134 
135         log.debug("Building " + screenName);
136 
137         // Ask the Screen for its Layout and then execute the Layout.
138         // The Screen can override the getLayout() method to re-define
139         // the Layout depending on data passed in via the
140         // data.parameters object.
141         ScreenLoader sl = ScreenLoader.getInstance();
142         Screen aScreen = sl.getInstance(screenName);
143         String layout = aScreen.getLayout(data);
144 
145         // If the Layout has been set to be null, attempt to execute
146         // the Screen that has been defined.
147         if (layout != null)
148         {
149             LayoutLoader.getInstance().exec(data, layout);
150         }
151         else
152         {
153             ScreenLoader.getInstance().exec(data, screenName);
154         }
155 
156         // Do any post build actions (overridable by subclasses -
157         // does nothing here).
158         doPostBuild(data);
159     }
160 
161     /***
162      * Can be used by template Pages to stuff the Context into the
163      * RunData so that it is available to the Action module and the
164      * Screen module via getContext().  It does nothing here.
165      *
166      * @param data Turbine information.
167      * @exception Exception, a generic exception.
168      */
169     protected void doBuildBeforeAction(RunData data)
170             throws Exception
171     {
172     }
173 
174     /***
175      * Can be overridden by template Pages to set up data needed to
176      * process a template.  It does nothing here.
177      *
178      * @param data Turbine information.
179      * @exception Exception, a generic exception.
180      */
181     protected void doBuildAfterAction(RunData data)
182             throws Exception
183     {
184     }
185 
186     /***
187      * Can be overridden to perform actions when the request is
188      * fully processed. It does nothing here.
189      *
190      * @param data Turbine information.
191      * @exception Exception, a generic exception.
192      */
193     protected void doPostBuild(RunData data)
194             throws Exception
195     {
196     }
197 
198     /***
199      * Set the default Doctype.  If Doctype is set to null, it will
200      * not be added.  The default Doctype can be set in
201      * TurbineResources by using the single strings: Html40Strict,
202      * Html40Transitional, or Html40Frameset.  Additionally the
203      * default can be supplied as two strings giving the dtd and uri.
204      *
205      * @param data Turbine information.
206      * @exception Exception, a generic exception.
207      */
208     private void setDefaultDoctype(RunData data)
209             throws Exception
210     {
211         String errMsg =
212                 "default.doctype property not set properly in TurbineResources.properties!";
213         List doctypeProperty =
214             Turbine.getConfiguration().getList(TurbineConstants.DEFAULT_DOCUMENT_TYPE_KEY);
215 
216         if (doctypeProperty != null)
217         {
218             switch(doctypeProperty.size())
219             {
220             case 0:
221                 {
222                     // Don't add a doctype.
223                     break;
224                 }
225             case 1:
226                 {
227                     String doc = (String) doctypeProperty.get(0);
228                     if (doc.equalsIgnoreCase(TurbineConstants.DOCUMENT_TYPE_HTML40TRANSITIONAL))
229                     {
230                         data.getPage().setDoctype(new Doctype.Html40Transitional());
231                     }
232                     else if (doc.equalsIgnoreCase(TurbineConstants.DOCUMENT_TYPE_HTML40STRICT))
233                     {
234                         data.getPage().setDoctype(new Doctype.Html40Strict());
235                     }
236                     else if (doc.equalsIgnoreCase(TurbineConstants.DOCUMENT_TYPE_HTML40FRAMESET))
237                     {
238                         data.getPage().setDoctype(new Doctype.Html40Frameset());
239                     }
240                     else
241                     {
242                         throw new TurbineException(errMsg);
243                     }
244                     break;
245                 }
246             case 2:
247                 {
248                     data.getPage()
249                         .setDoctype(new Doctype()
250                                     .setIdentifier((String) doctypeProperty.get(0))
251                                     .setUri((String) doctypeProperty.get(1)));
252                     break;
253                 }
254             default:
255                 {
256                     throw new TurbineException(errMsg);
257                 }
258             }
259         }
260     }
261 }