View Javadoc

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