0001: /*
0002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
0003: *
0004: * This file is part of Resin(R) Open Source
0005: *
0006: * Each copy or derived work must preserve the copyright notice and this
0007: * notice unmodified.
0008: *
0009: * Resin Open Source is free software; you can redistribute it and/or modify
0010: * it under the terms of the GNU General Public License as published by
0011: * the Free Software Foundation; either version 2 of the License, or
0012: * (at your option) any later version.
0013: *
0014: * Resin Open Source is distributed in the hope that it will be useful,
0015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
0017: * of NON-INFRINGEMENT. See the GNU General Public License for more
0018: * details.
0019: *
0020: * You should have received a copy of the GNU General Public License
0021: * along with Resin Open Source; if not, write to the
0022: *
0023: * Free Software Foundation, Inc.
0024: * 59 Temple Place, Suite 330
0025: * Boston, MA 02111-1307 USA
0026: *
0027: * @author Scott Ferguson
0028: */
0029:
0030: package com.caucho.jsp.java;
0031:
0032: import com.caucho.el.Expr;
0033: import com.caucho.jsp.JspLineParseException;
0034: import com.caucho.jsp.JspParseException;
0035: import com.caucho.jsp.JspParser;
0036: import com.caucho.jsp.Namespace;
0037: import com.caucho.jsp.ParseState;
0038: import com.caucho.jsp.TagInstance;
0039: import com.caucho.log.Log;
0040: import com.caucho.util.CharBuffer;
0041: import com.caucho.util.CompileException;
0042: import com.caucho.util.L10N;
0043: import com.caucho.util.LineCompileException;
0044: import com.caucho.vfs.Path;
0045: import com.caucho.vfs.WriteStream;
0046: import com.caucho.xml.QName;
0047: import com.caucho.xml.XmlChar;
0048: import com.caucho.xpath.NamespaceContext;
0049: import com.caucho.xpath.XPath;
0050:
0051: import javax.el.MethodExpression;
0052: import javax.el.ValueExpression;
0053: import javax.servlet.jsp.tagext.JspFragment;
0054: import javax.servlet.jsp.tagext.TagAttributeInfo;
0055: import java.beans.PropertyEditor;
0056: import java.beans.PropertyEditorManager;
0057: import java.io.IOException;
0058: import java.lang.reflect.Method;
0059: import java.math.BigDecimal;
0060: import java.math.BigInteger;
0061: import java.util.ArrayList;
0062: import java.util.logging.Level;
0063: import java.util.logging.Logger;
0064:
0065: public abstract class JspNode {
0066: static final L10N L = new L10N(JspNode.class);
0067: static final Logger log = Log.open(JspNode.class);
0068:
0069: static final String JSP_NS = JspParser.JSP_NS;
0070:
0071: protected Path _sourcePath;
0072: protected String _filename;
0073: protected int _startLine;
0074: protected int _endAttributeLine;
0075: protected int _endLine;
0076:
0077: protected Namespace _ns;
0078:
0079: protected JavaJspGenerator _gen;
0080: protected ParseState _parseState;
0081:
0082: protected QName _name;
0083: protected JspNode _parent;
0084:
0085: protected JspNode() {
0086: }
0087:
0088: /**
0089: * Sets the Java generator.
0090: */
0091: public void setGenerator(JavaJspGenerator gen) {
0092: _gen = gen;
0093: }
0094:
0095: /**
0096: * Sets the parse state
0097: */
0098: public void setParseState(ParseState parseState) {
0099: _parseState = parseState;
0100: }
0101:
0102: /**
0103: * Returns the qname of the node.
0104: */
0105: public QName getQName() {
0106: return _name;
0107: }
0108:
0109: /**
0110: * Sets the node's qname
0111: */
0112: public void setQName(QName name) {
0113: _name = name;
0114: }
0115:
0116: /**
0117: * Returns the qname of the node.
0118: */
0119: public String getTagName() {
0120: if (_name != null)
0121: return _name.getName();
0122: else
0123: return "jsp:unknown";
0124: }
0125:
0126: /**
0127: * Returns the parent node.
0128: */
0129: public JspNode getParent() {
0130: return _parent;
0131: }
0132:
0133: /**
0134: * Sets the parent node
0135: */
0136: public void setParent(JspNode parent) {
0137: _parent = parent;
0138: }
0139:
0140: /**
0141: * Sets the start location of the node.
0142: */
0143: public void setStartLocation(Path sourcePath, String filename,
0144: int line) {
0145: _sourcePath = sourcePath;
0146: _filename = filename;
0147: _startLine = line;
0148: _endAttributeLine = line;
0149: }
0150:
0151: /**
0152: * Sets the end location of the node.
0153: */
0154: public void setEndAttributeLocation(String filename, int line) {
0155: if (_filename != null && _filename.equals(filename))
0156: _endAttributeLine = line;
0157: }
0158:
0159: /**
0160: * Sets the end location of the node.
0161: */
0162: public void setEndLocation(String filename, int line) {
0163: if (_filename != null && _filename.equals(filename))
0164: _endLine = line;
0165: }
0166:
0167: /**
0168: * Gets the filename of the node
0169: */
0170: public String getFilename() {
0171: return _filename;
0172: }
0173:
0174: /**
0175: * Gets the starting line number
0176: */
0177: public int getStartLine() {
0178: return _startLine;
0179: }
0180:
0181: /**
0182: * Gets the attribute ending line number
0183: */
0184: public int getEndAttributeLine() {
0185: return _endAttributeLine;
0186: }
0187:
0188: /**
0189: * Gets the ending line number
0190: */
0191: public int getEndLine() {
0192: return _endLine;
0193: }
0194:
0195: /**
0196: * True if the node only has static text.
0197: */
0198: public boolean isStatic() {
0199: return false;
0200: }
0201:
0202: /**
0203: * True if this is a jstl node.
0204: */
0205: public boolean isJstl() {
0206: return false;
0207: }
0208:
0209: /**
0210: * Returns the static text.
0211: */
0212: public String getStaticText() {
0213: CharBuffer cb = CharBuffer.allocate();
0214:
0215: getStaticText(cb);
0216:
0217: return cb.close();
0218: }
0219:
0220: /**
0221: * Returns the static text.
0222: */
0223: public void getStaticText(CharBuffer cb) {
0224: }
0225:
0226: /**
0227: * True if the node has scripting (counting rtexpr)
0228: */
0229: public boolean hasScripting() {
0230: return false;
0231: }
0232:
0233: /**
0234: * True if the node has scripting element (i.e. not counting rtexpr values)
0235: */
0236: public boolean hasScriptingElement() {
0237: return false;
0238: }
0239:
0240: /**
0241: * Finds the first scripting node
0242: */
0243: public JspNode findScriptingNode() {
0244: if (hasScripting())
0245: return this ;
0246: else
0247: return null;
0248: }
0249:
0250: /**
0251: * Returns the body content.
0252: */
0253: public String getBodyContent() {
0254: return "jsp";
0255: }
0256:
0257: /**
0258: * True if the node contains a child tag.
0259: */
0260: public boolean hasCustomTag() {
0261: return false;
0262: }
0263:
0264: /**
0265: * True if the node contains a child tag.
0266: */
0267: public boolean hasTag() {
0268: return hasCustomTag();
0269: }
0270:
0271: /**
0272: * Returns the tag name for the current tag.
0273: */
0274: public String getCustomTagName() {
0275: return null;
0276: }
0277:
0278: /**
0279: * Returns true for a simple tag.
0280: */
0281: public boolean isSimpleTag() {
0282: return false;
0283: }
0284:
0285: /**
0286: * Returns parent tag node
0287: */
0288: public JspNode getParentTagNode() {
0289: if (getCustomTagName() != null)
0290: return this ;
0291: else {
0292: JspNode parent = getParent();
0293:
0294: if (parent != null)
0295: return parent.getParentTagNode();
0296: else
0297: return null;
0298: }
0299: }
0300:
0301: /**
0302: * Returns parent tag node
0303: */
0304: public String getParentTagName() {
0305: if (getCustomTagName() != null)
0306: return getCustomTagName();
0307: else {
0308: JspNode parent = getParent();
0309:
0310: if (parent != null)
0311: return parent.getParentTagName();
0312: else
0313: return null;
0314: }
0315: }
0316:
0317: /**
0318: * Returns true if the namespace decl has been printed.
0319: */
0320: public boolean hasNamespace(String prefix, String uri) {
0321: if (_parent == null)
0322: return false;
0323: else
0324: return _parent.hasNamespace(prefix, uri);
0325: }
0326:
0327: /**
0328: * Adds a namespace, e.g. from a prefix declaration.
0329: */
0330: public final void addNamespace(String prefix, String value) {
0331: addNamespaceRec(prefix, value);
0332: }
0333:
0334: /**
0335: * Adds a namespace, e.g. from a prefix declaration.
0336: */
0337: public final void setNamespace(Namespace ns) {
0338: _ns = ns;
0339: }
0340:
0341: /**
0342: * Returns the XPath namespace context.
0343: */
0344: public final NamespaceContext getNamespaceContext() {
0345: NamespaceContext ns = null;
0346:
0347: for (Namespace ptr = _ns; ptr != null; ptr = ptr.getNext()) {
0348: // jsp/1g58
0349: if (!"".equals(ptr.getPrefix()))
0350: ns = new NamespaceContext(ns, ptr.getPrefix(), ptr
0351: .getURI());
0352: }
0353:
0354: return ns;
0355: }
0356:
0357: /**
0358: * Adds a namespace, e.g. from a prefix declaration.
0359: */
0360: public void addNamespaceRec(String prefix, String value) {
0361: if (_parent != null)
0362: _parent.addNamespaceRec(prefix, value);
0363: }
0364:
0365: /**
0366: * Adds a namespace, e.g. from a prefix declaration.
0367: */
0368: public String getNamespacePrefix(String uri) {
0369: if (_parent != null)
0370: return _parent.getNamespacePrefix(uri);
0371: else
0372: return null;
0373: }
0374:
0375: /**
0376: * Returns true if the namespace decl has been printed.
0377: */
0378: public boolean hasNamespace(QName name) {
0379: return hasNamespace(name.getPrefix(), name.getNamespaceURI());
0380: }
0381:
0382: /**
0383: * Adds an attribute.
0384: */
0385: public void addAttribute(QName name, String value)
0386: throws JspParseException {
0387: throw error(L.l("attribute '{0}' is not allowed in <{1}>.",
0388: name.getName(), getTagName()));
0389: }
0390:
0391: /**
0392: * Adds a JspAttribute attribute.
0393: *
0394: * @param name the name of the attribute.
0395: * @param value the value of the attribute.
0396: */
0397: public void addAttribute(QName name, JspAttribute value)
0398: throws JspParseException {
0399: if (value.isStatic()) {
0400: addAttribute(name, value.getStaticText().trim());
0401: } else
0402: throw error(L.l("attribute '{0}' is not allowed in <{1}>.",
0403: name.getName(), getTagName()));
0404: }
0405:
0406: /**
0407: * Called after all the attributes from the tag.
0408: */
0409: public void endAttributes() throws JspParseException {
0410: }
0411:
0412: /**
0413: * Adds text.
0414: */
0415: public JspNode addText(String text) throws JspParseException {
0416: for (int i = 0; i < text.length(); i++) {
0417: char ch = text.charAt(i);
0418:
0419: if (!XmlChar.isWhitespace(ch))
0420: throw error(L.l(
0421: "Text is not allowed in <{0}> at '{1}'.", _name
0422: .getName(), text));
0423: }
0424:
0425: return null;
0426: }
0427:
0428: /**
0429: * Adds a child node.
0430: */
0431: public void addChild(JspNode node) throws JspParseException {
0432: node.setParent(this );
0433:
0434: if (node instanceof JspAttribute) {
0435: } else if (node instanceof StaticText
0436: && ((StaticText) node).isWhitespace()) {
0437: } else
0438: throw node.error(L.l(
0439: "<{0}> does not allow any child elements at {1}",
0440: getTagName(), node.getTagName()));
0441: }
0442:
0443: /**
0444: * Adds a child node after its completely initialized..
0445: */
0446: public void addChildEnd(JspNode node) throws JspParseException {
0447: if (node instanceof JspAttribute) {
0448: JspAttribute attr = (JspAttribute) node;
0449:
0450: QName name = attr.getName();
0451:
0452: addAttribute(name, attr);
0453: }
0454: }
0455:
0456: /**
0457: * Called when the tag closes.
0458: */
0459: public void endElement() throws Exception {
0460: }
0461:
0462: /**
0463: * Returns the children.
0464: */
0465: public ArrayList<JspNode> getChildren() {
0466: return null;
0467: }
0468:
0469: /**
0470: * Returns the TagInstance of the enclosing parent.
0471: */
0472: public TagInstance getTag() {
0473: JspNode parent = getParent();
0474:
0475: if (parent != null)
0476: return parent.getTag();
0477: else
0478: return _gen.getRootTag();
0479: }
0480:
0481: /**
0482: * Return true for pre-21 taglib.
0483: */
0484: public boolean isPre21Taglib() {
0485: return false;
0486: }
0487:
0488: /**
0489: * Generates the XML text representation for the tag validation.
0490: *
0491: * @param os write stream to the generated XML.
0492: */
0493: abstract public void printXml(WriteStream os) throws IOException;
0494:
0495: /**
0496: * Prints the jsp:id
0497: */
0498: public void printJspId(WriteStream os) throws IOException {
0499: os.print(" jsp:id=\"" + _gen.generateJspId() + "\"");
0500: }
0501:
0502: /**
0503: * Generates the XML text representation for the tag validation.
0504: *
0505: * @param os write stream to the generated XML.
0506: */
0507: public void printXmlText(WriteStream os, String text)
0508: throws IOException {
0509: os.print(xmlText(text));
0510: }
0511:
0512: /**
0513: * Generates the XML text representation for the tag validation.
0514: *
0515: * @param os write stream to the generated XML.
0516: */
0517: public void printXmlAttribute(WriteStream os, String name,
0518: String text) throws IOException {
0519: os.print(" ");
0520: os.print(name);
0521: os.print("=\"");
0522:
0523: if (text.startsWith("<%=") && text.endsWith("%>")) {
0524: os.print("%=");
0525: os.print(xmlAttrText(text.substring(3, text.length() - 2)));
0526: os.print("%");
0527: } else
0528: os.print(xmlAttrText(text));
0529: os.print("\"");
0530: }
0531:
0532: /**
0533: * Generates the XML text.
0534: */
0535: public String xmlText(String text) {
0536: if (text == null)
0537: return "";
0538:
0539: CharBuffer cb = new CharBuffer();
0540:
0541: for (int i = 0; i < text.length(); i++) {
0542: char ch = text.charAt(i);
0543:
0544: switch (ch) {
0545: case '<':
0546: cb.append("<");
0547: break;
0548: case '>':
0549: cb.append(">");
0550: break;
0551: case '&':
0552: cb.append("&");
0553: break;
0554: case '"':
0555: cb.append(""");
0556: break;
0557: default:
0558: cb.append(ch);
0559: break;
0560: }
0561: }
0562:
0563: return cb.toString();
0564: }
0565:
0566: /**
0567: * Generates the XML text.
0568: */
0569: public String xmlAttrText(String text) {
0570: if (text == null)
0571: return "";
0572:
0573: CharBuffer cb = new CharBuffer();
0574:
0575: for (int i = 0; i < text.length(); i++) {
0576: char ch = text.charAt(i);
0577:
0578: switch (ch) {
0579: case '&':
0580: cb.append("&");
0581: break;
0582: case '<':
0583: cb.append("<");
0584: break;
0585: case '>':
0586: cb.append(">");
0587: break;
0588: case '"':
0589: cb.append(""");
0590: break;
0591: case '\'':
0592: cb.append("'");
0593: break;
0594: default:
0595: cb.append(ch);
0596: break;
0597: }
0598: }
0599:
0600: return cb.toString();
0601: }
0602:
0603: /**
0604: * Generates the start location.
0605: */
0606: public void generateStartLocation(JspJavaWriter out)
0607: throws IOException {
0608: out.setLocation(_filename, _startLine);
0609: }
0610:
0611: /**
0612: * Generates the start location.
0613: */
0614: public void generateEndLocation(JspJavaWriter out)
0615: throws IOException {
0616: out.setLocation(_filename, _endLine);
0617: }
0618:
0619: /**
0620: * generates prologue data.
0621: */
0622: public void generatePrologue(JspJavaWriter out) throws Exception {
0623: generatePrologueChildren(out);
0624: }
0625:
0626: /**
0627: * generates prologue data.
0628: */
0629: public void generatePrologueDeclare(JspJavaWriter out)
0630: throws Exception {
0631: }
0632:
0633: /**
0634: * generates data for prologue children.
0635: */
0636: public void generatePrologueChildren(JspJavaWriter out)
0637: throws Exception {
0638: }
0639:
0640: /**
0641: * generates declaration data.
0642: */
0643: public void generateDeclaration(JspJavaWriter out)
0644: throws IOException {
0645: generateDeclarationChildren(out);
0646: }
0647:
0648: /**
0649: * generates data for declaration children.
0650: */
0651: public void generateDeclarationChildren(JspJavaWriter out)
0652: throws IOException {
0653: }
0654:
0655: /**
0656: * Generates the code for the tag
0657: *
0658: * @param out the output writer for the generated java.
0659: */
0660: abstract public void generate(JspJavaWriter out) throws Exception;
0661:
0662: /**
0663: * Generates the code for the children.
0664: *
0665: * @param out the output writer for the generated java.
0666: */
0667: public void generateChildren(JspJavaWriter out) throws Exception {
0668: }
0669:
0670: /**
0671: * Generates the code for the tag
0672: *
0673: * @param out the output writer for the generated java.
0674: */
0675: public void generateStatic(JspJavaWriter out) throws Exception {
0676: }
0677:
0678: /**
0679: * Generates the code for the tag
0680: *
0681: * @param out the output writer for the generated java.
0682: */
0683: public void generateEmpty() throws Exception {
0684: generateChildrenEmpty();
0685: }
0686:
0687: /**
0688: * Generates the code for the children.
0689: *
0690: * @param out the output writer for the generated java.
0691: */
0692: public void generateChildrenEmpty() throws Exception {
0693: }
0694:
0695: /**
0696: * Converts the string to a boolean.
0697: */
0698: protected boolean attributeToBoolean(String attr, String value)
0699: throws JspParseException {
0700: if (value.equals("yes") || value.equals("true"))
0701: return true;
0702: else if (value.equals("no") || value.equals("false"))
0703: return false;
0704: else
0705: throw error(L
0706: .l(
0707: "'{0}' is an unknown value for {1}. 'true' or 'false' are the expected values.",
0708: value, attr));
0709: }
0710:
0711: /**
0712: * Returns true if in a fragment
0713: */
0714: public boolean isInFragment() {
0715: for (JspNode node = getParent(); node != null; node = node
0716: .getParent()) {
0717: if (node instanceof JspAttribute
0718: || node instanceof CustomSimpleTag)
0719: return true;
0720: }
0721:
0722: return false;
0723: }
0724:
0725: void generateSetParameter(JspJavaWriter out, String obj,
0726: Object objValue, Method method, boolean allowRtexpr,
0727: String contextVar, boolean isFragment,
0728: TagAttributeInfo attrInfo) throws Exception {
0729: Class type = method.getParameterTypes()[0];
0730:
0731: if (isFragment || JspFragment.class.equals(type)) {
0732: generateFragmentParameter(out, obj, objValue, method,
0733: allowRtexpr, contextVar);
0734: return;
0735: }
0736:
0737: if (objValue instanceof JspAttribute) {
0738: JspAttribute attr = (JspAttribute) objValue;
0739:
0740: if (attr.isStatic())
0741: objValue = attr.getStaticText();
0742: else {
0743: String str = "_jsp_str_" + _gen.uniqueId();
0744: out.println("String " + str + " = "
0745: + attr.generateValue() + ";");
0746: out.println(obj + "." + method.getName() + "("
0747: + stringToValue(type, str) + ");");
0748: return;
0749: }
0750: } else if (objValue instanceof JspNode)
0751: throw error(L
0752: .l("jsp:attribute may not set this attribute."));
0753:
0754: String strValue = (String) objValue;
0755:
0756: String convValue = generateParameterValue(type, strValue,
0757: allowRtexpr, attrInfo, _parseState.isELIgnored());
0758:
0759: PropertyEditor editor;
0760:
0761: if (convValue != null)
0762: out.println(obj + "." + method.getName() + "(" + convValue
0763: + ");");
0764: else if ((editor = PropertyEditorManager.findEditor(type)) != null) {
0765: generateSetParameter(out, obj, strValue, method, editor
0766: .getClass());
0767: } else
0768: throw error(L
0769: .l(
0770: "expected '<%= ... %>' at '{0}' for tag attribute setter '{1}'. Tag attributes which can't be converted from strings must use a runtime attribute expression.",
0771: strValue, method.getName() + "("
0772: + type.getName() + ")"));
0773: }
0774:
0775: void generateSetParameter(JspJavaWriter out, String obj,
0776: String value, Method method, Class editorClass)
0777: throws Exception {
0778: Class type = method.getParameterTypes()[0];
0779:
0780: String name = "_jsp_editor" + _gen.uniqueId();
0781: out.print("java.beans.PropertyEditor " + name + " = new "
0782: + editorClass.getName() + "();");
0783: out.println(name + ".setAsText(\"" + escapeJavaString(value)
0784: + "\");");
0785: out.println(obj + "." + method.getName() + "(("
0786: + type.getName() + ") " + name + ".getValue());");
0787: }
0788:
0789: void generateFragmentParameter(JspJavaWriter out, Object obj,
0790: Object objValue, Method method, boolean allowRtexpr,
0791: String contextVar) throws Exception {
0792: out.print(obj + "." + method.getName() + "(");
0793: if (objValue instanceof JspFragmentNode)
0794: generateFragment(out, (JspFragmentNode) objValue,
0795: contextVar);
0796: else if (objValue instanceof String) {
0797: String string = (String) objValue;
0798:
0799: int index = _gen.addExpr(string);
0800:
0801: out
0802: .print("new com.caucho.jsp.ELExprFragment(pageContext, _caucho_expr_"
0803: + index + ")");
0804: } else {
0805: throw error(L.l("can't handle fragment '{0}' of type {1}",
0806: objValue, objValue.getClass()));
0807: }
0808: out.println(");");
0809: }
0810:
0811: String generateFragmentParameter(String string, boolean allowRtexpr)
0812: throws Exception {
0813: int index = _gen.addExpr(string);
0814:
0815: return ("new com.caucho.jsp.ELExprFragment(pageContext, _caucho_expr_"
0816: + index + ")");
0817: }
0818:
0819: /**
0820: * Returns the containing segment.
0821: */
0822: public JspSegmentNode getSegment() {
0823: JspNode parent = getParent();
0824:
0825: if (parent != null)
0826: return parent.getSegment();
0827: else
0828: return null;
0829: }
0830:
0831: void generateFragment(JspJavaWriter out, JspFragmentNode frag,
0832: String contextVar) throws Exception {
0833: out.print(generateFragment(frag, contextVar));
0834: }
0835:
0836: void generateParentTag(JspJavaWriter out, TagInstance parent)
0837: throws IOException {
0838: String parentId = parent.getId();
0839: if (parentId == null || parentId.startsWith("top_")) {
0840: out.print("null");
0841: } else if (parent.isSimpleTag()) {
0842: out.print("(" + parentId + "_adapter != null ? ");
0843: out.print(parentId + "_adapter : ");
0844: out
0845: .print("("
0846: + parentId
0847: + "_adapter = new javax.servlet.jsp.tagext.TagAdapter("
0848: + parentId + ")))");
0849: } else
0850: out.print(parentId);
0851: }
0852:
0853: String generateRTValue(Class type, Object value) throws Exception {
0854: if (value instanceof String)
0855: return generateParameterValue(type, (String) value, true,
0856: null, _parseState.isELIgnored());
0857: else {
0858: JspAttribute attr = (JspAttribute) value;
0859:
0860: return stringToValue(type, attr.generateValue());
0861: }
0862: }
0863:
0864: /**
0865: * Generates the code invoking a fragment to a string.
0866: */
0867: protected String invokeFragment(JspFragmentNode frag)
0868: throws Exception {
0869: return frag.generateValue();
0870: }
0871:
0872: /**
0873: * Generates the code for a fragment.
0874: */
0875: protected String generateFragment(JspFragmentNode frag,
0876: String contextVar) throws Exception {
0877: int index = _gen.addFragment(frag);
0878:
0879: StringBuffer cb = new StringBuffer();
0880:
0881: if (frag.isStatic()) {
0882: String fragmentVar = frag.getFragmentName();
0883:
0884: cb
0885: .append(fragmentVar
0886: + " = com.caucho.jsp.StaticJspFragmentSupport.create("
0887: + fragmentVar + ", " + contextVar + ", \"");
0888:
0889: cb.append(escapeJavaString(frag.getStaticText()));
0890: cb.append("\")");
0891:
0892: return cb.toString();
0893: }
0894:
0895: String fragmentVar = frag.getFragmentName();
0896:
0897: cb
0898: .append(fragmentVar + " = _CauchoFragment.create("
0899: + fragmentVar + ", " + index + ", "
0900: + contextVar + ", ");
0901:
0902: JspNode parentTag = getParentTagNode();
0903:
0904: if (parentTag == null)
0905: cb.append("null");
0906: else if (frag.hasCustomTag()
0907: && parentTag instanceof CustomSimpleTag)
0908: cb.append(parentTag.getCustomTagName() + "_adapter");
0909: else
0910: cb.append(parentTag.getCustomTagName());
0911:
0912: if (_gen instanceof JavaTagGenerator) {
0913: JavaTagGenerator tagGen = (JavaTagGenerator) _gen;
0914:
0915: if (tagGen.isStaticDoTag()) // jsp/1025
0916: cb.append(", _jspBody");
0917: else
0918: cb.append(", getJspBody()");
0919: } else
0920: cb.append(", null");
0921:
0922: cb.append(")");
0923:
0924: return cb.toString();
0925: }
0926:
0927: /**
0928: * Generates the code for the value of a parent tag.
0929: */
0930: protected String generateParentTag(TagInstance parent)
0931: throws IOException {
0932: String parentId = parent.getId();
0933: if (parent.isTop()) {
0934: return "null";
0935: } else if (parent.isSimpleTag()) {
0936: CharBuffer cb = CharBuffer.allocate();
0937:
0938: cb.append("(" + parentId + "_adapter != null ? ");
0939: cb.append(parentId + "_adapter : ");
0940: cb
0941: .append("("
0942: + parentId
0943: + "_adapter = new javax.servlet.jsp.tagext.TagAdapter("
0944: + parentId + ")))");
0945:
0946: return cb.close();
0947: } else
0948: return parentId;
0949: }
0950:
0951: //
0952: // JSF functions
0953: //
0954:
0955: /**
0956: * Returns the variable containing the jsf component
0957: */
0958: public String getJsfVar() {
0959: if (_parent != null)
0960: return _parent.getJsfVar();
0961: else
0962: return null;
0963: }
0964:
0965: /**
0966: * Returns the variable containing the jsf body
0967: */
0968: public String getJsfBodyVar() {
0969: if (_parent != null)
0970: return _parent.getJsfBodyVar();
0971: else
0972: return null;
0973: }
0974:
0975: /**
0976: * True if the jsf-parent setting is required.
0977: */
0978: public boolean isJsfParentRequired() {
0979: return false;
0980: }
0981:
0982: //
0983: // value generation
0984: //
0985:
0986: /**
0987: * Generate include params.
0988: */
0989: void generateIncludeParams(JspJavaWriter out, ArrayList params)
0990: throws Exception {
0991: boolean hasQuery = false;
0992:
0993: for (int i = 0; i < params.size(); i++) {
0994: JspParam param = (JspParam) params.get(i);
0995: String value = param.getValue();
0996:
0997: if (hasQuery)
0998: out.print("+ \"&\" + ");
0999:
1000: hasQuery = true;
1001: out.print("\"" + param.getName() + "=\"");
1002:
1003: String outValue = generateParameterValue(String.class,
1004: value);
1005:
1006: if (outValue.equals("null")) {
1007: } else if (outValue.startsWith("\""))
1008: out.print(" + (" + outValue + ")");
1009: else
1010: out.print(" + com.caucho.el.Expr.toString(" + outValue
1011: + ", null)");
1012: }
1013: }
1014:
1015: String generateJstlValue(Class type, String value) throws Exception {
1016: return generateParameterValue(type, value, true, null, false);
1017: }
1018:
1019: String generateValue(Class type, String value) throws Exception {
1020: return generateParameterValue(type, value, true, null,
1021: _parseState.isELIgnored());
1022: }
1023:
1024: String generateParameterValue(Class type, String value)
1025: throws Exception {
1026: return generateParameterValue(type, value, true, null,
1027: _parseState.isELIgnored());
1028: }
1029:
1030: String generateParameterValue(Class type, String value,
1031: boolean rtexpr, TagAttributeInfo attrInfo,
1032: boolean isELIgnored) throws Exception {
1033: // jsp/1c2m
1034: if (isJstl())
1035: isELIgnored = false;
1036:
1037: boolean isEmpty = value == null || value.equals("");
1038: if (isEmpty)
1039: value = "0";
1040:
1041: try {
1042: if (JspFragment.class.equals(type))
1043: return generateFragmentParameter(value, rtexpr);
1044: else if (type.equals(ValueExpression.class)) {
1045: int exprIndex;
1046:
1047: String typeName = attrInfo != null ? attrInfo
1048: .getExpectedTypeName() : "";
1049:
1050: if (isEmpty)
1051: exprIndex = _gen.addValueExpr("", typeName);
1052: else
1053: exprIndex = _gen.addValueExpr(value, typeName);
1054:
1055: if (value.indexOf("#{") < 0)
1056: return ("_caucho_value_expr_" + exprIndex);
1057: else {
1058: StringBuilder sb = new StringBuilder();
1059:
1060: sb
1061: .append("pageContext.createExpr(_caucho_value_expr_");
1062: sb.append(exprIndex);
1063: sb.append(", \"");
1064: sb.append(escapeJavaString(value));
1065: sb.append("\", ");
1066: if (null == typeName || "".equals(typeName)) {
1067: sb.append("java.lang.Object.class)");
1068: } else {
1069: sb.append(escapeJavaString(typeName));
1070: sb.append(".class)");
1071: }
1072:
1073: return sb.toString();
1074: }
1075: } else if (type.equals(MethodExpression.class)) {
1076: int exprIndex;
1077:
1078: String sig = attrInfo != null ? attrInfo
1079: .getMethodSignature()
1080: : "java.lang.String misc()";
1081:
1082: if (isEmpty)
1083: exprIndex = _gen.addMethodExpr("", sig);
1084: else
1085: exprIndex = _gen.addMethodExpr(value, sig);
1086:
1087: return ("_caucho_method_expr_" + exprIndex);
1088: } else if (com.caucho.el.Expr.class.equals(type)) {
1089: int exprIndex;
1090:
1091: if (isEmpty)
1092: exprIndex = _gen.addExpr("");
1093: else
1094: exprIndex = _gen.addExpr(value);
1095:
1096: return ("_caucho_expr_" + exprIndex);
1097: } else if (com.caucho.xpath.Expr.class.equals(type)) {
1098: int exprIndex;
1099:
1100: com.caucho.xpath.Expr expr;
1101: if (isEmpty)
1102: expr = XPath.parseExpr("");
1103: else
1104: expr = XPath
1105: .parseExpr(value, getNamespaceContext());
1106:
1107: return _gen.addXPathExpr(expr);
1108: } else if (rtexpr && hasRuntimeAttribute(value)) {
1109: return getRuntimeAttribute(value);
1110: } else if (rtexpr && hasELAttribute(value, isELIgnored)) {
1111: // jsp/0138, jsp/18s0, jsp/1ce5, jsp/1e0a
1112: return generateELValue(type, value);
1113: } else if (!rtexpr && hasELAttribute(value, isELIgnored)) {
1114: // JSP.2.3.6 says this is an error
1115: // jsp/184v vs jsp/18cr vs jsp/18f5
1116: // #2112
1117:
1118: if (String.class.equals(type))
1119: return '"' + escapeJavaString(value) + '"';
1120: else
1121: throw error(L
1122: .l(
1123: "EL expression '{0}' is only allowed for attributes with rtexprvalue='true'.",
1124: value));
1125: } else if (rtexpr && hasDeferredAttribute(value, false)) {
1126: // jsp/1c2m, jsp/1ce8
1127: return generateELValue(type, value);
1128: } else if (!rtexpr
1129: && hasDeferredAttribute(value, isELIgnored)
1130: && !_gen.getParseState()
1131: .isDeferredSyntaxAllowedAsLiteral()) {
1132: throw error(L
1133: .l(
1134: "Deferred syntax '{0}' is not allowed as a literal.",
1135: value));
1136: } else if (type.equals(boolean.class))
1137: return String.valueOf(Boolean.valueOf(isEmpty ? "false"
1138: : value));
1139: else if (type.equals(Boolean.class)) {
1140: if (isEmpty)
1141: return "java.lang.Boolean.FALSE";
1142: else
1143: return "new java.lang.Boolean("
1144: + Boolean.valueOf(value) + ")";
1145: } else if (type.equals(byte.class))
1146: return "(byte) " + Byte.valueOf(value);
1147: else if (type.equals(Byte.class))
1148: return "new java.lang.Byte((byte) "
1149: + Byte.valueOf(value) + ")";
1150: else if (type.equals(char.class)) {
1151: if (isEmpty)
1152: return "'\\0'";
1153: else
1154: return "'" + value.charAt(0) + "'";
1155: } else if (type.equals(Character.class)) {
1156: if (isEmpty)
1157: return "new java.lang.Character('\\0')";
1158: else
1159: return ("new Character('" + value.charAt(0) + "')");
1160: } else if (type.equals(short.class))
1161: return ("(short) " + Short.valueOf(value));
1162: else if (type.equals(Short.class))
1163: return ("new java.lang.Short((short) "
1164: + Short.valueOf(value) + ")");
1165: else if (type.equals(int.class))
1166: return String.valueOf(Integer.valueOf(value));
1167: else if (type.equals(Integer.class))
1168: return ("new java.lang.Integer("
1169: + Integer.valueOf(value) + ")");
1170: else if (type.equals(long.class))
1171: return String.valueOf(Long.valueOf(value));
1172: else if (type.equals(Long.class))
1173: return ("new java.lang.Long(" + Long.valueOf(value) + ")");
1174: else if (type.equals(float.class))
1175: return ("(float) " + Float.valueOf(value));
1176: else if (type.equals(Float.class))
1177: return ("new java.lang.Float((float) "
1178: + Float.valueOf(value) + ")");
1179: else if (type.equals(double.class))
1180: return String.valueOf(Double.valueOf(value));
1181: else if (type.equals(Double.class)) {
1182: double v = Double.valueOf(value);
1183:
1184: if (Double.isNaN(v))
1185: return ("new java.lang.Double(Double.NaN)");
1186: else
1187: return ("new java.lang.Double(" + v + ")");
1188: } else if (!type.equals(String.class)
1189: && !type.equals(Object.class)) {
1190: return null;
1191: } else if (!isEmpty) {
1192: return '"' + escapeJavaString(value) + '"';
1193: } else
1194: return "\"\"";
1195: } catch (NumberFormatException e) {
1196: throw error(L.l("parameter format error: {0}", e
1197: .getMessage()), e);
1198: }
1199: }
1200:
1201: protected String generateELValue(Class type, String value)
1202: throws Exception {
1203: if (type.equals(com.caucho.el.Expr.class)) {
1204: int exprIndex;
1205:
1206: exprIndex = _gen.addExpr(value);
1207:
1208: return ("_caucho_expr_" + exprIndex);
1209: } else if (type.equals(ValueExpression.class)) {
1210: int exprIndex;
1211:
1212: exprIndex = _gen.addValueExpr(value, "");
1213:
1214: return ("_caucho_value_expr_" + exprIndex);
1215: } else if (type.equals(com.caucho.xpath.Expr.class)) {
1216: com.caucho.xpath.Expr expr;
1217:
1218: expr = XPath.parseExpr(value, getNamespaceContext());
1219:
1220: return _gen.addXPathExpr(expr);
1221: }
1222:
1223: Expr expr = _gen.genExpr(value);
1224:
1225: if (expr.isConstant()) {
1226: try {
1227: if (expr.evalObject(null) != null) {
1228: } else if (Character.class.isAssignableFrom(type)) {
1229: // jsp/18s0
1230: return "new Character((char) 0)";
1231: } else if (Boolean.class.isAssignableFrom(type)) {
1232: // jsp/18s1
1233: return "Boolean.FALSE";
1234: } else if (String.class.isAssignableFrom(type)) {
1235: // jsp/18s2
1236: return "\"\"";
1237: } else if (BigInteger.class.isAssignableFrom(type)) {
1238: return "java.math.BigInteger.ZERO";
1239: } else if (BigDecimal.class.isAssignableFrom(type)) {
1240: return "java.math.BigDecimal.ZERO";
1241: } else if (Number.class.isAssignableFrom(type)) {
1242: // jsp/18s6
1243: return "new " + type.getName() + "((byte) 0)";
1244: } else if (Object.class.isAssignableFrom(type))
1245: return "null";
1246:
1247: if (boolean.class.equals(type))
1248: return expr.evalBoolean(null) ? "true" : "false";
1249: else if (Boolean.class.equals(type))
1250: return expr.evalBoolean(null) ? "java.lang.Boolean.TRUE"
1251: : "java.lang.Boolean.FALSE";
1252: else if (byte.class.equals(type))
1253: return "(byte) " + expr.evalLong(null);
1254: else if (Byte.class.equals(type))
1255: return "new java.lang.Byte((byte) "
1256: + expr.evalLong(null) + "L)";
1257: else if (short.class.equals(type))
1258: return "(short) " + expr.evalLong(null);
1259: else if (Short.class.equals(type))
1260: return "new java.lang.Short((short) "
1261: + expr.evalLong(null) + "L)";
1262: else if (int.class.equals(type))
1263: return "(int) " + expr.evalLong(null);
1264: else if (Integer.class.equals(type))
1265: return "new java.lang.Integer((int) "
1266: + expr.evalLong(null) + "L)";
1267: else if (long.class.equals(type))
1268: return "" + expr.evalLong(null) + "L";
1269: else if (Long.class.equals(type))
1270: return "new java.lang.Long(" + expr.evalLong(null)
1271: + "L)";
1272: else if (float.class.equals(type))
1273: return "(float) " + expr.evalDouble(null);
1274: else if (Float.class.equals(type))
1275: return "new java.lang.Float((float) "
1276: + expr.evalDouble(null) + ")";
1277: else if (double.class.equals(type)) {
1278: double v = expr.evalDouble(null);
1279:
1280: if (Double.isNaN(v))
1281: return "Double.NaN";
1282: else
1283: return "" + v;
1284: } else if (Double.class.equals(type)) {
1285: double v = expr.evalDouble(null);
1286:
1287: if (Double.isNaN(v))
1288: return "new Double(Double.NaN)";
1289: else
1290: return "new java.lang.Double(" + v + ")";
1291: } else if (char.class.equals(type))
1292: return "((char) " + (int) expr.evalCharacter(null)
1293: + ")";
1294: else if (Character.class.equals(type)) {
1295: // jsp/18s0
1296: return "new Character((char) "
1297: + (int) expr.evalCharacter(null) + ")";
1298: } else if (String.class.equals(type))
1299: return "\""
1300: + escapeJavaString(expr.evalString(null))
1301: + "\"";
1302: else if (BigInteger.class.equals(type)) {
1303: String v = expr.evalBigInteger(null).toString();
1304:
1305: // 18s3
1306: if (v.equals("") || v.equals("0"))
1307: return "java.math.BigInteger.ZERO";
1308: else
1309: return "new java.math.BigInteger(\"" + v
1310: + "\")";
1311: } else if (BigDecimal.class.equals(type)) {
1312: String v = expr.evalBigDecimal(null).toString();
1313:
1314: // 18s4
1315: if (v.equals("") || v.equals("0.0"))
1316: return "java.math.BigDecimal.ZERO";
1317: else
1318: return "new java.math.BigDecimal(\"" + v
1319: + "\")";
1320: } else if (Object.class.equals(type)) {
1321: Object cValue = expr.evalObject(null);
1322:
1323: String result = generateObject(cValue);
1324:
1325: if (result != null)
1326: return result;
1327: } else {
1328: Object cValue = expr.evalObject(null);
1329:
1330: // jsp/184t
1331: if ("".equals(cValue))
1332: return "null";
1333: }
1334: } catch (Throwable e) {
1335: // jsp/18co
1336: // exceptions are caught at runtime
1337: log.log(Level.FINER, e.toString(), e);
1338:
1339: log.fine(e.getMessage());
1340: }
1341: }
1342:
1343: int exprIndex = _gen.addExpr(value);
1344: String var = "_caucho_expr_" + exprIndex;
1345:
1346: if (boolean.class.equals(type))
1347: return var + ".evalBoolean(_jsp_env)";
1348: else if (Boolean.class.equals(type))
1349: return var
1350: + ".evalBoolean(_jsp_env) ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE";
1351: else if (byte.class.equals(type))
1352: return "(byte) " + var + ".evalLong(_jsp_env)";
1353: else if (Byte.class.equals(type))
1354: return "new java.lang.Byte((byte) " + var
1355: + ".evalLong(_jsp_env))";
1356: else if (short.class.equals(type))
1357: return "(short) " + var + ".evalLong(_jsp_env)";
1358: else if (Short.class.equals(type))
1359: return "new java.lang.Short((short) " + var
1360: + ".evalLong(_jsp_env))";
1361: else if (int.class.equals(type))
1362: return "(int) " + var + ".evalLong(_jsp_env)";
1363: else if (Integer.class.equals(type))
1364: return "new java.lang.Integer((int) " + var
1365: + ".evalLong(_jsp_env))";
1366: else if (long.class.equals(type))
1367: return var + ".evalLong(_jsp_env)";
1368: else if (Long.class.equals(type))
1369: return "new java.lang.Long(" + var + ".evalLong(_jsp_env))";
1370: else if (float.class.equals(type))
1371: return "(float) " + var + ".evalDouble(_jsp_env)";
1372: else if (Float.class.equals(type))
1373: return "new java.lang.Float((float) " + var
1374: + ".evalDouble(_jsp_env))";
1375: else if (double.class.equals(type))
1376: return var + ".evalDouble(_jsp_env)";
1377: else if (Double.class.equals(type))
1378: return "new java.lang.Double(" + var
1379: + ".evalDouble(_jsp_env))";
1380: else if (java.math.BigDecimal.class.equals(type))
1381: return "" + var + ".evalBigDecimal(_jsp_env)";
1382: else if (java.math.BigInteger.class.equals(type))
1383: return "" + var + ".evalBigInteger(_jsp_env)";
1384: else if (char.class.equals(type))
1385: return var + ".evalCharacter(_jsp_env)";
1386: else if (Character.class.equals(type))
1387: return "new Character(" + var + ".evalCharacter(_jsp_env))";
1388: else if (String.class.equals(type))
1389: return var + ".evalString(_jsp_env)";
1390: else if (BigInteger.class.equals(type))
1391: return var + ".evalBigInteger(_jsp_env)";
1392: else if (BigDecimal.class.equals(type))
1393: return var + ".evalBigDecimal(_jsp_env)";
1394: else if (Object.class.equals(type))
1395: return var + ".evalObject(_jsp_env)";
1396: else {
1397: return "(" + classToString(type) + ") " + var
1398: + ".evalObject(_jsp_env)";
1399: }
1400: }
1401:
1402: public void convertParameterValue(JspJavaWriter out, String type,
1403: String value) throws IOException {
1404: if (type.equals("boolean"))
1405: out.print("java.lang.Boolean.TRUE.equals(" + value + ")");
1406: else if (type.equals("byte"))
1407: out.print("java.lang.Byte.valueOf(" + value + ")");
1408: else if (type.equals("char"))
1409: out.print("java.lang.Character.valueOf(" + value + ")");
1410: else if (type.equals("short"))
1411: out.print("java.lang.Short.valueOf(" + value + ")");
1412: else if (type.equals("int"))
1413: out.print("((java.lang.Integer) " + value + ").intValue()");
1414: else if (type.equals("long"))
1415: out.print("((java.lang.Long) " + value + ").longValue()");
1416: else if (type.equals("float"))
1417: out.print("((java.lang.Float) " + value + ").floatValue()");
1418: else if (type.equals("double"))
1419: out.print("((java.lang.Double) " + value
1420: + ").doubleValue()");
1421: else
1422: out.print("(" + type + ")" + value);
1423: }
1424:
1425: protected String classToString(Class cl) {
1426: if (cl.isArray())
1427: return classToString(cl.getComponentType()) + "[]";
1428: else
1429: return cl.getName();
1430: }
1431:
1432: /**
1433: * Returns true if the value is a runtime attribute.
1434: */
1435: public boolean hasRuntimeAttribute(String value)
1436: throws JspParseException {
1437: if (_parseState.isScriptingInvalid()) {
1438: // && value.indexOf("<%=") >= 0) {
1439: return false;
1440: /*
1441: throw error(L.l("Runtime expressions are forbidden here. Scripting has been disabled either:\n1) disabled by the web.xml scripting-invalid\n2) disabled in a tag's descriptor\n3) forbidden in <jsp:attribute> or <jsp:body> tags."));
1442: */
1443: }
1444:
1445: if (value.startsWith("<%=") && value.endsWith("%>"))
1446: return true;
1447: else if (value.startsWith("%=") && value.endsWith("%"))
1448: return true;
1449: else if (value.indexOf("<%=") >= 0
1450: && value.indexOf("<%=") < value.indexOf("%>"))
1451: throw error(L
1452: .l(
1453: "interpolated runtime values are forbidden by the JSP spec at '{0}'",
1454: value));
1455: else
1456: return false;
1457: }
1458:
1459: /**
1460: * Returns true if the string has scripting.
1461: */
1462: public boolean hasScripting(String value) {
1463: try {
1464: return value != null && hasRuntimeAttribute(value);
1465: } catch (Exception e) {
1466: throw new RuntimeException(e);
1467: }
1468: }
1469:
1470: /**
1471: * Returns true if the string has scripting.
1472: */
1473: public boolean hasScripting(JspAttribute value) {
1474: return value != null && value.hasScripting();
1475: }
1476:
1477: /**
1478: * Returns true if the value is a runtime attribute.
1479: */
1480: public boolean hasELAttribute(String value) {
1481: return !_parseState.isELIgnored() && value.indexOf("${") >= 0;
1482: }
1483:
1484: /**
1485: * Returns true if the value is a runtime attribute.
1486: */
1487: public boolean hasDeferredAttribute(String value) {
1488: if (value.indexOf("#{") < 0)
1489: return false;
1490: else if (isPre21Taglib())
1491: return false;
1492: else
1493: return !_parseState.isELIgnored();
1494: }
1495:
1496: /**
1497: * Returns true if the value is a runtime attribute.
1498: */
1499: public boolean hasELAttribute(String value, boolean isELIgnored) {
1500: return !isELIgnored && value.indexOf("${") >= 0;
1501: }
1502:
1503: /**
1504: * Returns true if the value is a runtime attribute.
1505: */
1506: public boolean hasDeferredAttribute(String value,
1507: boolean isELIgnored) {
1508: if (isELIgnored)
1509: return false;
1510: else if (value.indexOf("#{") < 0)
1511: return false;
1512: else if (isPre21Taglib())
1513: return false;
1514: else
1515: return true;
1516: }
1517:
1518: /**
1519: * Returns the runtime attribute of the value.
1520: */
1521: public String getRuntimeAttribute(String value) throws Exception {
1522: if (value.startsWith("<%=") && value.endsWith("%>"))
1523: return value.substring(3, value.length() - 2);
1524: else if (value.startsWith("%=") && value.endsWith("%"))
1525: return value.substring(2, value.length() - 1);
1526: else
1527: return value;
1528: }
1529:
1530: /**
1531: * Converts a string-valued expression to the given type.
1532: */
1533: String stringToValue(Class type, String obj) {
1534: if (boolean.class.equals(type))
1535: return "com.caucho.jsp.PageContextImpl.toBoolean(" + obj
1536: + ")";
1537: else if (Boolean.class.equals(type))
1538: return "java.lang.Boolean.valueOf(" + obj + ")";
1539: else if (byte.class.equals(type))
1540: return "java.lang.Byte.parseByte(" + obj + ")";
1541: else if (Byte.class.equals(type))
1542: return "java.lang.Byte.valueOf(" + obj + ")";
1543: else if (char.class.equals(type))
1544: return obj + ".charAt(0)";
1545: else if (Character.class.equals(type))
1546: return "new java.lang.Character(" + obj + ".charAt(0))";
1547: else if (short.class.equals(type))
1548: return "java.lang.Short.parseShort(" + obj + ")";
1549: else if (Short.class.equals(type))
1550: return "java.lang.Short.valueOf(" + obj + ")";
1551: else if (int.class.equals(type))
1552: return "java.lang.Integer.parseInt(" + obj + ")";
1553: else if (Integer.class.equals(type))
1554: return "java.lang.Integer.valueOf(" + obj + ")";
1555: else if (long.class.equals(type))
1556: return "java.lang.Long.parseLong(" + obj + ")";
1557: else if (Long.class.equals(type))
1558: return "java.lang.Long.valueOf(" + obj + ")";
1559: else if (float.class.equals(type))
1560: return "java.lang.Float.parseFloat(" + obj + ")";
1561: else if (Float.class.equals(type))
1562: return "java.lang.Float.valueOf(" + obj + ")";
1563: else if (double.class.equals(type))
1564: return "java.lang.Double.parseDouble(" + obj + ")";
1565: else if (Double.class.equals(type))
1566: return "java.lang.Double.valueOf(" + obj + ")";
1567: else if (type.isAssignableFrom(String.class))
1568: return obj;
1569: else
1570: return null;
1571: }
1572:
1573: protected String generateObject(Object obj) {
1574: if (obj instanceof String)
1575: return "\"" + escapeJavaString((String) obj) + "\"";
1576: else if (obj instanceof Long)
1577: return "new java.lang.Long(" + obj + "L)";
1578: else if (obj instanceof Integer)
1579: return "new java.lang.Integer((int) " + obj + "L)";
1580: else if (obj instanceof Double) {
1581: double v = (Double) obj;
1582:
1583: if (Double.isNaN(v))
1584: return "new java.lang.Double(Double.NaN)";
1585: else
1586: return "new java.lang.Double(" + v + ")";
1587: } else if (obj instanceof Boolean)
1588: return ((Boolean) obj).booleanValue() ? "java.lang.Boolean.TRUE"
1589: : "java.lang.Boolean.FALSE";
1590: else
1591: return null;
1592: }
1593:
1594: public static String toELObject(String expr, Class type) {
1595: if (boolean.class.equals(type))
1596: return "((" + expr + ") ? Boolean.TRUE : Boolean.FALSE)";
1597: else if (byte.class.equals(type))
1598: return "new Long(" + expr + ")";
1599: else if (short.class.equals(type))
1600: return "new Long(" + expr + ")";
1601: else if (int.class.equals(type))
1602: return "new Long(" + expr + ")";
1603: else if (long.class.equals(type))
1604: return "new Long(" + expr + ")";
1605: else if (float.class.equals(type))
1606: return "new Double(" + expr + ")";
1607: else if (double.class.equals(type))
1608: return "new Double(" + expr + ")";
1609: else if (char.class.equals(type))
1610: return "String.valueOf(" + expr + ")";
1611: else
1612: return expr;
1613: }
1614:
1615: /**
1616: * Escapes a java string.
1617: */
1618: public static String escapeJavaString(String s) {
1619: if (s == null)
1620: return "";
1621:
1622: CharBuffer cb = CharBuffer.allocate();
1623: for (int i = 0; i < s.length(); i++) {
1624: if (s.charAt(i) == '\\')
1625: cb.append("\\\\");
1626: else if (s.charAt(i) == '"')
1627: cb.append("\\\"");
1628: else if (s.charAt(i) == '\n')
1629: cb.append("\\n");
1630: else if (s.charAt(i) == '\r')
1631: cb.append("\\r");
1632: else
1633: cb.append(s.charAt(i));
1634: }
1635:
1636: return cb.close();
1637: }
1638:
1639: protected Class loadClass(String type) throws JspParseException {
1640: if (type == null)
1641: return null;
1642: else {
1643: try {
1644: return _gen.getBeanClass(type);
1645: } catch (Exception e) {
1646: throw new JspParseException(e);
1647: }
1648: }
1649: }
1650:
1651: /**
1652: * Creates a parse exception with the proper line information.
1653: */
1654: protected JspParseException error(String msg) {
1655: return error(msg, null);
1656: }
1657:
1658: /**
1659: * Creates a parse exception with the proper line information.
1660: */
1661: protected JspParseException error(String msg, Throwable e) {
1662: if (_filename != null) {
1663: String lines = _gen.getSourceLines(_sourcePath, _startLine);
1664:
1665: return new JspLineParseException(_filename + ":"
1666: + _startLine + ": " + msg + lines, e);
1667: } else
1668: return new JspParseException(msg, e);
1669: }
1670:
1671: /**
1672: * Creates a parse exception with the proper line information.
1673: */
1674: protected JspParseException error(Throwable e) {
1675: if (e instanceof JspLineParseException)
1676: return (JspParseException) e;
1677: else if (_filename == null || e instanceof LineCompileException)
1678: return new JspLineParseException(e);
1679:
1680: String msg;
1681:
1682: if (e instanceof CompileException)
1683: msg = e.getMessage();
1684: else
1685: msg = String.valueOf(e);
1686:
1687: String lines = _gen.getSourceLines(_sourcePath, _startLine);
1688:
1689: return new JspLineParseException(_filename + ":" + _startLine
1690: + ": " + msg + lines, e);
1691: }
1692:
1693: /**
1694: * Returns a printable version of the node.
1695: */
1696: public String toString() {
1697: if (_name == null)
1698: return "<" + getClass().getName() + ">";
1699: else
1700: return "<" + _name.getName() + ">";
1701: }
1702: }
|