View Javadoc

1   /*
2    * $Id: Head.java 651946 2008-04-27 13:41:38Z apetrelli $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  package org.apache.struts2.dojo.components;
23  
24  import javax.servlet.http.HttpServletRequest;
25  import javax.servlet.http.HttpServletResponse;
26  
27  import org.apache.struts2.views.annotations.StrutsTag;
28  import org.apache.struts2.views.annotations.StrutsTagAttribute;
29  import org.apache.struts2.views.annotations.StrutsTagSkipInheritance;
30  
31  import com.opensymphony.xwork2.util.ValueStack;
32  
33  /***
34   * <!-- START SNIPPET: notice -->
35   * The "head" tag renders required JavaScript code to configure Dojo and is required in order to use
36   * any of the tags included in the Dojo plugin.</p>
37   * <!-- END SNIPPET: notice -->
38   * 
39   * <!-- START SNIPPET: javadoc -->
40   * <p></p>
41   * 
42   * <p>To debug javascript errors set the "debug" attribute to true, which will display Dojo 
43   * (and Struts) warning and error messages at the bottom of the page. Core Dojo files are by default
44   * compressed, to improve loading time, which makes them very hard to read. To debug Dojo and Struts
45   * widgets, set the "compressed" attribute to true. Make sure to turn this option off before
46   * moving your project into production, as uncompressed files will take longer to download.
47   * </p>
48   * <p>For troubleshooting javascript problems the following configuration is recommended:</p>
49   * <pre>
50   *   &lt;sx:head debug="true" cache="false" compressed="false" /&gt;
51   * </pre>
52   *
53   * <p>Dojo files are loaded as required by the Dojo loading mechanism. The problem with this
54   * approach is that the files are not cached by the browser, so reloading a page or navigating
55   * to a different page that uses the same widgets will cause the files to be reloaded. To solve 
56   * this problem a custom Dojo profile is distributed with the Dojo plugin. This profile contains
57   * the files required by the tags in the Dojo plugin, all in one file (524Kb), which is cached 
58   * by the browser. This file will take longer to load by the browser but it will be downloaded 
59   * only once. By default the "cache" attribute is set to false.</p>
60   * 
61   * <p>Some tags like the "datetimepicker" can use different locales, to use a locale
62   * that is different from the request locale, it must be specified on the "extraLocales" 
63   * attribute. This attribute can contain a comma separated list of locale names. From
64   * Dojo's documentation:</p>
65   * 
66   * <p>
67   * The locale is a short string, defined by the host environment, which conforms to RFC 3066 
68   * (http://www.ietf.org/rfc/rfc3066.txt) used in the HTML specification. 
69   * It consists of short identifiers, typically two characters 
70   * long which are case-insensitive. Note that Dojo uses dash separators, not underscores like 
71   * Java (e.g. "en-us", not "en_US"). Typically country codes are used in the optional second 
72   * identifier, and additional variants may be specified. For example, Japanese is "ja"; 
73   * Japanese in Japan is "ja-jp". Notice that the lower case is intentional -- while Dojo 
74   * will often convert all locales to lowercase to normalize them, it is the lowercase that 
75   * must be used when defining your resources.
76   * </p>
77   * 
78   * <p>The "locale" attribute configures Dojo's locale:</p>
79   * 
80   * <p>"The locale Dojo uses on a page may be overridden by setting djConfig.locale. This may be 
81   * done to accomodate applications with a known user profile or server pages which do manual
82   * assembly and assume a certain locale. You may also set djConfig.extraLocale to load 
83   * localizations in addition to your own, in case you want to specify a particular 
84   * translation or have multiple languages appear on your page."</p>
85   * 
86   * <p>To improve loading time, the property "parseContent" is set to false by default. This property will
87   * instruct Dojo to only build widgets using specific element ids. If the property is set to true
88   * Dojo will scan the whole document looking for widgets.</p>
89   * 
90   * <p>Dojo 0.4.3 is distributed with the Dojo plugin, to use a different Dojo version, the 
91   * "baseRelativePath" attribute can be set to the URL of the Dojo root folder on your application.
92   * </p>
93   * <!-- END SNIPPET: javadoc -->
94   *
95   * <p/> <b>Examples</b>
96   *
97   * <pre>
98   * <!-- START SNIPPET: example1 -->
99   * &lt;%@ taglib prefix="sx" uri="/struts-dojo-tags" %&gt;
100  * &lt;head&gt;
101  *   &lt;title&gt;My page&lt;/title&gt;
102  *   &lt;sx:head/&gt;
103  * &lt;/head&gt;
104  * <!-- END SNIPPET: example1 -->
105  * </pre>
106  *
107  * <pre>
108  * <!-- START SNIPPET: example3 -->
109  * &lt;%@ taglib prefix="sx" uri="/struts-dojo-tags" %&gt;
110  * &lt;head&gt;
111  *   &lt;title&gt;My page&lt;/title&gt;
112  *   &lt;sx:head debug="true" extraLocales="en-us,nl-nl,de-de"/&gt;
113  * &lt;/head&gt;
114  * <!-- END SNIPPET: example3 -->
115  * </pre>
116  *
117  */
118 @StrutsTag(name="head", tldBodyContent="empty", tldTagClass="org.apache.struts2.dojo.views.jsp.ui.HeadTag",
119     description="Render a chunk of HEAD for your HTML file")
120 @StrutsTagSkipInheritance
121 public class Head extends org.apache.struts2.components.Head {
122     public static final String TEMPLATE = "head";
123     public static final String PARSE_CONTENT = "struts.dojo.head.parseContent";
124     
125     private String debug;
126     private String compressed;
127     private String baseRelativePath;
128     private String extraLocales;
129     private String locale;
130     private String cache;
131     private String parseContent;
132     
133     public Head(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
134         super(stack, request, response);
135     }
136 
137     protected String getDefaultTemplate() {
138         return TEMPLATE;
139     }
140 
141     public void evaluateParams() {
142         super.evaluateParams();
143         
144         if (this.debug != null)
145             addParameter("debug", findValue(this.debug, Boolean.class));
146         if (this.compressed != null)
147             addParameter("compressed", findValue(this.compressed, Boolean.class));
148         if (this.baseRelativePath != null)
149             addParameter("baseRelativePath", findString(this.baseRelativePath));
150         if (this.extraLocales != null) {
151             String locales = findString(this.extraLocales);
152             addParameter("extraLocales", locales.split(","));
153         }
154         if (this.locale != null)
155             addParameter("locale", findString(this.locale));
156         if (this.cache != null)
157             addParameter("cache", findValue(this.cache, Boolean.class));
158         if (this.parseContent != null) {
159             Boolean shouldParseContent = (Boolean) findValue(this.parseContent, Boolean.class);
160             addParameter("parseContent", shouldParseContent);
161             stack.getContext().put(PARSE_CONTENT, shouldParseContent);
162         } else {
163             addParameter("parseContent", false);
164             stack.getContext().put(PARSE_CONTENT, false);
165         }
166     }
167 
168     @Override
169     @StrutsTagSkipInheritance
170     public void setTheme(String theme) {
171         super.setTheme(theme);
172     }
173     
174     @Override
175     public String getTheme() {
176         return "ajax";
177     }
178     
179     public boolean isDebug() {
180         return debug != null && Boolean.parseBoolean(debug);
181     }
182 
183     @StrutsTagAttribute(description="Enable Dojo debug messages", defaultValue="false", type="Boolean")
184     public void setDebug(String debug) {
185         this.debug = debug;
186     }
187 
188     @StrutsTagAttribute(description="Use compressed version of dojo.js", defaultValue="true", type="Boolean")
189     public void setCompressed(String compressed) {
190         this.compressed = compressed;
191     }
192 
193     @StrutsTagAttribute(description="Context relative path of Dojo distribution folder", defaultValue="/struts/dojo")
194     public void setBaseRelativePath(String baseRelativePath) {
195         this.baseRelativePath = baseRelativePath;
196     }
197 
198     @StrutsTagAttribute(description="Comma separated list of locale names to be loaded by Dojo, locale names must be specified as in RFC3066")
199     public void setExtraLocales(String extraLocales) {
200         this.extraLocales = extraLocales;
201     }
202 
203     @StrutsTagAttribute(description="Default locale to be used by Dojo, locale name must be specified as in RFC3066")
204     public void setLocale(String locale) {
205         this.locale = locale;
206     }
207 
208     @StrutsTagAttribute(description="Use Struts Dojo profile, which contains all Struts widgets in one file, making it possible to be chached by " +
209                 "the browser", defaultValue="true", type="Boolean")
210     public void setCache(String cache) {
211         this.cache = cache;
212     }
213     
214     @StrutsTagAttribute(description="Parse the whole document for widgets", defaultValue="false", type="Boolean")
215     public void setParseContent(String parseContent) {
216         this.parseContent = parseContent;
217     }
218 }