kinman 2003/03/24 16:07:12 Modified: jasper2/src/share/org/apache/jasper/compiler ELFunctionMapper.java ELNode.java Validator.java jasper2/src/share/org/apache/jasper/resources messages.properties Log: - Implement a FunctionMapper to be used in parseExpression, for checking expression syntax. Refactor some codes dealing with signature parsing, so that it can be used in both Validator and ELFunctionMapper. Revision Changes Path 1.3 +10 -52 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/ELFunctionMapper.java Index: ELFunctionMapper.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/ELFunctionMapper.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- ELFunctionMapper.java 21 Mar 2003 00:43:57 -0000 1.2 +++ ELFunctionMapper.java 25 Mar 2003 00:07:10 -0000 1.3 @@ -185,64 +185,22 @@ String key = f.getPrefix()+ ":" + f.getName(); ds.append(" " + decName + ".mapFunction(\"" + key + "\", " + funcInfo.getFunctionClass() + ".class, " + - '\"' + getMethod(f) + "\", " + - "new Class[] {" + getParameters(f) + "}" + - ");\n"); + '\"' + f.getMethodName() + "\", " + + "new Class[] {"); + String params[] = f.getParameters(); + for (int k = 0; k < params.length; k++) { + if (k != 0) { + ds.append(", "); + } + ds.append(params[k] + ".class"); + } + ds.append("});\n"); } el.setMapName(decName); } private String getMapName() { return "_jspx_fnmap_" + currFunc++; - } - - private String getMethod(ELNode.Function func) - throws JasperException { - FunctionInfo funcInfo = func.getFunctionInfo(); - String signature = funcInfo.getFunctionSignature(); - - int start = signature.indexOf(' '); - if (start < 0) { - err.jspError("jsp.error.tld.fn.invalid.signature", - func.getPrefix(), func.getName()); - } - int end = signature.indexOf('('); - if (end < 0) { - err.jspError("jsp.error.tld.fn.invalid.signature.parenexpected", - func.getPrefix(), func.getName()); - } - return signature.substring(start+1, end).trim(); - } - - private String getParameters(ELNode.Function func) - throws JasperException { - FunctionInfo funcInfo = func.getFunctionInfo(); - StringBuffer buf = new StringBuffer(); - String signature = funcInfo.getFunctionSignature(); - // Signature is of the form - // <return-type> S <method-name S? '(' - // < <arg-type> ( ',' <arg-type> )* )? ')' - int start = signature.indexOf('(') + 1; - boolean lastArg = false; - while (true) { - int p = signature.indexOf(',', start); - if (p < 0) { - p = signature.indexOf(')', start); - if (p < 0) { - err.jspError("jsp.error.tld.fn.invalid.signature", - func.getPrefix(), func.getName()); - } - lastArg = true; - } - String arg = signature.substring(start, p).trim(); - buf.append(arg + ".class"); - if (lastArg) { - break; - } - buf.append(','); - start = p+1; - } - return buf.toString(); } } } 1.2 +21 -3 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/ELNode.java Index: ELNode.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/ELNode.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ELNode.java 19 Mar 2003 20:51:34 -0000 1.1 +++ ELNode.java 25 Mar 2003 00:07:10 -0000 1.2 @@ -143,9 +143,11 @@ */ public static class Function extends ELNode { - String prefix; - String name; - FunctionInfo functionInfo; + private String prefix; + private String name; + private FunctionInfo functionInfo; + private String methodName; + private String[] parameters; Function(String prefix, String name) { this.prefix = prefix; @@ -170,6 +172,22 @@ public FunctionInfo getFunctionInfo() { return functionInfo; + } + + public void setMethodName(String methodName) { + this.methodName = methodName; + } + + public String getMethodName() { + return methodName; + } + + public void setParameters(String[] parameters) { + this.parameters = parameters; + } + + public String[] getParameters() { + return parameters; } } 1.96 +133 -8 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Validator.java Index: Validator.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Validator.java,v retrieving revision 1.95 retrieving revision 1.96 diff -u -r1.95 -r1.96 --- Validator.java 24 Mar 2003 23:50:40 -0000 1.95 +++ Validator.java 25 Mar 2003 00:07:10 -0000 1.96 @@ -62,6 +62,7 @@ import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.Hashtable; import java.util.HashMap; import java.util.Enumeration; @@ -666,16 +667,16 @@ // a null FunctionMapper is passed. if ( !pageInfo.isELIgnored() ) { String expressions = "${" + new String(n.getText()) + "}"; + ELNode.Nodes el = ELParser.parse(expressions); + validateFunctions(el, n); JspUtil.validateExpressions( n.getStart(), expressions, java.lang.String.class, // XXX - Should template text // always evaluate to String? - null, + getFunctionMapper(el), null, err); - ELNode.Nodes el = ELParser.parse(expressions); - validateFunctions(el, n); n.setEL(el); } } @@ -1096,15 +1097,15 @@ // expression(s) ELNode.Nodes el = ELParser.parse(value); if (el.containsEL() && !pageInfo.isELIgnored()) { + validateFunctions(el, n); JspUtil.validateExpressions( n.getStart(), value, expectedType, - null, + getFunctionMapper(el), defaultPrefix, this.err); - validateFunctions(el, n); result = new Node.JspAttribute(qName, uri, localName, value, false, el, @@ -1249,10 +1250,134 @@ } // Skip TLD function uniqueness check. Done by Schema ? func.setFunctionInfo(funcInfo); + processSignature(func); } } el.visit(new FVVisitor(n)); + } + + private void processSignature(ELNode.Function func) + throws JasperException { + func.setMethodName(getMethod(func)); + func.setParameters(getParameters(func)); + } + + /** + * Get the method name from the signature. + */ + private String getMethod(ELNode.Function func) + throws JasperException { + FunctionInfo funcInfo = func.getFunctionInfo(); + String signature = funcInfo.getFunctionSignature(); + + int start = signature.indexOf(' '); + if (start < 0) { + err.jspError("jsp.error.tld.fn.invalid.signature", + func.getPrefix(), func.getName()); + } + int end = signature.indexOf('('); + if (end < 0) { + err.jspError("jsp.error.tld.fn.invalid.signature.parenexpected", + func.getPrefix(), func.getName()); + } + return signature.substring(start+1, end).trim(); + } + + /** + * Get the parameters types from the function signature. + * @return An array of parameter class names + */ + private String[] getParameters(ELNode.Function func) + throws JasperException { + FunctionInfo funcInfo = func.getFunctionInfo(); + String signature = funcInfo.getFunctionSignature(); + ArrayList params = new ArrayList(); + // Signature is of the form + // <return-type> S <method-name S? '(' + // < <arg-type> ( ',' <arg-type> )* )? ')' + int start = signature.indexOf('(') + 1; + boolean lastArg = false; + while (true) { + int p = signature.indexOf(',', start); + if (p < 0) { + p = signature.indexOf(')', start); + if (p < 0) { + err.jspError("jsp.error.tld.fn.invalid.signature", + func.getPrefix(), func.getName()); + } + lastArg = true; + } + params.add(signature.substring(start, p).trim()); + if (lastArg) { + break; + } + start = p+1; + } + return (String[]) params.toArray(new String[params.size()]); + } + + private FunctionMapper getFunctionMapper(ELNode.Nodes el) + throws JasperException { + + class ValidateFunctionMapper implements FunctionMapper { + + private HashMap fnmap = new java.util.HashMap(); + public void mapFunction(String fnQName, Method method) { + fnmap.put(fnQName, method); + } + + public Method resolveFunction(String prefix, String localName) { + return (Method) this.fnmap.get(prefix + ":" + localName); + } + } + + class MapperELVisitor extends ELNode.Visitor { + ValidateFunctionMapper fmapper; + + MapperELVisitor(ValidateFunctionMapper fmapper) { + this.fmapper = fmapper; + } + + public void visit(ELNode.Function n) throws JasperException { + + Class c = null; + Method method = null; + try { + c = loader.loadClass( + n.getFunctionInfo().getFunctionClass()); + } catch (ClassNotFoundException e) { + err.jspError("jsp.error.function.classnotfound", + n.getFunctionInfo().getFunctionClass(), + n.getPrefix() + ':' + n.getName(), + e.getMessage()); + } + String paramTypes[] = n.getParameters(); + int size = paramTypes.length; + Class params[] = new Class[size]; + int i = 0; + try { + for (i = 0; i < size; i++) { + params[i] = JspUtil.toClass(paramTypes[i], loader); + } + method = c.getDeclaredMethod(n.getMethodName(), params); + } catch (ClassNotFoundException e) { + err.jspError("jsp.error.signature.classnotfound", + paramTypes[i], + n.getPrefix() + ':' + n.getName(), + e.getMessage()); + } catch (NoSuchMethodException e ) { + err.jspError("jsp.error.noMethod", n.getName(), + n.getMethodName(), c.getName()); + } + fmapper.mapFunction(n.getPrefix() + ':' + n.getName(), + method); + } + } + + ValidateFunctionMapper fmapper = new ValidateFunctionMapper(); + el.visit(new MapperELVisitor(fmapper)); + return fmapper; } } // End of ValidateVisitor 1.108 +2 -1 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/resources/messages.properties Index: messages.properties =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/resources/messages.properties,v retrieving revision 1.107 retrieving revision 1.108 diff -u -r1.107 -r1.108 --- messages.properties 24 Mar 2003 23:50:41 -0000 1.107 +++ messages.properties 25 Mar 2003 00:07:12 -0000 1.108 @@ -375,3 +375,4 @@ jsp.error.jsproot.version.invalid=Invalid version number: \"{0}\", must be \"1.2\" or \"2.0\" jsp.error.noFunctionPrefix=The function {0} must be used with a prefix when a default namespace is not specified jsp.error.noFunction=The function {0} cannot be located with the specified prefix +jsp.error.noFunctionMethod=The method {0} for the function {1} is not defined in the class {2}
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]