/*
* Copyright (c) 1998-2011 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Resin Open Source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
*
* Free Software Foundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Scott Ferguson
*/
package com.caucho.jsp.java;
import com.caucho.jsp.JspParseException;
import com.caucho.util.L10N;
import com.caucho.vfs.WriteStream;
import com.caucho.xml.QName;
import java.io.IOException;
import java.util.Locale;
public class JspDirectiveTag extends JspNode {
private static final QName IMPORT = new QName("import");
private static final QName DISPLAY_NAME = new QName("display-name");
private static final QName BODY_CONTENT = new QName("body-content");
private static final QName DYNAMIC_ATTRIBUTES
= new QName("dynamic-attributes");
private static final QName SMALL_ICON = new QName("small-icon");
private static final QName LARGE_ICON = new QName("large-icon");
private static final QName DESCRIPTION = new QName("description");
private static final QName EXAMPLE = new QName("example");
private static final QName LANGUAGE = new QName("language");
private static final QName PAGE_ENCODING = new QName("pageEncoding");
private static final QName IS_EL_IGNORED = new QName("isELIgnored");
private static final QName DEFERRED_AS_LITERAL
= new QName("deferredSyntaxAllowedAsLiteral");
private static final QName TRIM_WHITESPACES
= new QName("trimDirectiveWhitespaces");
private static final QName IS_VELOCITY_ENABLED =
new QName("isVelocityEnabled");
static final L10N L = new L10N(JspDirectiveTag.class);
private String _import;
/**
* Adds an attribute.
*
* @param name the attribute name
* @param value the attribute value
*/
public void addAttribute(QName name, String value)
throws JspParseException
{
if (! _gen.isTag())
throw error(L.l("@tag directive is only allowed in tag files"));
JavaTagGenerator gen = (JavaTagGenerator) _gen;
if (IS_EL_IGNORED.equals(name)) {
boolean isIgnored = value.equals("true");
if (_parseState.isELIgnoredPageSpecified() &&
isIgnored != _parseState.isELIgnored())
throw error(L.l("isELIgnored values conflict"));
_parseState.setELIgnored(isIgnored);
_parseState.setELIgnoredPageSpecified(true);
}
/*
else if (name.equals("isScriptingInvalid"))
_parseState.setScriptingInvalid(value.equals("true"));
*/
else if (IS_VELOCITY_ENABLED.equals(name))
_parseState.setVelocityEnabled(value.equals("true"));
else if (PAGE_ENCODING.equals(name)) {
String oldEncoding = _parseState.getPageEncoding();
if (oldEncoding != null && ! value.equals(oldEncoding))
throw error(L.l("pageEncoding '{0}' conflicts with previous value of pageEncoding '{1}'. Check the .jsp and any included .jsp files for conflicts.", value, oldEncoding));
_parseState.setPageEncoding(value);
_parseState.setCharEncoding(value);
}
else if (LANGUAGE.equals(name)) {
if (! value.equals("java"))
throw error(L.l("'{0}' is not supported as a JSP scripting language.",
value));
}
else if (IMPORT.equals(name)) {
_import = value;
_parseState.addImport(value);
}
else if (DISPLAY_NAME.equals(name)) {
String oldValue = gen.getDisplayName();
if (oldValue != null && ! oldValue.equals(value))
throw error(L.l("@tag display-name '{0}' conflicts with previous value '{1}'. The display-name attribute may only be specified once.",
value, oldValue));
gen.setDisplayName(value);
}
else if (SMALL_ICON.equals(name)) {
String oldValue = gen.getSmallIcon();
if (oldValue != null && ! oldValue.equals(value))
throw error(L.l("@tag small-icon '{0}' conflicts with previous value '{1}'. The small-icon attribute may only be specified once.",
value, oldValue));
gen.setSmallIcon(value);
}
else if (LARGE_ICON.equals(name)) {
String oldValue = gen.getLargeIcon();
if (oldValue != null && ! oldValue.equals(value))
throw error(L.l("@tag large-icon '{0}' conflicts with previous value '{1}'. The large-icon attribute may only be specified once.",
value, oldValue));
gen.setLargeIcon(value);
}
else if (DESCRIPTION.equals(name)) {
String oldValue = gen.getDescription();
if (oldValue != null && ! oldValue.equals(value))
throw error(L.l("@tag description '{0}' conflicts with previous value '{1}'. The description attribute may only be specified once.",
value, oldValue));
gen.setDescription(value);
}
else if (EXAMPLE.equals(name)) {
String oldValue = gen.getExample();
if (oldValue != null && ! oldValue.equals(value))
throw error(L.l("@tag example '{0}' conflicts with previous value '{1}'. The example attribute may only be specified once.",
value, oldValue));
gen.setExample(value);
}
else if (DYNAMIC_ATTRIBUTES.equals(name)) {
String oldValue = gen.getDynamicAttributes();
if (oldValue != null && ! oldValue.equals(value))
throw error(L.l("@tag dynamic-attributes '{0}' conflicts with previous value '{1}'. The dynamic-attributes attribute may only be specified once.",
value, oldValue));
else if (gen.findAttribute(value) != null) {
throw error(L.l("@tag dynamic-attributes '{0}' conflicts with an attribute.",
value));
}
else if (gen.findVariable(value) != null) {
throw error(L.l("@tag dynamic-attributes '{0}' conflicts with a variable.",
value));
}
gen.setDynamicAttributes(value);
}
else if (BODY_CONTENT.equals(name)) {
String oldValue = gen.getBodyContent();
if (oldValue != null && ! oldValue.equals(value)) {
throw error(L.l("@tag body-content '{0}' conflicts with previous value '{1}'. The body-content attribute may only be specified once.",
value, oldValue));
}
if (value.equals("scriptless")
|| value.equals("tagdependent")
|| value.equals("empty")) {
}
else
throw error(L.l("'{0}' is an unknown body-content value for the JSP tag directive attribute. 'scriptless', 'tagdependent', and 'empty' are the allowed values.",
value));
gen.setBodyContent(value);
}
else if (DEFERRED_AS_LITERAL.equals(name)) {
_parseState.setDeferredSyntaxAllowedAsLiteral(value.equals("true"));
}
else if (TRIM_WHITESPACES.equals(name)) {
if (value.equals("true"))
_parseState.setTrimWhitespace(true);
else if (value.equals("false"))
_parseState.setTrimWhitespace(false);
else
throw error(L.l("trimDirectiveWhitespaces expects 'true' or 'false' at '{0}'",
value));
}
else {
throw error(L.l("'{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, trimDirectiveWhitespaces.",
name.getName()));
}
}
protected String getRelativeUrl(String value)
{
if (value.length() > 0 && value.charAt(0) == '/')
return value;
else
return _parseState.getUriPwd() + value;
}
/**
* Charset can be specific as follows:
* test/html; z=9; charset=utf8; w=12
*/
static String parseCharEncoding(String type)
throws JspParseException
{
type = type.toLowerCase(Locale.ENGLISH);
int i;
char ch;
while ((i = type.indexOf(';')) >= 0 && i < type.length()) {
i++;
while (i < type.length() && ((ch = type.charAt(i)) == ' ' || ch == '\t'))
i++;
if (i >= type.length())
return null;
type = type.substring(i);
i = type.indexOf('=');
if (i >= 0) {
if (! type.startsWith("charset"))
continue;
for (i++;
i < type.length() && ((ch = type.charAt(i)) == ' ' || ch == '\t');
i++) {
}
type = type.substring(i);
}
for (i = 0;
i < type.length() && (ch = type.charAt(i)) != ';' && ch != ' ';
i++) {
}
return type.substring(0, i);
}
return null;
}
/**
* Called when the tag ends.
*/
public void endAttributes()
throws JspParseException
{
if (! _gen.isTag())
throw error(L.l("tag directive is only allowed in tag files."));
}
/**
* Return true if the node only has static text.
*/
public boolean isStatic()
{
return true;
}
/**
* Generates the XML text representation for the tag validation.
*
* @param os write stream to the generated XML.
*/
public void printXml(WriteStream os)
throws IOException
{
JavaTagGenerator gen = (JavaTagGenerator) _gen;
os.print("<jsp:directive.tag");
os.print(" jsp:id=\"" + gen.generateJspId() + "\"");
if (_parseState.isELIgnoredPageSpecified())
os.print(" el-ignored='" + _parseState.isELIgnored() + "'");
if (_import != null)
os.print(" import='" + _import + "'");
/*
if (! _parseState.isScriptingEnabled())
os.print(" scripting-enabled='false'");
*/
String dynAttr = gen.getDynamicAttributes();
if (dynAttr != null)
os.print(" dynamic-attributes='" + dynAttr + "'");
os.print("/>");
}
/**
* Generates the code for the tag
*
* @param out the output writer for the generated java.
*/
public void generate(JspJavaWriter out)
throws Exception
{
}
}