1 package net.sf.saxon.functions; 2 3 import net.sf.saxon.expr.Expression; 4 import net.sf.saxon.om.NamespaceConstant; 5 import net.sf.saxon.trans.StaticError; 6 import net.sf.saxon.trans.XPathException; 7 import net.sf.saxon.Err; 8 9 14 15 public class SystemFunctionLibrary implements FunctionLibrary { 16 17 private int functionSet; 18 19 public static final int XPATH_ONLY = 0; 20 public static final int FULL_XSLT = 1; 21 public static final int USE_WHEN = 2; 22 23 28 29 public SystemFunctionLibrary(int functionSet) { 30 this.functionSet = functionSet; 31 } 32 33 43 44 public boolean isAvailable(int fingerprint, String uri, String local, int arity) { 45 if (uri.equals(NamespaceConstant.FN)) { 46 StandardFunction.Entry entry = StandardFunction.getFunction(local, arity); 47 if (entry == null) { 48 return false; 49 } 50 return (arity == -1 || 51 (arity >= entry.minArguments && arity <= entry.maxArguments)); 52 } else { 53 return false; 54 } 55 } 56 57 73 74 public Expression bind(int nameCode, String uri, String local, Expression[] staticArgs) 75 throws XPathException { 76 if (uri.equals(NamespaceConstant.FN)) { 77 StandardFunction.Entry entry = StandardFunction.getFunction(local, staticArgs.length); 78 if (entry == null) { 79 if (StandardFunction.getFunction(local, -1) == null) { 80 StaticError err = new StaticError("Unknown system function " + local + "()"); 81 err.setErrorCode("XPST0017"); 82 throw err; 83 } else { 84 StaticError err = new StaticError("System function " + local + "() cannot be called with " 85 + pluralArguments(staticArgs.length)); 86 err.setErrorCode("XPST0017"); 87 throw err; 88 } 89 } 90 Class functionClass = entry.implementationClass; 91 SystemFunction f; 92 try { 93 f = (SystemFunction)functionClass.newInstance(); 94 } catch (Exception err) { 95 throw new AssertionError ("Failed to load system function: " + err.getMessage()); 96 } 97 f.setDetails(entry); 98 f.setFunctionNameCode(nameCode); 99 if (functionSet != FULL_XSLT) { 100 if (f instanceof XSLTFunction || (f instanceof NamePart && entry.opcode==NamePart.GENERATE_ID)) { 101 if (functionSet == XPATH_ONLY) { 102 StaticError err = new StaticError( 103 "Cannot use the " + local + "() function in a non-XSLT context"); 104 err.setErrorCode("XPST0017"); 105 throw err; 106 } else if (functionSet == USE_WHEN && 107 !(f instanceof Available || f instanceof SystemProperty)) { 108 StaticError err = new StaticError( 109 "Cannot use the " + local + "() function in a use-when expression"); 110 err.setErrorCode("XPST0017"); 111 throw err; 112 } 113 } 114 } 115 f.setArguments(staticArgs); 116 checkArgumentCount(staticArgs.length, entry.minArguments, entry.maxArguments, local); 117 return f; 118 } else { 119 return null; 120 } 121 } 122 123 131 132 private int checkArgumentCount(int numArgs, int min, int max, String local) throws XPathException { 133 if (min==max && numArgs != min) { 134 throw new StaticError("Function " + Err.wrap(local, Err.FUNCTION) + " must have " 135 + min + pluralArguments(min)); 136 } 137 if (numArgs < min) { 138 throw new StaticError("Function " + Err.wrap(local, Err.FUNCTION) + " must have at least " 139 + min + pluralArguments(min)); 140 } 141 if (numArgs > max) { 142 throw new StaticError("Function " + Err.wrap(local, Err.FUNCTION) + " must have no more than " 143 + max + pluralArguments(max)); 144 } 145 return numArgs; 146 } 147 148 151 152 private static String pluralArguments(int num) { 153 if (num==1) return " argument"; 154 return " arguments"; 155 } 156 157 164 165 public FunctionLibrary copy() { 166 return this; 167 } 168 } 169 | Popular Tags |