/*
* 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 SoftwareFoundation, 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.jsp.TagInstance;
import com.caucho.xml.QName;
import javax.servlet.jsp.tagext.JspIdConsumer;
import javax.servlet.jsp.tagext.VariableInfo;
import java.util.ArrayList;
/**
* Represents a custom tag.
*/
public class CustomSimpleTag extends GenericTag
{
JspBody _body;
private boolean _oldLocalScriptingInvalid;
/**
* Simple tags can't be reused.
*/
public boolean isReuse()
{
return false;
}
@Override
protected void addTagDepend()
{
// jsp/10i0 - #3578
}
/**
* Called when the attributes end.
*/
public void endAttributes()
throws JspParseException
{
super.endAttributes();
_oldLocalScriptingInvalid = _parseState.isLocalScriptingInvalid();
// jsp/18dj
// _parseState.setScriptingInvalid(true);
}
/**
* Adds a child node.
*/
public void endElement()
throws Exception
{
super.endElement();
_parseState.setLocalScriptingInvalid(_oldLocalScriptingInvalid);
if (isEmpty())
return;
for (int i = 0; i < _children.size(); i++) {
JspNode node = (JspNode) _children.get(i);
if (node instanceof JspBody) {
if (_body != null)
throw error(L.l("Only one <jsp:body> is allowed as a child of a tag."));
_body = (JspBody) node;
_children.remove(i);
return;
}
}
_body = new JspBody();
_body.setParent(this);
_body.setStartLocation(_sourcePath, _filename, _startLine);
_body.setGenerator(_gen);
_body.endAttributes();
_body.setEndLocation(_filename, _startLine);
for (int i = 0; i < _children.size(); i++) {
JspNode node = _children.get(i);
if (! (node instanceof JspAttribute))
_body.addChild(node);
_body.setEndLocation(node.getFilename(), node.getEndLine());
}
_body.endElement();
_children = null;
}
/**
* Set true if the node contains a child tag.
*/
public boolean hasCustomTag()
{
if (_body != null && _body.hasCustomTag())
return true;
else
return super.hasCustomTag();
}
/**
* Generates code before the actual JSP.
*/
public void generatePrologue(JspJavaWriter out)
throws Exception
{
super.generatePrologue(out);
if (_body != null) {
_body.setJspFragment(true);
_body.generateFragmentPrologue(out);
}
if (hasCustomTag()) {
// jsp/18ei, jsp/18e8
if (_tag.generateAdapterDeclaration()) {
out.println("javax.servlet.jsp.tagext.Tag " + _tag.getId() + "_adapter = null;");
}
}
}
/**
* Generates the code for a custom tag.
*
* @param out the output writer for the generated java.
*/
public void generate(JspJavaWriter out)
throws Exception
{
String name = _tag.getId();
if (! isReuse()) {
generateTagInit(out);
}
else if (! isDeclared()) {
out.println("if (" + name + " == null) {");
out.pushDepth();
generateTagInit(out);
out.popDepth();
out.println("}");
out.println();
}
fillAttributes(out, name);
if (_body != null) {
out.print(name + ".setJspBody(");
generateFragment(out, _body, "pageContext", false);
out.println(");");
}
out.println(name + ".doTag();");
printVarDeclaration(out, VariableInfo.AT_END);
}
/**
* Generates the initialization code for the tag.
*
* @param out the output stream
*/
private void generateTagInit(JspJavaWriter out)
throws Exception
{
TagInstance parent = _tag.getParent();
String var = _tag.getId();
String className = _tag.getTagClass().getName();
if (_tag.getAnalyzedTag().getHasInjection()) {
// out.println("_jsp_inject_" + _tag.getId() + ".configure(" + var + ");");
out.print(var + " = com.caucho.config.inject.InjectManager.create().createTransientObject(");
out.printClass(_tag.getTagClass());
out.println(".class);");
}
else {
out.print(var + " = new ");
out.printClass(_tag.getTagClass());
out.println("();");
}
/*
out.print(var + " = new ");
out.printClass(_tag.getTagClass());
out.println("();");
*/
if (JspIdConsumer.class.isAssignableFrom(_tag.getTagClass())) {
String shortName = className;
int p = shortName.lastIndexOf('.');
if (p >= 0)
shortName = shortName.substring(p + 1);
out.print(var + ".setJspId(\"" + shortName + "-" + _gen.generateJspId() + "\");");
}
out.println(var + ".setJspContext(pageContext);");
JspNode parentNode = getParent().getParentTagNode();
if (parentNode != null) {
out.println(var + ".setParent(" + parentNode.getCustomTagName() + ");");
}
/*
if (_tag.getAnalyzedTag() != null
&& _tag.getAnalyzedTag().getHasInjection()) {
out.println("_jsp_inject_" + _tag.getId() + ".configure(" + var + ");");
}
*/
if (hasCustomTag()) {
out.println(var + "_adapter = new javax.servlet.jsp.tagext.TagAdapter(" + var + ");");
}
ArrayList<QName> names = _tag.getAttributeNames();
for (int i = 0; i < names.size(); i++) {
QName name = names.get(i);
String value = _tag.getAttribute(name);
if (value == null)
continue;
generateSetAttribute(out, var, name, value, false, false,
_tag.getAttributeInfo(name.getLocalName()));
}
}
}