001: /*
002: * $Id: HtmlTag.java 482895 2006-12-06 05:12:27Z niallp $
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021: package org.apache.struts.taglib.html;
022:
023: import org.apache.struts.Globals;
024: import org.apache.struts.taglib.TagUtils;
025: import org.apache.struts.util.MessageResources;
026:
027: import javax.servlet.jsp.JspException;
028: import javax.servlet.jsp.PageContext;
029: import javax.servlet.jsp.tagext.TagSupport;
030:
031: import java.util.Locale;
032:
033: /**
034: * Renders an HTML <html> element with appropriate language attributes if
035: * there is a current Locale available in the user's session.
036: *
037: * @version $Rev: 482895 $ $Date: 2005-08-21 19:08:45 -0400 (Sun, 21 Aug 2005)
038: * $
039: */
040: public class HtmlTag extends TagSupport {
041: // ------------------------------------------------------------- Properties
042:
043: /**
044: * The message resources for this package.
045: */
046: protected static MessageResources messages = MessageResources
047: .getMessageResources(Constants.Package + ".LocalStrings");
048:
049: /**
050: * Are we rendering an xhtml page?
051: */
052: protected boolean xhtml = false;
053:
054: /**
055: * Are we rendering a lang attribute?
056: *
057: * @since Struts 1.2
058: */
059: protected boolean lang = false;
060:
061: public boolean getXhtml() {
062: return this .xhtml;
063: }
064:
065: public void setXhtml(boolean xhtml) {
066: this .xhtml = xhtml;
067: }
068:
069: /**
070: * Returns true if the tag should render a lang attribute.
071: *
072: * @since Struts 1.2
073: */
074: public boolean getLang() {
075: return this .lang;
076: }
077:
078: /**
079: * Sets whether the tag should render a lang attribute.
080: *
081: * @since Struts 1.2
082: */
083: public void setLang(boolean lang) {
084: this .lang = lang;
085: }
086:
087: /**
088: * Process the start of this tag.
089: *
090: * @throws JspException if a JSP exception has occurred
091: */
092: public int doStartTag() throws JspException {
093: TagUtils.getInstance().write(this .pageContext,
094: this .renderHtmlStartElement());
095:
096: return EVAL_BODY_INCLUDE;
097: }
098:
099: /**
100: * Renders an <html> element with appropriate language attributes.
101: *
102: * @since Struts 1.2
103: */
104: protected String renderHtmlStartElement() {
105: StringBuffer sb = new StringBuffer("<html");
106:
107: String language = null;
108: String country = "";
109:
110: Locale currentLocale = TagUtils.getInstance().getUserLocale(
111: pageContext, Globals.LOCALE_KEY);
112:
113: language = currentLocale.getLanguage();
114: country = currentLocale.getCountry();
115:
116: boolean validLanguage = isValidRfc2616(language);
117: boolean validCountry = isValidRfc2616(country);
118:
119: if (this .xhtml) {
120: this .pageContext.setAttribute(Globals.XHTML_KEY, "true",
121: PageContext.PAGE_SCOPE);
122:
123: sb.append(" xmlns=\"http://www.w3.org/1999/xhtml\"");
124: }
125:
126: if ((this .lang || this .xhtml) && validLanguage) {
127: sb.append(" lang=\"");
128: sb.append(language);
129:
130: if (validCountry) {
131: sb.append("-");
132: sb.append(country);
133: }
134:
135: sb.append("\"");
136: }
137:
138: if (this .xhtml && validLanguage) {
139: sb.append(" xml:lang=\"");
140: sb.append(language);
141:
142: if (validCountry) {
143: sb.append("-");
144: sb.append(country);
145: }
146:
147: sb.append("\"");
148: }
149:
150: sb.append(">");
151:
152: return sb.toString();
153: }
154:
155: /**
156: * Process the end of this tag.
157: *
158: * @throws JspException if a JSP exception has occurred
159: */
160: public int doEndTag() throws JspException {
161: TagUtils.getInstance().write(pageContext, "</html>");
162:
163: // Evaluate the remainder of this page
164: return (EVAL_PAGE);
165: }
166:
167: /**
168: * Release any acquired resources.
169: */
170: public void release() {
171: this .xhtml = false;
172: this .lang = false;
173: }
174:
175: /**
176: * Check whether the value contains valid characters for the
177: * "Accept-Language" header according to RFC 2616 (section 14.4).
178: *
179: * @param value The value to check
180: * @return <code>true</code> if valid, otherwise <code>false</code>
181: */
182: private boolean isValidRfc2616(String value) {
183: if (value == null || value.length() == 0) {
184: return false;
185: }
186: for (int i = 0; i < value.length(); i++) {
187: char c = value.charAt(i);
188:
189: if (!(Character.isLetter(c) || c == '-')) {
190: return false;
191: }
192: }
193: return true;
194: }
195: }
|