001: package net.sf.saxon.functions;
002:
003: import net.sf.saxon.expr.Expression;
004: import net.sf.saxon.expr.StaticContext;
005: import net.sf.saxon.expr.StaticProperty;
006: import net.sf.saxon.expr.XPathContext;
007: import net.sf.saxon.om.Item;
008: import net.sf.saxon.om.NodeInfo;
009: import net.sf.saxon.om.DocumentPool;
010: import net.sf.saxon.trans.XPathException;
011: import net.sf.saxon.value.QNameValue;
012: import net.sf.saxon.value.StringValue;
013: import net.sf.saxon.value.AnyURIValue;
014: import net.sf.saxon.type.Type;
015:
016: /**
017: * This class supports the name(), local-name(), and namespace-uri() functions
018: * from XPath 1.0, and also the XSLT generate-id() function
019: */
020:
021: public class NamePart extends SystemFunction {
022:
023: public static final int NAME = 0;
024: public static final int LOCAL_NAME = 1;
025: public static final int NAMESPACE_URI = 2;
026: public static final int GENERATE_ID = 3;
027: public static final int DOCUMENT_URI = 4;
028: public static final int NODE_NAME = 6;
029:
030: /**
031: * Simplify and validate.
032: */
033:
034: public Expression simplify(StaticContext env) throws XPathException {
035: useContextItemAsDefault();
036: return simplifyArguments(env);
037: }
038:
039: /**
040: * Determine the special properties of this expression. The generate-id()
041: * function is a special case: it is considered creative if its operand
042: * is creative, so that generate-id(f()) is not taken out of a loop
043: */
044:
045: public int computeSpecialProperties() {
046: int p = super .computeSpecialProperties();
047: if (operation == GENERATE_ID) {
048: return p & ~StaticProperty.NON_CREATIVE;
049: } else {
050: return p;
051: }
052: }
053:
054: /**
055: * Evaluate the function in a string context
056: */
057:
058: public Item evaluateItem(XPathContext c) throws XPathException {
059: NodeInfo node = (NodeInfo) argument[0].evaluateItem(c);
060: if (node == null) {
061: // Effect of supplying an empty sequence as the argument differs depending on the function
062: if (operation == NODE_NAME || operation == DOCUMENT_URI) {
063: return null;
064: } else if (operation == NAMESPACE_URI) {
065: return AnyURIValue.EMPTY_URI;
066: } else {
067: return StringValue.EMPTY_STRING;
068: }
069: }
070:
071: String s;
072: switch (operation) {
073: case NAME:
074: s = node.getDisplayName();
075: break;
076: case LOCAL_NAME:
077: s = node.getLocalPart();
078: break;
079: case NAMESPACE_URI:
080: String uri = node.getURI();
081: s = (uri == null ? "" : uri);
082: // null should no longer be returned, but the spec has changed, so it's
083: // better to be defensive
084: return new AnyURIValue(s);
085: case GENERATE_ID:
086: s = node.generateId();
087: break;
088: case DOCUMENT_URI:
089: if (node.getNodeKind() == Type.DOCUMENT) {
090: DocumentPool pool = c.getController().getDocumentPool();
091: String docURI = pool.getDocumentURI(node);
092: if (docURI == null) {
093: return null;
094: } else {
095: return StringValue.makeStringValue(docURI);
096: }
097: } else {
098: return null;
099: }
100: case NODE_NAME:
101: int nc = node.getNameCode();
102: if (nc == -1) {
103: return null;
104: }
105: return new QNameValue(node.getNamePool(), nc);
106: default:
107: throw new UnsupportedOperationException(
108: "Unknown name operation");
109: }
110: return new StringValue(s);
111: }
112:
113: /**
114: * Test whether an expression is a call on the generate-id() function
115: * @param exp the expression to be tested
116: * @return true if exp is a call on generate-id(), else false
117: */
118:
119: public static boolean isGenerateIdFunction(Expression exp) {
120: return ((exp instanceof NamePart) && ((NamePart) exp).operation == GENERATE_ID);
121: }
122: }
123:
124: //
125: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
126: // you may not use this file except in compliance with the License. You may obtain a copy of the
127: // License at http://www.mozilla.org/MPL/
128: //
129: // Software distributed under the License is distributed on an "AS IS" basis,
130: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
131: // See the License for the specific language governing rights and limitations under the License.
132: //
133: // The Original Code is: all this file.
134: //
135: // The Initial Developer of the Original Code is Michael H. Kay.
136: //
137: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
138: //
139: // Contributor(s): none.
140: //
|