package client.net.sf.saxon.ce.functions; import client.net.sf.saxon.ce.Configuration; import client.net.sf.saxon.ce.Version; import client.net.sf.saxon.ce.expr.Expression; import client.net.sf.saxon.ce.expr.ExpressionVisitor; import client.net.sf.saxon.ce.expr.StringLiteral; import client.net.sf.saxon.ce.expr.XPathContext; import client.net.sf.saxon.ce.lib.NamespaceConstant; import client.net.sf.saxon.ce.om.Item; import client.net.sf.saxon.ce.om.NamespaceResolver; import client.net.sf.saxon.ce.om.StructuredQName; import client.net.sf.saxon.ce.trans.XPathException; import client.net.sf.saxon.ce.value.StringValue; /** * Implementation of the XSLT system-property() function */ public class SystemProperty extends SystemFunction { public SystemProperty newInstance() { return new SystemProperty(); } private NamespaceResolver nsContext; private StructuredQName propertyName; private transient boolean checked = false; // the second time checkArguments is called, it's a global check so the static context is inaccurate public void checkArguments(ExpressionVisitor visitor) throws XPathException { if (checked) return; checked = true; super.checkArguments(visitor); if (argument[0] instanceof StringLiteral) { try { propertyName = StructuredQName.fromLexicalQName( ((StringLiteral)argument[0]).getStringValue(), false, visitor.getStaticContext().getNamespaceResolver()); } catch (XPathException e) { String code = e.getErrorCodeLocalPart(); if (code==null || code.equals("FOCA0002") || code.equals("FONS0004")) { e.setErrorCode("XTDE1390"); throw e; } } // Don't actually read the system property yet, it might be different at run-time } else { // we need to save the namespace context nsContext = visitor.getStaticContext().getNamespaceResolver(); } } /** * preEvaluate: this method performs compile-time evaluation for properties in the XSLT namespace only * @param visitor an expression visitor */ public Expression preEvaluate(ExpressionVisitor visitor) throws XPathException { if (propertyName != null && NamespaceConstant.XSLT.equals(propertyName.getNamespaceURI())) { return new StringLiteral( getProperty(NamespaceConstant.XSLT, propertyName.getLocalName(), visitor.getConfiguration())); } else { return this; } } /** * Evaluate the function at run-time */ public Item evaluateItem(XPathContext context) throws XPathException { StructuredQName qName = propertyName; if (qName == null) { CharSequence name = argument[0].evaluateItem(context).getStringValueCS(); try { qName = StructuredQName.fromLexicalQName(name, false, nsContext); } catch (XPathException err) { dynamicError("Invalid system property name. " + err.getMessage(), "XTDE1390", context); return null; } } return new StringValue(getProperty( qName.getNamespaceURI(), qName.getLocalName(), context.getConfiguration())); } /** * Here's the real code: * @param uri the namespace URI of the system property name * @param local the local part of the system property name * @param config the Saxon configuration * @return the value of the corresponding system property */ public static String getProperty(String uri, String local, Configuration config) { if (uri.equals(NamespaceConstant.XSLT)) { if (local.equals("version")) { return Version.getXSLVersionString(); } else if (local.equals("vendor")) { return Version.getProductTitle(); } else if (local.equals("vendor-url")) { return Version.getWebSiteAddress(); } else if (local.equals("product-name")) { return Version.getProductName(); } else if (local.equals("product-version")) { return Version.getProductVariantAndVersion(); } else if (local.equals("supports-serialization")) { return "yes"; } else if (local.equals("supports-backwards-compatibility")) { return "yes"; } else if (local.equals("supports-namespace-axis")) { // Erratum E14 return "yes"; } else if (local.equals("is-schema-aware")) { return "no"; } return ""; } else { return ""; } } } // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. // If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0.