Clover coverage report - brownies library - 1.0-beta-1 Coverage timestamp: 月 8 16 2004 17:14:42 GMT+09:00 FRAMES NO FRAMES |
file stats: | LOC: | 386 |  | Methods: | 11
| NCLOC: | 172 |  | Classes: | 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
Source file | Conditionals | Statements | Methods | TOTAL
ExBody.java | 0% | 0% | 0% | 0% |

1 |  |
     /*
2 |  |
      * Joey and its relative products are published under the terms
3 |  |
      * of the Apache Software License.
4 |  |
      */
5 |  |
     /*
6 |  |
      * Created on 2004/01/07
7 |  |
      */
8 |  |
     package org.asyrinx.brownie.tapestry.components.html;
9 |  |
10 |  |
     import java.util.ArrayList;
11 |  |
     import java.util.HashMap;
12 |  |
     import java.util.List;
13 |  |
     import java.util.Map;
14 |  |
15 |  |
     import org.apache.tapestry.ApplicationRuntimeException;
16 |  |
     import org.apache.tapestry.IMarkupWriter;
17 |  |
     import org.apache.tapestry.IRequestCycle;
18 |  |
     import org.apache.tapestry.IResourceLocation;
19 |  |
     import org.apache.tapestry.Tapestry;
20 |  |
     import org.apache.tapestry.asset.PrivateAsset;
21 |  |
     import org.apache.tapestry.html.Body;
22 |  |
     import org.apache.tapestry.html.Rollover;
23 |  |
     import org.apache.tapestry.html.Script;
24 |  |
     import org.apache.tapestry.resource.ClasspathResourceLocation;
25 |  |
     import org.apache.tapestry.util.IdAllocator;
26 |  |
     import org.asyrinx.brownie.tapestry.script.IFinalizableScriptProcessor;
27 |  |
28 |  |
     /**
29 |  |
      * @author akima
30 |  |
      */
31 |  |
     public abstract class ExBody extends Body implements
