/* * 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.config.types.Signature; import com.caucho.jsp.JspParseException; import com.caucho.jsp.cfg.TldAttribute; import com.caucho.util.L10N; import com.caucho.vfs.WriteStream; import com.caucho.xml.QName; import javax.servlet.jsp.tagext.JspFragment; import java.io.IOException; public class JspDirectiveAttribute extends JspNode { static L10N L = new L10N(JspDirectiveAttribute.class); private static final QName NAME = new QName("name"); private static final QName REQUIRED = new QName("required"); private static final QName FRAGMENT = new QName("fragment"); private static final QName RTEXPRVALUE = new QName("rtexprvalue"); private static final QName TYPE = new QName("type"); private static final QName DESCRIPTION = new QName("description"); private static final QName DEFERRED_VALUE = new QName("deferredValue"); private static final QName DEFERRED_VALUE_TYPE = new QName("deferredValueType"); private static final QName DEFERRED_METHOD = new QName("deferredMethod"); private static final QName DEFERRED_METHOD_SIGNATURE = new QName("deferredMethodSignature"); private String _name; private String _type; private boolean _isRequired; private boolean _isFragment; private Boolean _isRtexprvalue; private String _description; private Boolean _deferredValue; private String _deferredValueType; private Boolean _deferredMethod; private String _deferredMethodSignature; /** * Adds an attribute. * * @param name the attribute name * @param value the attribute value */ public void addAttribute(QName name, String value) throws JspParseException { if (! _gen.getParseState().isTag()) throw error(L.l("'{0}' is only allowed in .tag files. Attribute directives are not allowed in normal JSP files.", getTagName())); JavaTagGenerator gen = (JavaTagGenerator) _gen; if (NAME.equals(name)) { if (gen.findVariable(value) != null) { throw error(L.l("@attribute name '{0}' is already used by a variable.", value)); } else if (gen.findAttribute(value) != null) { throw error(L.l("@attribute name '{0}' is already used by another attribute.", value)); } _name = value; } else if (TYPE.equals(name)) _type = value; else if (REQUIRED.equals(name)) _isRequired = attributeToBoolean(name.getName(), value); else if (FRAGMENT.equals(name)) _isFragment = attributeToBoolean(name.getName(), value); else if (RTEXPRVALUE.equals(name)) _isRtexprvalue = attributeToBoolean(name.getName(), value); else if (DESCRIPTION.equals(name)) _description = value; else if (DEFERRED_VALUE.equals(name)) { if (_gen.isPre21()) throw error("deferredValue requires JSP 2.1 or later tag file"); _deferredValue = attributeToBoolean(name.getName(), value); if (_deferredValue) _type = "javax.el.ValueExpression"; } else if (DEFERRED_VALUE_TYPE.equals(name)) { if (_gen.isPre21()) throw error("deferredValueType requires JSP 2.1 or later tag file"); _type = "javax.el.ValueExpression"; _deferredValueType = value; } else if (DEFERRED_METHOD.equals(name)) { if (_gen.isPre21()) throw error("deferredMethod requires JSP 2.1 or later tag file"); _deferredMethod = attributeToBoolean(name.getName(), value); if (Boolean.TRUE.equals(_deferredMethod)) _type = "javax.el.MethodExpression"; } else if (DEFERRED_METHOD_SIGNATURE.equals(name)) { if (_gen.isPre21()) throw error("deferredMethodSignature requires JSP 2.1 or later tag file"); try { new Signature(value); } catch (Exception e) { throw error(e.getMessage()); } _type = "javax.el.MethodExpression"; _deferredMethodSignature = value; } else { throw error(L.l("'{0}' is an unknown JSP attribute directive attributes. The valid attributes are: deferredMethod, deferredMethodSignature, deferredValue, deferredValueType, description, fragment, name, rtexprvalue, type.", name.getName())); } } /** * When the element complets. */ public void endElement() throws JspParseException { if (! _gen.getParseState().isTag()) throw error(L.l("'{0}' is only allowed in .tag files. Attribute directives are not allowed in normal JSP files.", getTagName())); if (_name == null) throw error(L.l("<{0}> needs a 'name' attribute.", getTagName())); JavaTagGenerator tagGen = (JavaTagGenerator) _gen; TldAttribute attr = new TldAttribute(); attr.setName(_name); if (_type == null) { attr.setType(String.class); } else { Class type = loadClass(_type); if (type == null) throw error(L.l("type '{0}' is an unknown class for tag attribute {1}.", _type, _name)); if (type.isPrimitive()) throw error(L.l( "attribute type '{0}' cannot be a Java primitive for {1}.", _type, _name)); attr.setType(type); } attr.setRequired(_isRequired); if (_isFragment && _isRtexprvalue != null) throw error(L.l("@attribute rtexprvalue cannot be set when fragment is true.")); if (_isFragment && _type != null) throw error(L.l("@attribute type cannot be set when fragment is true.")); if (_isRtexprvalue == null || Boolean.TRUE.equals(_isRtexprvalue)) attr.setRtexprvalue(Boolean.TRUE); if (_isFragment) attr.setType(JspFragment.class); if (_deferredValue != null && _deferredValueType != null) throw error(L.l("@attribute deferredValue and deferredValueType may not both be specified")); if (_deferredMethod != null && _deferredMethodSignature != null) throw error(L.l("@attribute deferredMethod and deferredMethodSignature may not both be specified")); if ((_deferredValue != null || _deferredValueType != null) && (_deferredMethod != null || _deferredMethodSignature != null)) throw error(L.l("@attribute deferredValue and deferredMethod may not both be specified")); if (Boolean.TRUE.equals(_deferredValue) || _deferredValueType != null) { attr.setDeferredValue(new TldAttribute.DeferredValue()); if (_deferredValueType != null) attr.getDeferredValue().setType(_deferredValueType); } if (Boolean.TRUE.equals(_deferredMethod) || _deferredMethodSignature != null) { attr.setDeferredMethod(new TldAttribute.DeferredMethod()); if (_deferredMethodSignature != null) attr.getDeferredMethod().setMethodSignature(new Signature(_deferredMethodSignature)); } tagGen.addAttribute(attr); } /** * 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 { os.print("<jsp:directive.attribute"); os.print(" jsp:id=\"" + _gen.generateJspId() + "\""); os.print(" name=\"" + _name + "\""); if (_type != null) os.print(" type=\"" + _type + "\""); os.println("/>"); } /** * Generates the code for the tag * * @param out the output writer for the generated java. */ public void generate(JspJavaWriter out) throws Exception { } }