KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tapestry > util > PageRenderSupportImpl


1 // Copyright 2005 The Apache Software Foundation
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15 package org.apache.tapestry.util;
16
17 import java.util.ArrayList JavaDoc;
18 import java.util.HashMap JavaDoc;
19 import java.util.List JavaDoc;
20 import java.util.Map JavaDoc;
21
22 import org.apache.hivemind.Locatable;
23 import org.apache.hivemind.Location;
24 import org.apache.hivemind.Resource;
25 import org.apache.hivemind.util.Defense;
26 import org.apache.tapestry.IAsset;
27 import org.apache.tapestry.IMarkupWriter;
28 import org.apache.tapestry.IRequestCycle;
29 import org.apache.tapestry.PageRenderSupport;
30 import org.apache.tapestry.Tapestry;
31 import org.apache.tapestry.asset.AssetFactory;
32 import org.apache.tapestry.asset.PrivateAsset;
33
34 /**
35  * Implementation of {@link org.apache.tapestry.PageRenderSupport}. The
36  * {@link org.apache.tapestry.html.Body} component uses an instance of this class.
37  *
38  * @author Howard M. Lewis Ship
39  * @since 4.0
40  */

41 public class PageRenderSupportImpl implements Locatable, PageRenderSupport
42 {
43     private final AssetFactory _assetFactory;
44
45     private final Location _location;
46
47     // Lines that belong inside the onLoad event handler for the <body> tag.
48
private StringBuffer JavaDoc _initializationScript;
49
50     // Any other scripting desired
51

52     private StringBuffer JavaDoc _bodyScript;
53
54     // Contains text lines related to image initializations
55

56     private StringBuffer JavaDoc _imageInitializations;
57
58     /**
59      * Map of URLs to Strings (preloaded image references).
60      */

61
62     private Map JavaDoc _imageMap;
63
64     /**
65      * List of included scripts. Values are Strings.
66      *
67      * @since 1.0.5
68      */

69
70     private List JavaDoc _externalScripts;
71
72     private final IdAllocator _idAllocator;
73
74     private final String JavaDoc _preloadName;
75
76     public PageRenderSupportImpl(AssetFactory assetFactory, String JavaDoc namespace, Location location)
77     {
78         Defense.notNull(assetFactory, "assetService");
79
80         _assetFactory = assetFactory;
81         _location = location;
82         _idAllocator = new IdAllocator(namespace);
83
84         _preloadName = (namespace.equals("") ? "tapestry" : namespace) + "_preload";
85     }
86
87     /**
88      * Returns the location, which may be used in error messages. In practical terms, this is the
89      * location of the {@link org.apache.tapestry.html.Body}&nbsp;component.
90      */

91
92     public Location getLocation()
93     {
94         return _location;
95     }
96
97     public String JavaDoc getPreloadedImageReference(String JavaDoc URL)
98     {
99         if (_imageMap == null)
100             _imageMap = new HashMap JavaDoc();
101
102         String JavaDoc reference = (String JavaDoc) _imageMap.get(URL);
103
104         if (reference == null)
105         {
106             int count = _imageMap.size();
107             String JavaDoc varName = _preloadName + "[" + count + "]";
108             reference = varName + ".src";
109
110             if (_imageInitializations == null)
111                 _imageInitializations = new StringBuffer JavaDoc();
112
113             _imageInitializations.append(" ");
114             _imageInitializations.append(varName);
115             _imageInitializations.append(" = new Image();\n");
116             _imageInitializations.append(" ");
117             _imageInitializations.append(reference);
118             _imageInitializations.append(" = \"");
119             _imageInitializations.append(URL);
120             _imageInitializations.append("\";\n");
121
122             _imageMap.put(URL, reference);
123         }
124
125         return reference;
126     }
127
128     public void addBodyScript(String JavaDoc script)
129     {
130         if (_bodyScript == null)
131             _bodyScript = new StringBuffer JavaDoc(script.length());
132
133         _bodyScript.append(script);
134     }
135
136     public void addInitializationScript(String JavaDoc script)
137     {
138         if (_initializationScript == null)
139             _initializationScript = new StringBuffer JavaDoc(script.length() + 1);
140
141         _initializationScript.append(script);
142         _initializationScript.append('\n');
143     }
144
145     public void addExternalScript(Resource scriptLocation)
146     {
147         if (_externalScripts == null)
148             _externalScripts = new ArrayList JavaDoc();
149
150         if (_externalScripts.contains(scriptLocation))
151             return;
152
153         // Record the Resource so we don't include it twice.
154

155         _externalScripts.add(scriptLocation);
156
157     }
158
159     public String JavaDoc getUniqueString(String JavaDoc baseValue)
160     {
161         return _idAllocator.allocateId(baseValue);
162     }
163
164     private void writeExternalScripts(IMarkupWriter writer, IRequestCycle cycle)
165     {
166         int count = Tapestry.size(_externalScripts);
167         for (int i = 0; i < count; i++)
168         {
169             Resource scriptLocation = (Resource) _externalScripts.get(i);
170
171             IAsset asset = _assetFactory.createAsset(scriptLocation, null);
172
173             String JavaDoc url = asset.buildURL(cycle);
174
175             // Note: important to use begin(), not beginEmpty(), because browser don't
176
// interpret <script .../> properly.
177

178             writer.begin("script");
179             writer.attribute("language", "JavaScript");
180             writer.attribute("type", "text/javascript");
181             writer.attribute("src", url);
182             writer.end();
183             writer.println();
184         }
185     }
186
187     /**
188      * Writes a single large JavaScript block containing:
189      * <ul>
190      * <li>Any image initializations (via {@link #getPreloadedImageReference(String)})
191      * <li>Any included scripts (via {@link #addExternalScript(Resource)})
192      * <li>Any contributions (via {@link #addBodyScript(String)})
193      * </ul>
194      *
195      * @see #writeInitializationScript(IMarkupWriter)
196      */

197
198     public void writeBodyScript(IMarkupWriter writer, IRequestCycle cycle)
199     {
200         if (!Tapestry.isEmpty(_externalScripts))
201             writeExternalScripts(writer, cycle);
202
203         if (!(any(_bodyScript) || any(_imageInitializations)))
204             return;
205
206         writer.begin("script");
207         writer.attribute("language", "JavaScript");
208         writer.attribute("type", "text/javascript");
209         writer.printRaw("<!--");
210
211         if (any(_imageInitializations))
212         {
213             writer.printRaw("\n\nvar " + _preloadName + " = new Array();\n");
214             writer.printRaw("if (document.images)\n");
215             writer.printRaw("{\n");
216             writer.printRaw(_imageInitializations.toString());
217             writer.printRaw("}\n");
218         }
219
220         if (any(_bodyScript))
221         {
222             writer.printRaw("\n\n");
223             writer.printRaw(_bodyScript.toString());
224         }
225
226         writer.printRaw("\n\n// -->");
227         writer.end();
228     }
229
230     /**
231      * Writes any image initializations; this should be invoked at the end of the render, after all
232      * the related HTML will have already been streamed to the client and parsed by the web browser.
233      * Earlier versions of Tapestry uses a <code>window.onload</code> event handler.
234      */

235
236     public void writeInitializationScript(IMarkupWriter writer)
237     {
238         if (!any(_initializationScript))
239             return;
240
241         writer.begin("script");
242         writer.attribute("language", "JavaScript");
243         writer.attribute("type", "text/javascript");
244         writer.printRaw("<!--\n");
245
246         writer.printRaw(_initializationScript.toString());
247
248         writer.printRaw("\n// -->");
249         writer.end();
250     }
251
252     private boolean any(StringBuffer JavaDoc buffer)
253     {
254         return buffer != null && buffer.length() > 0;
255     }
256 }
Popular Tags