32 |  |
             IFinalizableScriptProcessor {
33 |  |
34 |  |
         // Lines that belong inside the onLoad event handler for the <body> tag.
35 |  |
         private StringBuffer _initializationScript;
36 |  |
37 |  |
         // Lines that belong inside the onUnload event handler for the <body> tag.
38 |  |
         private StringBuffer _finalizationScript;
39 |  |
40 |  |
         // The writer initially passed to render() ... wrapped elements render
41 |  |
         // into a nested response writer.
42 |  |
43 |  |
         private IMarkupWriter _outerWriter;
44 |  |
45 |  |
         // Any other scripting desired
46 |  |
47 |  |
         private StringBuffer _bodyScript;
48 |  |
49 |  |
         // Contains text lines related to image initializations
50 |  |
51 |  |
         private StringBuffer _imageInitializations;
52 |  |
53 |  |
         /**
54 |  |
          * Map of URLs to Strings (preloaded image references).
55 |  |
          *
56 |  |
          */
57 |  |
58 |  |
         private Map _imageMap;
59 |  |
60 |  |
         /**
61 |  |
          * List of included scripts. Values are Strings.
62 |  |
          *
63 |  |
          * @since 1.0.5
64 |  |
          *
65 |  |
          */
66 |  |
67 |  |
         private List _externalScripts;
68 |  |
69 |  |
         private IdAllocator _idAllocator;
70 |  |
71 |  |
         private static final String ATTRIBUTE_NAME = "org.apache.tapestry.active.Body";
72 |  |
73 |  |
         /**
74 |  |
          * Tracks a particular preloaded image.
75 |  |
          *
76 |  |
          */
77 |  |
78 |  |
         /**
79 |  |
          * Adds to the script an initialization for the named variable as an
80 |  |
          * Image(), to the given URL.
81 |  |
          *
82 |  |
          * <p>
83 |  |
          * Returns a reference, a string that can be used to represent the preloaded
84 |  |
          * image in a JavaScript function.
85 |  |
          *
86 |  |
          * @since 1.0.2
87 |  |
          */
88 |  |
89 | 0 |
         public String getPreloadedImageReference(String URL) {
90 | 0 |
             if (_imageMap == null)
91 | 0 |
                 _imageMap = new HashMap();
92 |  |
93 | 0 |
             String reference = (String) _imageMap.get(URL);
94 |  |
95 | 0 |
             if (reference == null) {
96 | 0 |
                 int count = _imageMap.size();
97 | 0 |
                 String varName = "tapestry_preload[" + count + "]";
98 | 0 |
                 reference = varName + ".src";
99 |  |
100 | 0 |
                 if (_imageInitializations == null)
101 | 0 |
                     _imageInitializations = new StringBuffer();
102 |  |
103 | 0 |
                 _imageInitializations.append("  ");
104 | 0 |
                 _imageInitializations.append(varName);
105 | 0 |
                 _imageInitializations.append(" = new Image();\n");
106 | 0 |
                 _imageInitializations.append("  ");
107 | 0 |
                 _imageInitializations.append(reference);
108 | 0 |
                 _imageInitializations.append(" = \"");
109 | 0 |
                 _imageInitializations.append(URL);
110 | 0 |
                 _imageInitializations.append("\";\n");
111 |  |
112 | 0 |
                 _imageMap.put(URL, reference);
113 |  |
             }
114 |  |
115 | 0 |
             return reference;
116 |  |
         }
117 |  |
118 |  |
         /**
119 |  |
          * Adds other initialization, in the form of additional JavaScript code to
120 |  |
          * execute from the &lt;body&gt;'s <code>onLoad</code> event handler. The
121 |  |
          * caller is responsible for adding a semicolon (statement terminator). This
122 |  |
          * method will add a newline after the script.
123 |  |
          *
124 |  |
          */
125 |  |
126 | 0 |
         public void addInitializationScript(String script) {
127 | 0 |
             if (_initializationScript == null)
128 | 0 |
                 _initializationScript = new StringBuffer(script.length() + 1);
129 |  |
130 | 0 |
             _initializationScript.append(script);
131 | 0 |
             _initializationScript.append('\n');
132 |  |
133 |  |
         }
134 |  |
135 |  |
         /**
136 |  |
          * Adds other finalization, in the form of additional JavaScript code to
137 |  |
          * execute from the &lt;body&gt;'s <code>onUnload</code> event handler.
138 |  |
          * The caller is responsible for adding a semicolon (statement terminator).
139 |  |
          * This method will add a newline after the script.
140 |  |
          *
141 |  |
          */
142 |  |
143 | 0 |
         public void addFinalizationScript(String script) {
144 | 0 |
             if (_finalizationScript == null)
145 | 0 |
                 _finalizationScript = new StringBuffer(script.length() + 1);
146 |  |
147 | 0 |
             _finalizationScript.append(script);
148 | 0 |
             _finalizationScript.append('\n');
149 |  |
150 |  |
         }
151 |  |
152 |  |
         /**
153 |  |
          * Adds additional scripting code to the page. This code will be added to a
154 |  |
          * large block of scripting code at the top of the page (i.e., the before
155 |  |
          * the &lt;body&gt; tag).
156 |  |
          *
157 |  |
          * <p>
158 |  |
          * This is typically used to add some form of JavaScript event handler to a
159 |  |
          * page. For example, the {@link Rollover}component makes use of this.
160 |  |
          *
161 |  |
          * <p>
162 |  |
          * Another way this is invoked is by using the {@link Script}component.
163 |  |
          *
164 |  |
          * <p>
165 |  |
          * The string will be added, as-is, within the &lt;script&gt; block
166 |  |
          * generated by this <code>Body</code> component. The script should
167 |  |
          * <em>not</em> contain HTML comments, those will be supplied by this Body
168 |  |
          * component.
169 |  |
          *
170 |  |
          * <p>
171 |  |
          * A frequent use is to add an initialization function using this method,
172 |  |
          * then cause it to be executed using
173 |  |
          * {@link #addOtherInitialization(String)}.
174 |  |
          *
175 |  |
          */
176 |  |
177 | 0 |
         public void addBodyScript(String script) {
178 | 0 |
             if (_bodyScript == null)
179 | 0 |
                 _bodyScript = new StringBuffer(script.length());
180 |  |
181 | 0 |
             _bodyScript.append(script);
182 |  |
         }
183 |  |
184 |  |
         /**
185 |  |
          * Used to include a script from an outside URL (the scriptLocation is a
186 |  |
          * URL, probably obtained from an asset. This adds an &lt;script
187 |  |
          * src="..."&gt; tag before the main &lt;script&gt; tag. The Body component
188 |  |
          * ensures that each URL is included only once.
189 |  |
          *
190 |  |
          * @since 1.0.5
191 |  |
          *
192 |  |
          */
193 |  |
194 | 0 |
         public void addExternalScript(IResourceLocation scriptLocation) {
195 | 0 |
             if (_externalScripts == null)
196 | 0 |
                 _externalScripts = new ArrayList();
197 |  |
198 | 0 |
             if (_externalScripts.contains(scriptLocation))
199 | 0 |
                 return;
200 |  |
201 |  |
             // Alas, this won't give a good ILocation for the actual problem.
202 |  |
203 | 0 |
             if (!(scriptLocation instanceof ClasspathResourceLocation))
204 | 0 |
                 throw new ApplicationRuntimeException(
205 |  |
                         "Body.include-classpath-script-only", this, null, null);
206 |  |
207 |  |
             // Record the URL so we don't include it twice.
208 |  |
209 | 0 |
             _externalScripts.add(scriptLocation);
210 |  |
         }
211 |  |
212 |  |
         /**
213 |  |
          * Writes &lt;script&gt; elements for all the external scripts.
214 |  |
          */
215 | 0 |
         private void writeExternalScripts(IMarkupWriter writer) {
216 | 0 |
             int count = Tapestry.size(_externalScripts);
217 | 0 |
             for (int i = 0; i < count; i++) {
218 | 0 |
                 ClasspathResourceLocation scriptLocation = (ClasspathResourceLocation) _externalScripts
219 |  |
                         .get(i);
220 |  |
221 |  |
                 // This is still very awkward! Should move the code inside
222 |  |
                 // PrivateAsset somewhere
223 |  |
                 // else, so that an asset does not have to be created to to build
224 |  |
                 // the URL.
225 | 0 |
                 PrivateAsset asset = new PrivateAsset(scriptLocation, null);
226 | 0 |
                 String url = asset.buildURL(getPage().getRequestCycle());
227 |  |
228 |  |
                 // Note: important to use begin(), not beginEmpty(), because browser
229 |  |
                 // don't
230 |  |
                 // interpret <script .../> properly.
231 |  |
232 | 0 |
                 writer.begin("script");
233 | 0 |
                 writer.attribute("language", "JavaScript");
234 | 0 |
                 writer.attribute("type", "text/javascript");
235 | 0 |
                 writer.attribute("src", url);
236 | 0 |
                 writer.end();
237 | 0 |
                 writer.println();
238 |  |
             }
239 |  |
240 |  |
         }
241 |  |
242 |  |
         /**
243 |  |
          * Retrieves the <code>Body</code> that was stored into the request cycle.
244 |  |
          * This allows components wrapped by the <code>Body</code> to locate it
245 |  |
          * and access the services it provides.
246 |  |
          *
247 |  |
          */
248 |  |
249 | 0 |
         public static Body get(IRequestCycle cycle) {
250 | 0 |
             return (Body) cycle.getAttribute(ATTRIBUTE_NAME);
251 |  |
         }
252 |  |
253 | 0 |
         protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle) {
254 | 0 |
             if (cycle.getAttribute(ATTRIBUTE_NAME) != null)
255 | 0 |
                 throw new ApplicationRuntimeException(Tapestry
256 |  |
                         .getMessage("Body.may-not-nest"), this, null, null);
257 |  |
258 | 0 |
             cycle.setAttribute(ATTRIBUTE_NAME, this);
259 |  |
260 | 0 |
             _outerWriter = writer;
261 |  |
262 | 0 |
             IMarkupWriter nested = writer.getNestedWriter();
263 |  |
264 | 0 |
             renderBody(nested, cycle);
265 |  |
266 |  |
             // Start the body tag.
267 | 0 |
             writer.println();
268 | 0 |
             writer.begin(getElement());
269 | 0 |
             renderInformalParameters(writer, cycle);
270 |  |
271 | 0 |
             writer.println();
272 |  |
273 |  |
             // Write the page's scripting. This is included scripts
274 |  |
             // and dynamic JavaScript, including initialization.
275 |  |
276 | 0 |
             writeScript();
277 |  |
278 |  |
             // Close the nested writer, which dumps its buffered content
279 |  |
             // into its parent.
280 |  |
281 | 0 |
             nested.close();
282 |  |
283 | 0 |
             writer.end(); // <body>
284 |  |
285 |  |
         }
