package client.net.sf.saxon.ce.functions;
import client.net.sf.saxon.ce.expr.*;
import client.net.sf.saxon.ce.om.DocumentPool;
import client.net.sf.saxon.ce.tree.util.FastStringBuffer;
import client.net.sf.saxon.ce.om.Item;
import client.net.sf.saxon.ce.om.NodeInfo;
import client.net.sf.saxon.ce.trans.XPathException;
import client.net.sf.saxon.ce.type.Type;
import client.net.sf.saxon.ce.value.AnyURIValue;
import client.net.sf.saxon.ce.value.QNameValue;
import client.net.sf.saxon.ce.value.StringValue;
/**
* This class supports the name(), local-name(), and namespace-uri() functions
* from XPath 1.0, and also the XSLT generate-id() function
*/
public class NamePart extends SystemFunction {
public NamePart(int operation) {
this.operation = operation;
}
public NamePart newInstance() {
return new NamePart(operation);
}
public static final int NAME = 0;
public static final int LOCAL_NAME = 1;
public static final int NAMESPACE_URI = 2;
public static final int GENERATE_ID = 3;
public static final int DOCUMENT_URI = 4;
public static final int NODE_NAME = 6;
/**
* Simplify and validate.
* @param visitor an expression visitor
*/
public Expression simplify(ExpressionVisitor visitor) throws XPathException {
useContextItemAsDefault();
return simplifyArguments(visitor);
}
/**
* Determine the special properties of this expression. The generate-id()
* function is a special case: it is considered creative if its operand
* is creative, so that generate-id(f()) is not taken out of a loop
*/
public int computeSpecialProperties() {
int p = super.computeSpecialProperties();
if (operation == GENERATE_ID) {
return p & ~StaticProperty.NON_CREATIVE;
} else {
return p;
}
}
@Override
public int computeDependencies() {
return super.computeDependencies();
}
/**
* Evaluate the function in a string context
*/
public Item evaluateItem(XPathContext c) throws XPathException {
NodeInfo node = (NodeInfo)argument[0].evaluateItem(c);
if (node==null) {
// Effect of supplying an empty sequence as the argument differs depending on the function
if (operation == NODE_NAME || operation == DOCUMENT_URI ) {
return null;
} else if (operation == NAMESPACE_URI) {
return AnyURIValue.EMPTY_URI;
} else {
return StringValue.EMPTY_STRING;
}
}
String s;
switch (operation) {
case NAME:
s = node.getDisplayName();
break;
case LOCAL_NAME:
s = node.getLocalPart();
break;
case NAMESPACE_URI:
String uri = node.getURI();
s = (uri==null ? "" : uri);
// null should no longer be returned, but the spec has changed, so it's
// better to be defensive
return new AnyURIValue(s);
case GENERATE_ID:
FastStringBuffer buffer = new FastStringBuffer(FastStringBuffer.TINY);
node.generateId(buffer);
buffer.condense();
return new StringValue(buffer);
case DOCUMENT_URI:
// If the node is in the document pool, get the URI under which it is registered.
// Otherwise, return its systemId.
return getDocumentURI(node, c);
case NODE_NAME:
int nc = node.getNameCode();
if (nc == -1) {
return null;
}
return new QNameValue(node.getNamePool(), nc);
default:
throw new UnsupportedOperationException("Unknown name operation");
}
return new StringValue(s);
}
public static AnyURIValue getDocumentURI(NodeInfo node, XPathContext c) {
if (node.getNodeKind() == Type.DOCUMENT) {
DocumentPool pool = c.getController().getDocumentPool();
String docURI = pool.getDocumentURI(node);
if (docURI == null) {
docURI = node.getSystemId();
}
if (docURI == null) {
return null;
} else if ("".equals(docURI)) {
return null;
} else {
return new AnyURIValue(docURI);
}
} else {
return null;
}
}
/**
* Test whether an expression is a call on the generate-id() function
* @param exp the expression to be tested
* @return true if exp is a call on generate-id(), else false
*/
public static boolean isGenerateIdFunction(Expression exp) {
return ((exp instanceof NamePart) && ((NamePart)exp).operation == GENERATE_ID);
}
}
// 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.