001: package net.sf.saxon.trans;
002:
003: import net.sf.saxon.Configuration;
004: import net.sf.saxon.expr.Binding;
005: import net.sf.saxon.expr.BindingReference;
006: import net.sf.saxon.expr.VariableDeclaration;
007: import net.sf.saxon.expr.XPathContext;
008: import net.sf.saxon.om.ValueRepresentation;
009: import net.sf.saxon.value.EmptySequence;
010: import net.sf.saxon.value.QNameValue;
011: import net.sf.saxon.value.SequenceType;
012: import net.sf.saxon.value.Value;
013:
014: import java.io.Serializable;
015:
016: /**
017: * An object representing an XPath variable for use in the standalone XPath API. The object
018: * can only be created by calling the declareVariable method of class StandaloneContext.
019: */
020:
021: public final class Variable implements VariableDeclaration, Binding,
022: Serializable {
023:
024: private QNameValue name;
025: private ValueRepresentation value;
026: private Configuration config;
027:
028: /**
029: * Private constructor: for use only by the protected factory method make()
030: */
031:
032: private Variable() {
033: };
034:
035: /**
036: * Factory method, for use by the declareVariable method of class StandaloneContext
037: */
038:
039: public static Variable make(QNameValue name, Configuration config) {
040: Variable v = new Variable();
041: v.name = name;
042: v.config = config;
043: return v;
044: }
045:
046: /**
047: * Factory method, retained for backwards compatibility
048: * @param qname the lexical QName of the variable name
049: * @deprecated since 8.5: use {@link #make(QNameValue, Configuration)}
050: */
051:
052: public static Variable make(String qname, Configuration config)
053: throws XPathException {
054: Variable v = new Variable();
055: int colon = qname.indexOf(':');
056: if (colon < 0) {
057: v.name = new QNameValue("", "", qname, config
058: .getNameChecker());
059: } else {
060: v.name = new QNameValue(qname.substring(0, colon),
061: "http://saxon.sf.net/", qname.substring(colon + 1),
062: config.getNameChecker());
063: }
064: v.config = config;
065: return v;
066: }
067:
068: /**
069: * Indicate whether the binding is local or global. A global binding is one that has a fixed
070: * value for the life of a query or transformation; any other binding is local.
071: */
072:
073: public boolean isGlobal() {
074: return true;
075: }
076:
077: /**
078: * Test whether it is permitted to assign to the variable using the saxon:assign
079: * extension element. This will only be for an XSLT global variable where the extra
080: * attribute saxon:assignable="yes" is present.
081: */
082:
083: public final boolean isAssignable() {
084: return false;
085: }
086:
087: /**
088: * If this is a local variable held on the local stack frame, return the corresponding slot number.
089: * In other cases, return -1.
090: */
091:
092: public int getLocalSlotNumber() {
093: return -1;
094: }
095:
096: /**
097: * Get the name of the variable. Used for diagnostic purposes only.
098: * @return the name of the variable, as a string (containing the raw QName)
099: */
100:
101: public String getVariableName() {
102: return name.toString();
103: }
104:
105: /**
106: * Establish the nameCode of the name of this variable.
107: * @return the nameCode
108: */
109:
110: public int getNameCode() {
111: return name.allocateNameCode(config.getNamePool());
112: }
113:
114: /**
115: * Assign a value to the variable. This value may be changed between successive evaluations of
116: * a compiled XPath expression that references the variable.
117: * @param value the value of the variable, as a Java object. This is converted to the "best fit"
118: * XPath data type.
119: * @throws net.sf.saxon.trans.XPathException if the Java value cannot be converted to an XPath type
120: */
121:
122: public void setValue(Object value) throws XPathException {
123: this .value = Value.convertJavaObjectToXPath(value,
124: SequenceType.ANY_SEQUENCE, config);
125: if (this .value == null) {
126: this .value = EmptySequence.getInstance();
127: }
128: }
129:
130: /**
131: * Assign a value to the variable. This value may be changed between successive evaluations of
132: * a compiled XPath expression that references the variable.
133: * @param value the value of the variable, which must be an instance of a class
134: * representing a value in the XPath model.
135: */
136:
137: public void setXPathValue(ValueRepresentation value) {
138: this .value = value;
139: if (this .value == null) {
140: this .value = EmptySequence.getInstance();
141: }
142: }
143:
144: /**
145: * Method called by the XPath expression parser to register a reference to this variable.
146: * This method should not be called by users of the API.
147: */
148:
149: public void registerReference(BindingReference ref) {
150: ref.setStaticType(SequenceType.ANY_SEQUENCE, null, 0);
151: ref.fixup(this );
152: }
153:
154: /**
155: * Get the value of the variable. This method is used by the XPath execution engine
156: * to retrieve the value.
157: * @param context The dynamic evaluation context
158: * @return The value of the variable
159: */
160:
161: public ValueRepresentation evaluateVariable(XPathContext context) {
162: return value;
163: }
164: }
165:
166: //
167: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
168: // you may not use this file except in compliance with the License. You may obtain a copy of the
169: // License at http://www.mozilla.org/MPL/
170: //
171: // Software distributed under the License is distributed on an "AS IS" basis,
172: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
173: // See the License for the specific language governing rights and limitations under the License.
174: //
175: // The Original Code is: all this file.
176: //
177: // The Initial Developer of the Original Code is Michael H. Kay
178: //
179: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
180: //
181: // Contributor(s): none.
182: //
|