286 |  |
287 | 0 |
         protected void cleanupAfterRender(IRequestCycle cycle) {
288 | 0 |
             super.cleanupAfterRender(cycle);
289 |  |
290 | 0 |
             if (_idAllocator != null)
291 | 0 |
                 _idAllocator.clear();
292 |  |
293 | 0 |
             if (_imageMap != null)
294 | 0 |
                 _imageMap.clear();
295 |  |
296 | 0 |
             if (_externalScripts != null)
297 | 0 |
                 _externalScripts.clear();
298 |  |
299 | 0 |
             if (_initializationScript != null)
300 | 0 |
                 _initializationScript.setLength(0);
301 |  |
302 | 0 |
             if (_finalizationScript != null)
303 | 0 |
                 _finalizationScript.setLength(0);
304 |  |
305 | 0 |
             if (_imageInitializations != null)
306 | 0 |
                 _imageInitializations.setLength(0);
307 |  |
308 | 0 |
             if (_bodyScript != null)
309 | 0 |
                 _bodyScript.setLength(0);
310 |  |
311 | 0 |
             _outerWriter = null;
312 | 0 |
             _outerWriter = null;
313 |  |
         }
314 |  |
315 |  |
         /**
316 |  |
          * Writes a single large JavaScript block containing:
317 |  |
          * <ul>
318 |  |
          * <li>Any image initializations
319 |  |
          * <li>Any scripting
320 |  |
          * <li>Any initializations
321 |  |
          * </ul>
322 |  |
          *
323 |  |
          * <p>
324 |  |
          * The script is written into a nested markup writer.
325 |  |
          *
326 |  |
          * <p>
327 |  |
          * If there are any other initializations (see
328 |  |
          * {@link #addOtherInitialization(String)}), then a function to execute
329 |  |
          * them is created.
330 |  |
          */
