1 /*
2 * $Id: HtmlTag.java 482895 2006-12-06 05:12:27Z niallp $
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 package org.apache.struts.taglib.html;
22
23 import org.apache.struts.Globals;
24 import org.apache.struts.taglib.TagUtils;
25 import org.apache.struts.util.MessageResources;
26
27 import javax.servlet.jsp.JspException;
28 import javax.servlet.jsp.PageContext;
29 import javax.servlet.jsp.tagext.TagSupport;
30
31 import java.util.Locale;
32
33 /**
34 * Renders an HTML <html> element with appropriate language attributes if
35 * there is a current Locale available in the user's session.
36 *
37 * @version $Rev: 482895 $ $Date: 2005-08-21 19:08:45 -0400 (Sun, 21 Aug 2005)
38 * $
39 */
40 public class HtmlTag extends TagSupport {
41 // ------------------------------------------------------------- Properties
42
43 /**
44 * The message resources for this package.
45 */
46 protected static MessageResources messages =
47 MessageResources.getMessageResources(Constants.Package
48 + ".LocalStrings");
49
50 /**
51 * Are we rendering an xhtml page?
52 */
53 protected boolean xhtml = false;
54
55 /**
56 * Are we rendering a lang attribute?
57 *
58 * @since Struts 1.2
59 */
60 protected boolean lang = false;
61
62 public boolean getXhtml() {
63 return this.xhtml;
64 }
65
66 public void setXhtml(boolean xhtml) {
67 this.xhtml = xhtml;
68 }
69
70 /**
71 * Returns true if the tag should render a lang attribute.
72 *
73 * @since Struts 1.2
74 */
75 public boolean getLang() {
76 return this.lang;
77 }
78
79 /**
80 * Sets whether the tag should render a lang attribute.
81 *
82 * @since Struts 1.2
83 */
84 public void setLang(boolean lang) {
85 this.lang = lang;
86 }
87
88 /**
89 * Process the start of this tag.
90 *
91 * @throws JspException if a JSP exception has occurred
92 */
93 public int doStartTag() throws JspException {
94 TagUtils.getInstance().write(this.pageContext,
95 this.renderHtmlStartElement());
96
97 return EVAL_BODY_INCLUDE;
98 }
99
100 /**
101 * Renders an <html> element with appropriate language attributes.
102 *
103 * @since Struts 1.2
104 */
105 protected String renderHtmlStartElement() {
106 StringBuffer sb = new StringBuffer("<html");
107
108 String language = null;
109 String country = "";
110
111 Locale currentLocale =
112 TagUtils.getInstance().getUserLocale(pageContext, Globals.LOCALE_KEY);
113
114 language = currentLocale.getLanguage();
115 country = currentLocale.getCountry();
116
117 boolean validLanguage = isValidRfc2616(language);
118 boolean validCountry = isValidRfc2616(country);
119
120 if (this.xhtml) {
121 this.pageContext.setAttribute(Globals.XHTML_KEY, "true",
122 PageContext.PAGE_SCOPE);
123
124 sb.append(" xmlns=\"http://www.w3.org/1999/xhtml\"");
125 }
126
127 if ((this.lang || this.xhtml) && validLanguage) {
128 sb.append(" lang=\"");
129 sb.append(language);
130
131 if (validCountry) {
132 sb.append("-");
133 sb.append(country);
134 }
135
136 sb.append("\"");
137 }
138
139 if (this.xhtml && validLanguage) {
140 sb.append(" xml:lang=\"");
141 sb.append(language);
142
143 if (validCountry) {
144 sb.append("-");
145 sb.append(country);
146 }
147
148 sb.append("\"");
149 }
150
151 sb.append(">");
152
153 return sb.toString();
154 }
155
156 /**
157 * Process the end of this tag.
158 *
159 * @throws JspException if a JSP exception has occurred
160 */
161 public int doEndTag() throws JspException {
162 TagUtils.getInstance().write(pageContext, "</html>");
163
164 // Evaluate the remainder of this page
165 return (EVAL_PAGE);
166 }
167
168 /**
169 * Release any acquired resources.
170 */
171 public void release() {
172 this.xhtml = false;
173 this.lang = false;
174 }
175
176 /**
177 * Check whether the value contains valid characters for the
178 * "Accept-Language" header according to RFC 2616 (section 14.4).
179 *
180 * @param value The value to check
181 * @return <code>true</code> if valid, otherwise <code>false</code>
182 */
183 private boolean isValidRfc2616(String value) {
184 if (value == null || value.length() == 0) {
185 return false;
186 }
187 for (int i = 0; i < value.length(); i++) {
188 char c = value.charAt(i);
189
190 if (!(Character.isLetter(c) || c == '-')) {
191 return false;
192 }
193 }
194 return true;
195 }
196 }