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
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
109
110 doBuildBeforeAction(data);
111
112
113
114 if (data.hasAction())
115 {
116 ActionLoader.getInstance().exec(data, data.getAction());
117 }
118
119
120 if (StringUtils.isNotEmpty(data.getRedirectURI()))
121 {
122 return;
123 }
124
125
126
127 setDefaultDoctype(data);
128
129
130
131 doBuildAfterAction(data);
132
133 String screenName = data.getScreen();
134
135 log.debug("Building " + screenName);
136
137
138
139
140
141 ScreenLoader sl = ScreenLoader.getInstance();
142 Screen aScreen = sl.getInstance(screenName);
143 String layout = aScreen.getLayout(data);
144
145
146
147 if (layout != null)
148 {
149 LayoutLoader.getInstance().exec(data, layout);
150 }
151 else
152 {
153 ScreenLoader.getInstance().exec(data, screenName);
154 }
155
156
157
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
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 }