1 package org.apache.turbine.modules.pages;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
106
107 doBuildBeforeAction(data);
108
109
110
111 if (data.hasAction())
112 {
113 ActionLoader.getInstance().exec(data, data.getAction());
114 }
115
116
117 if (StringUtils.isNotEmpty(data.getRedirectURI()))
118 {
119 return;
120 }
121
122
123
124 setDefaultDoctype(data);
125
126
127
128 doBuildAfterAction(data);
129
130 String screenName = data.getScreen();
131
132 log.debug("Building " + screenName);
133
134
135
136
137
138 ScreenLoader sl = ScreenLoader.getInstance();
139 Screen aScreen = sl.getInstance(screenName);
140 String layout = aScreen.getLayout(data);
141
142
143
144 if (layout != null)
145 {
146 LayoutLoader.getInstance().exec(data, layout);
147 }
148 else
149 {
150 ScreenLoader.getInstance().exec(data, screenName);
151 }
152
153
154
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
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 }