331 |  |
332 | 0 |
         protected void writeScript() {
333 | 0 |
             if (!Tapestry.isEmpty(_externalScripts))
334 | 0 |
                 writeExternalScripts(_outerWriter);
335 |  |
336 | 0 |
             if (!(any(_initializationScript) || any(_finalizationScript)
337 |  |
                     || any(_bodyScript) || any(_imageInitializations)))
338 | 0 |
                 return;
339 |  |
340 | 0 |
             _outerWriter.begin("script");
341 | 0 |
             _outerWriter.attribute("language", "JavaScript");
342 | 0 |
             _outerWriter.printRaw("<!--");
343 |  |
344 | 0 |
             if (any(_imageInitializations)) {
345 | 0 |
                 _outerWriter.printRaw("\n\nvar tapestry_preload = new Array();\n");
346 | 0 |
                 _outerWriter.printRaw("if (document.images)\n");
347 | 0 |
                 _outerWriter.printRaw("{\n");
348 | 0 |
                 _outerWriter.printRaw(_imageInitializations.toString());
349 | 0 |
                 _outerWriter.printRaw("}\n");
350 |  |
             }
351 |  |
352 | 0 |
             if (any(_bodyScript)) {
353 | 0 |
                 _outerWriter.printRaw("\n\n");
354 | 0 |
                 _outerWriter.printRaw(_bodyScript.toString());
355 |  |
             }
356 |  |
357 | 0 |
             if (any(_initializationScript)) {
358 | 0 |
                 _outerWriter.printRaw("\n\n" + "window.onload = function ()\n"
359 |  |
                         + "{\n");
360 | 0 |
                 _outerWriter.printRaw(_initializationScript.toString());
361 | 0 |
                 _outerWriter.printRaw("}");
362 |  |
             }
363 |  |
364 | 0 |
             if (any(_finalizationScript)) {
365 | 0 |
                 _outerWriter.printRaw("\n\n" + "window.onunload = function ()\n"
366 |  |
                         + "{\n");
367 | 0 |
                 _outerWriter.printRaw(_finalizationScript.toString());
368 | 0 |
                 _outerWriter.printRaw("}");
369 |  |
             }
370 |  |
371 | 0 |
             _outerWriter.printRaw("\n\n// -->");
372 | 0 |
             _outerWriter.end();
373 |  |
         }
374 |  |
375 | 0 |
         private boolean any(StringBuffer buffer) {
376 | 0 |
             if (buffer == null)
377 | 0 |
                 return false;
378 |  |
379 | 0 |
             return buffer.length() > 0;
380 |  |
         }
381 |  |
382 |  |
         public abstract String getElement();
383 |  |
384 |  |
         public abstract void setElement(String element);
385 |  |
386 |  |
     }