1 16 19 20 package org.apache.xalan.xsltc.compiler; 21 22 import java.lang.reflect.Method ; 23 import java.lang.reflect.Modifier ; 24 import java.util.Vector ; 25 26 import org.apache.bcel.generic.ConstantPoolGen; 27 import org.apache.bcel.generic.PUSH; 28 import org.apache.xalan.xsltc.compiler.util.ClassGenerator; 29 import org.apache.xalan.xsltc.compiler.util.ErrorMsg; 30 import org.apache.xalan.xsltc.compiler.util.MethodGenerator; 31 import org.apache.xalan.xsltc.compiler.util.Type; 32 import org.apache.xalan.xsltc.compiler.util.TypeCheckError; 33 import org.apache.xalan.xsltc.compiler.util.Util; 34 35 39 final class FunctionAvailableCall extends FunctionCall { 40 41 private Expression _arg; 42 private String _nameOfFunct = null; 43 private String _namespaceOfFunct = null; 44 private boolean _isFunctionAvailable = false; 45 46 52 public FunctionAvailableCall(QName fname, Vector arguments) { 53 super(fname, arguments); 54 _arg = (Expression)arguments.elementAt(0); 55 _type = null; 56 57 if (_arg instanceof LiteralExpr) { 58 LiteralExpr arg = (LiteralExpr) _arg; 59 _namespaceOfFunct = arg.getNamespace(); 60 _nameOfFunct = arg.getValue(); 61 62 if (!isInternalNamespace()) { 63 _isFunctionAvailable = hasMethods(); 64 } 65 } 66 } 67 68 72 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 73 if (_type != null) { 74 return _type; 75 } 76 if (_arg instanceof LiteralExpr) { 77 return _type = Type.Boolean; 78 } 79 ErrorMsg err = new ErrorMsg(ErrorMsg.NEED_LITERAL_ERR, 80 "function-available", this); 81 throw new TypeCheckError(err); 82 } 83 84 89 public Object evaluateAtCompileTime() { 90 return getResult() ? Boolean.TRUE : Boolean.FALSE; 91 } 92 93 97 private boolean hasMethods() { 98 LiteralExpr arg = (LiteralExpr)_arg; 99 100 String className = getClassNameFromUri(_namespaceOfFunct); 102 103 String methodName = null; 105 int colonIndex = _nameOfFunct.indexOf(":"); 106 if (colonIndex > 0) { 107 String functionName = _nameOfFunct.substring(colonIndex+1); 108 int lastDotIndex = functionName.lastIndexOf('.'); 109 if (lastDotIndex > 0) { 110 methodName = functionName.substring(lastDotIndex+1); 111 if (className != null && !className.equals("")) 112 className = className + "." + functionName.substring(0, lastDotIndex); 113 else 114 className = functionName.substring(0, lastDotIndex); 115 } 116 else 117 methodName = functionName; 118 } 119 else 120 methodName = _nameOfFunct; 121 122 if (className == null || methodName == null) { 123 return false; 124 } 125 126 if (methodName.indexOf('-') > 0) 128 methodName = replaceDash(methodName); 129 130 try { 131 final Class clazz = ObjectFactory.findProviderClass( 132 className, ObjectFactory.findClassLoader(), true); 133 134 if (clazz == null) { 135 return false; 136 } 137 138 final Method [] methods = clazz.getMethods(); 139 140 for (int i = 0; i < methods.length; i++) { 141 final int mods = methods[i].getModifiers(); 142 143 if (Modifier.isPublic(mods) && Modifier.isStatic(mods) 144 && methods[i].getName().equals(methodName)) 145 { 146 return true; 147 } 148 } 149 } 150 catch (ClassNotFoundException e) { 151 return false; 152 } 153 return false; 154 } 155 156 160 public boolean getResult() { 161 if (_nameOfFunct == null) { 162 return false; 163 } 164 165 if (isInternalNamespace()) { 166 final Parser parser = getParser(); 167 _isFunctionAvailable = 168 parser.functionSupported(Util.getLocalName(_nameOfFunct)); 169 } 170 return _isFunctionAvailable; 171 } 172 173 176 private boolean isInternalNamespace() { 177 return (_namespaceOfFunct == null || 178 _namespaceOfFunct.equals(EMPTYSTRING) || 179 _namespaceOfFunct.equals(TRANSLET_URI)); 180 } 181 182 187 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 188 final ConstantPoolGen cpg = classGen.getConstantPool(); 189 methodGen.getInstructionList().append(new PUSH(cpg, getResult())); 190 } 191 192 } 193 | Popular Tags |