1 package net.sf.saxon.functions; 2 3 import net.sf.saxon.expr.Expression; 4 import net.sf.saxon.expr.StaticContext; 5 import net.sf.saxon.expr.StaticProperty; 6 import net.sf.saxon.om.NamespaceConstant; 7 import net.sf.saxon.pattern.NodeKindTest; 8 import net.sf.saxon.trans.StaticError; 9 import net.sf.saxon.trans.XPathException; 10 import net.sf.saxon.type.ItemType; 11 import net.sf.saxon.type.Type; 12 import net.sf.saxon.Err; 13 14 import java.util.HashMap ; 15 16 21 22 public class VendorFunctionLibrary implements FunctionLibrary { 23 24 private HashMap functionTable; 25 26 public VendorFunctionLibrary() { 27 init(); 28 } 29 30 42 43 protected StandardFunction.Entry register( String name, 44 Class implementationClass, 45 int opcode, 46 int minArguments, 47 int maxArguments, 48 ItemType itemType, 49 int cardinality ) { 50 StandardFunction.Entry e = StandardFunction.makeEntry( 51 name, implementationClass, opcode, minArguments, maxArguments, itemType, cardinality); 52 functionTable.put(name, e); 53 return e; 54 } 55 56 protected void init() { 57 functionTable = new HashMap (30); 58 StandardFunction.Entry e; 59 e = register("evaluate", Evaluate.class, Evaluate.EVALUATE, 1, 10, Type.ITEM_TYPE, StaticProperty.ALLOWS_ZERO_OR_MORE); 60 StandardFunction.arg(e, 0, Type.STRING_TYPE, StaticProperty.EXACTLY_ONE); 61 62 e = register("evaluate-node", Evaluate.class, Evaluate.EVALUATE_NODE, 1, 1, Type.ITEM_TYPE, StaticProperty.ALLOWS_ZERO_OR_MORE); 63 StandardFunction.arg(e, 0, Type.NODE_TYPE, StaticProperty.EXACTLY_ONE); 64 65 e = register("eval", Evaluate.class, Evaluate.EVAL, 1, 10, Type.ITEM_TYPE, StaticProperty.ALLOWS_ZERO_OR_MORE); 66 StandardFunction.arg(e, 0, Type.ANY_ATOMIC_TYPE, StaticProperty.EXACTLY_ONE); 67 68 e = register("expression", Evaluate.class, Evaluate.EXPRESSION, 1, 1, Type.ANY_ATOMIC_TYPE, StaticProperty.EXACTLY_ONE); 69 StandardFunction.arg(e, 0, Type.STRING_TYPE, StaticProperty.EXACTLY_ONE); 70 71 e = register("parse", Parse.class, 0, 1, 1, NodeKindTest.DOCUMENT, StaticProperty.EXACTLY_ONE); 72 StandardFunction.arg(e, 0, Type.STRING_TYPE, StaticProperty.EXACTLY_ONE); 73 74 e = register("serialize", Serialize.class, 0, 2, 2, Type.STRING_TYPE, StaticProperty.EXACTLY_ONE); 75 StandardFunction.arg(e, 0, Type.NODE_TYPE, StaticProperty.ALLOWS_ZERO_OR_ONE); 76 StandardFunction.arg(e, 1, Type.STRING_TYPE, StaticProperty.EXACTLY_ONE); 77 78 } 79 80 90 91 public boolean isAvailable(int fingerprint, String uri, String local, int arity) { 92 if (uri.equals(NamespaceConstant.SAXON)) { 93 StandardFunction.Entry entry = (StandardFunction.Entry)functionTable.get(local); 94 if (entry == null) { 95 return false; 96 } 97 return (arity == -1 || 98 (arity >= entry.minArguments && arity <= entry.maxArguments)); 99 } else { 100 return false; 101 } 102 } 103 104 120 121 public Expression bind(int nameCode, String uri, String local, Expression[] staticArgs) 122 throws XPathException { 123 if (uri.equals(NamespaceConstant.SAXON)) { 124 StandardFunction.Entry entry = (StandardFunction.Entry)functionTable.get(local); 125 if (entry == null) { 126 return null; 127 } 128 Class functionClass = entry.implementationClass; 129 SystemFunction f; 130 try { 131 f = (SystemFunction)functionClass.newInstance(); 132 } catch (Exception err) { 133 throw new AssertionError ("Failed to load Saxon extension function: " + err.getMessage()); 134 } 135 f.setDetails(entry); 136 f.setFunctionNameCode(nameCode); 137 f.setArguments(staticArgs); 138 checkArgumentCount(staticArgs.length, entry.minArguments, entry.maxArguments, local); 139 return f; 140 } else { 141 return null; 142 } 143 } 144 145 148 149 public Expression makeSaxonFunction(String localName, StaticContext env, Expression[] arguments) 150 throws XPathException { 151 String uri = NamespaceConstant.SAXON; 152 int nameCode = env.getNamePool().allocate("saxon", uri, localName); 153 return bind(nameCode, uri, localName, arguments); 154 } 155 156 164 165 private int checkArgumentCount(int numArgs, int min, int max, String local) throws XPathException { 166 if (min==max && numArgs != min) { 167 throw new StaticError("Function " + Err.wrap("saxon:"+local, Err.FUNCTION) + " must have " 168 + min + pluralArguments(min)); 169 } 170 if (numArgs < min) { 171 throw new StaticError("Function " + Err.wrap("saxon:"+local, Err.FUNCTION) + " must have at least " 172 + min + pluralArguments(min)); 173 } 174 if (numArgs > max) { 175 throw new StaticError("Function " + Err.wrap("saxon:"+local, Err.FUNCTION) + " must have no more than " 176 + max + pluralArguments(max)); 177 } 178 return numArgs; 179 } 180 181 184 185 public static String pluralArguments(int num) { 186 if (num==1) return " argument"; 187 return " arguments"; 188 } 189 190 197 198 public FunctionLibrary copy() { 199 return this; 200 } 201 } 202 | Popular Tags |