1 package net.sf.saxon.functions; 2 import net.sf.saxon.expr.Expression; 3 import net.sf.saxon.expr.StaticContext; 4 import net.sf.saxon.expr.XPathContext; 5 import net.sf.saxon.om.*; 6 import net.sf.saxon.style.StyleNodeFactory; 7 import net.sf.saxon.style.XSLTStaticContext; 8 import net.sf.saxon.trans.StaticError; 9 import net.sf.saxon.trans.XPathException; 10 import net.sf.saxon.value.*; 11 import net.sf.saxon.Configuration; 12 13 16 17 public class Available extends SystemFunction implements XSLTFunction { 18 19 public static final int ELEMENT_AVAILABLE = 0; 20 public static final int FUNCTION_AVAILABLE = 1; 21 22 private transient NamespaceResolver nsContext; 23 private transient StyleNodeFactory styleNodeFactory; 24 private transient boolean checked = false; 25 27 public void checkArguments(StaticContext env) throws XPathException { 28 if (checked) return; 29 checked = true; 30 super.checkArguments(env); 31 if (!(argument[0] instanceof Value && 32 (argument.length==1 || argument[1] instanceof Value))) { 33 nsContext = env.getNamespaceResolver(); 35 } 36 } 37 38 42 43 public Expression preEvaluate(StaticContext env) throws XPathException { 44 String qname = ((StringValue)argument[0]).getStringValue(); 45 46 boolean b = false; 47 switch(operation) { 48 case ELEMENT_AVAILABLE: 49 b = ((XSLTStaticContext)env).isElementAvailable(qname); 50 break; 51 case FUNCTION_AVAILABLE: 52 long arity = -1; 53 if (argument.length == 2) { 54 arity = ((NumericValue)argument[1].evaluateItem(null)).longValue(); 55 } 56 try { 58 String [] parts = Name.getQNameParts(qname); 59 String prefix = parts[0]; 60 String uri; 61 if (prefix.equals("")) { 62 uri = env.getDefaultFunctionNamespace(); 63 } else { 64 uri = env.getURIForPrefix(prefix); 65 } 66 int fingerprint = env.getNamePool().allocate(prefix, uri, parts[1]) & 0xfffff; 67 b = env.getFunctionLibrary().isAvailable(fingerprint, uri, parts[1], (int)arity); 68 } catch (QNameException e) { 69 throw new StaticError(e.getMessage()); 70 } 71 break; 72 } 73 return BooleanValue.get(b); 74 } 75 76 81 82 public Item evaluateItem(XPathContext context) throws XPathException { 83 AtomicValue av1 = (AtomicValue)argument[0].evaluateItem(context); 84 long arity = -1; 85 if (argument.length == 2) { 86 arity = ((NumericValue)argument[1].evaluateItem(context)).longValue(); 87 } 88 StringValue nameValue = (StringValue)av1.getPrimitiveValue(); 89 String name = nameValue.getStringValue(); 90 String [] parts = null; 91 try { 92 parts = Name.getQNameParts(name); 93 } catch (QNameException e) { 94 String code = (operation == FUNCTION_AVAILABLE ? "XTDE1400" : "XTDE1440"); 95 dynamicError(e.getMessage(), code, context); 96 } 97 String prefix = parts[0]; 98 String lname = parts[1]; 99 String uri; 100 if (prefix.equals("")) { 101 if (operation==ELEMENT_AVAILABLE) { 102 uri = nsContext.getURIForPrefix(prefix, true); 104 } else { 105 uri = NamespaceConstant.FN; 106 } 107 } else { 108 uri = nsContext.getURIForPrefix(prefix, false); 109 } 110 if (uri==null) { 111 dynamicError("Namespace prefix '" + prefix + "' has not been declared", context); 112 } 113 114 boolean b = false; 115 switch(operation) { 116 case ELEMENT_AVAILABLE: 117 b = isElementAvailable(uri, lname, context); 118 break; 119 case FUNCTION_AVAILABLE: 120 final int fingerprint = context.getController().getNamePool().allocate(prefix, uri, lname) & 0xfffff; 121 final FunctionLibrary lib = context.getController().getExecutable().getFunctionLibrary(); 122 b = lib.isAvailable(fingerprint, uri, lname, (int)arity); 123 break; 124 } 125 return BooleanValue.get(b); 126 127 } 128 129 135 136 155 160 161 private boolean isElementAvailable(String uri, String localname, XPathContext context) { 162 163 167 170 try { 171 if (styleNodeFactory==null) { 172 Configuration config = context.getController().getConfiguration(); 173 styleNodeFactory = 175 new StyleNodeFactory ( 176 config); 177 } 178 return styleNodeFactory.isElementAvailable(uri, localname); 179 } catch (Exception err) { 180 return false; 182 } 183 } 184 185 } 186 187 188 189 | Popular Tags |