001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: * Free SoftwareFoundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package com.caucho.jsp.java;
030:
031: import com.caucho.jsp.JspParseException;
032: import com.caucho.util.L10N;
033: import com.caucho.vfs.WriteStream;
034: import com.caucho.xml.QName;
035:
036: import java.io.IOException;
037:
038: public class JspDirectiveTag extends JspNode {
039: private static final QName IMPORT = new QName("import");
040: private static final QName DISPLAY_NAME = new QName("display-name");
041: private static final QName BODY_CONTENT = new QName("body-content");
042: private static final QName DYNAMIC_ATTRIBUTES = new QName(
043: "dynamic-attributes");
044: private static final QName SMALL_ICON = new QName("small-icon");
045: private static final QName LARGE_ICON = new QName("large-icon");
046: private static final QName DESCRIPTION = new QName("description");
047: private static final QName EXAMPLE = new QName("example");
048: private static final QName LANGUAGE = new QName("language");
049: private static final QName PAGE_ENCODING = new QName("pageEncoding");
050: private static final QName IS_EL_IGNORED = new QName("isELIgnored");
051: private static final QName DEFERRED_AS_LITERAL = new QName(
052: "deferredSyntaxAllowedAsLiteral");
053: private static final QName TRIM_WHITESPACES = new QName(
054: "trimDirectiveWhitespaces");
055:
056: private static final QName IS_VELOCITY_ENABLED = new QName(
057: "isVelocityEnabled");
058:
059: static final L10N L = new L10N(JspDirectiveTag.class);
060:
061: private Boolean _isElIgnored;
062: private String _import;
063:
064: /**
065: * Adds an attribute.
066: *
067: * @param name the attribute name
068: * @param value the attribute value
069: */
070: public void addAttribute(QName name, String value)
071: throws JspParseException {
072: if (!_gen.isTag())
073: throw error(L
074: .l("@tag directive is only allowed in tag files"));
075:
076: JavaTagGenerator gen = (JavaTagGenerator) _gen;
077:
078: if (IS_EL_IGNORED.equals(name)) {
079: boolean isIgnored = value.equals("true");
080:
081: _parseState.setELIgnored(isIgnored);
082:
083: if (_isElIgnored != null
084: && _isElIgnored.booleanValue() != isIgnored)
085: throw error(L.l("isELIgnored values conflict"));
086:
087: _isElIgnored = new Boolean(isIgnored);
088: }
089: /*
090: else if (name.equals("isScriptingInvalid"))
091: _parseState.setScriptingInvalid(value.equals("true"));
092: */
093: else if (IS_VELOCITY_ENABLED.equals(name))
094: _parseState.setVelocityEnabled(value.equals("true"));
095: else if (PAGE_ENCODING.equals(name)) {
096: String oldEncoding = _parseState.getPageEncoding();
097:
098: if (oldEncoding != null && !value.equals(oldEncoding))
099: throw error(L
100: .l(
101: "pageEncoding '{0}' conflicts with previous value of pageEncoding '{1}'. Check the .jsp and any included .jsp files for conflicts.",
102: value, oldEncoding));
103:
104: _parseState.setPageEncoding(value);
105: _parseState.setCharEncoding(value);
106: } else if (LANGUAGE.equals(name)) {
107: if (!value.equals("java"))
108: throw error(L
109: .l(
110: "'{0}' is not supported as a JSP scripting language.",
111: value));
112: } else if (IMPORT.equals(name)) {
113: _import = value;
114:
115: _parseState.addImport(value);
116: } else if (DISPLAY_NAME.equals(name)) {
117: String oldValue = gen.getDisplayName();
118:
119: if (oldValue != null && !oldValue.equals(value))
120: throw error(L
121: .l(
122: "@tag display-name '{0}' conflicts with previous value '{1}'. The display-name attribute may only be specified once.",
123: value, oldValue));
124:
125: gen.setDisplayName(value);
126: } else if (SMALL_ICON.equals(name)) {
127: String oldValue = gen.getSmallIcon();
128:
129: if (oldValue != null && !oldValue.equals(value))
130: throw error(L
131: .l(
132: "@tag small-icon '{0}' conflicts with previous value '{1}'. The small-icon attribute may only be specified once.",
133: value, oldValue));
134:
135: gen.setSmallIcon(value);
136: } else if (LARGE_ICON.equals(name)) {
137: String oldValue = gen.getLargeIcon();
138:
139: if (oldValue != null && !oldValue.equals(value))
140: throw error(L
141: .l(
142: "@tag large-icon '{0}' conflicts with previous value '{1}'. The large-icon attribute may only be specified once.",
143: value, oldValue));
144:
145: gen.setLargeIcon(value);
146: } else if (DESCRIPTION.equals(name)) {
147: String oldValue = gen.getDescription();
148:
149: if (oldValue != null && !oldValue.equals(value))
150: throw error(L
151: .l(
152: "@tag description '{0}' conflicts with previous value '{1}'. The description attribute may only be specified once.",
153: value, oldValue));
154:
155: gen.setDescription(value);
156: } else if (EXAMPLE.equals(name)) {
157: String oldValue = gen.getExample();
158:
159: if (oldValue != null && !oldValue.equals(value))
160: throw error(L
161: .l(
162: "@tag example '{0}' conflicts with previous value '{1}'. The example attribute may only be specified once.",
163: value, oldValue));
164:
165: gen.setExample(value);
166: } else if (DYNAMIC_ATTRIBUTES.equals(name)) {
167: String oldValue = gen.getDynamicAttributes();
168:
169: if (oldValue != null && !oldValue.equals(value))
170: throw error(L
171: .l(
172: "@tag dynamic-attributes '{0}' conflicts with previous value '{1}'. The dynamic-attributes attribute may only be specified once.",
173: value, oldValue));
174: else if (gen.findAttribute(value) != null) {
175: throw error(L
176: .l(
177: "@tag dynamic-attributes '{0}' conflicts with an attribute.",
178: value));
179: } else if (gen.findVariable(value) != null) {
180: throw error(L
181: .l(
182: "@tag dynamic-attributes '{0}' conflicts with a variable.",
183: value));
184: }
185:
186: gen.setDynamicAttributes(value);
187: } else if (BODY_CONTENT.equals(name)) {
188: String oldValue = gen.getBodyContent();
189:
190: if (oldValue != null && !oldValue.equals(value)) {
191: throw error(L
192: .l(
193: "@tag body-content '{0}' conflicts with previous value '{1}'. The body-content attribute may only be specified once.",
194: value, oldValue));
195: }
196:
197: if (value.equals("scriptless")
198: || value.equals("tagdependent")
199: || value.equals("empty")) {
200: } else
201: throw error(L
202: .l(
203: "'{0}' is an unknown body-content value for the JSP tag directive attribute. 'scriptless', 'tagdependent', and 'empty' are the allowed values.",
204: value));
205:
206: gen.setBodyContent(value);
207: } else if (DEFERRED_AS_LITERAL.equals(name)) {
208: _parseState.setDeferredSyntaxAllowedAsLiteral(value
209: .equals("true"));
210: } else {
211: throw error(L
212: .l(
213: "'{0}' is an unknown JSP tag directive attribute. The valid attributes are: body-content, deferredSyntaxAllowedAsLiteral, display-name, dynamic-attributes, example, isELIgnored, language, large-icon, pageEncoding, small-icon, trimDirectiveWhitespace.",
214: name.getName()));
215: }
216: }
217:
218: protected String getRelativeUrl(String value) {
219: if (value.length() > 0 && value.charAt(0) == '/')
220: return value;
221: else
222: return _parseState.getUriPwd() + value;
223: }
224:
225: /**
226: * Charset can be specific as follows:
227: * test/html; z=9; charset=utf8; w=12
228: */
229: static String parseCharEncoding(String type)
230: throws JspParseException {
231: type = type.toLowerCase();
232: int i;
233: char ch;
234: while ((i = type.indexOf(';')) >= 0 && i < type.length()) {
235: i++;
236: while (i < type.length()
237: && ((ch = type.charAt(i)) == ' ' || ch == '\t'))
238: i++;
239:
240: if (i >= type.length())
241: return null;
242:
243: type = type.substring(i);
244: i = type.indexOf('=');
245: if (i >= 0) {
246: if (!type.startsWith("charset"))
247: continue;
248:
249: for (i++; i < type.length()
250: && ((ch = type.charAt(i)) == ' ' || ch == '\t'); i++) {
251: }
252:
253: type = type.substring(i);
254: }
255:
256: for (i = 0; i < type.length()
257: && (ch = type.charAt(i)) != ';' && ch != ' '; i++) {
258: }
259:
260: return type.substring(0, i);
261: }
262:
263: return null;
264: }
265:
266: /**
267: * Called when the tag ends.
268: */
269: public void endAttributes() throws JspParseException {
270: if (!_gen.isTag())
271: throw error(L
272: .l("tag directive is only allowed in tag files."));
273: }
274:
275: /**
276: * Return true if the node only has static text.
277: */
278: public boolean isStatic() {
279: return true;
280: }
281:
282: /**
283: * Generates the XML text representation for the tag validation.
284: *
285: * @param os write stream to the generated XML.
286: */
287: public void printXml(WriteStream os) throws IOException {
288: JavaTagGenerator gen = (JavaTagGenerator) _gen;
289:
290: os.print("<jsp:directive.tag");
291: os.print(" jsp:id=\"" + gen.generateJspId() + "\"");
292:
293: if (_isElIgnored != null)
294: os.print(" el-ignored='" + _isElIgnored + "'");
295:
296: if (_import != null)
297: os.print(" import='" + _import + "'");
298:
299: /*
300: if (! _parseState.isScriptingEnabled())
301: os.print(" scripting-enabled='false'");
302: */
303: String dynAttr = gen.getDynamicAttributes();
304: if (dynAttr != null)
305: os.print("dynamic-attributes='" + dynAttr + "'");
306:
307: os.print("/>");
308: }
309:
310: /**
311: * Generates the code for the tag
312: *
313: * @param out the output writer for the generated java.
314: */
315: public void generate(JspJavaWriter out) throws Exception {
316: }
317: }
|