KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > instruct > Bindery


1 package net.sf.saxon.instruct;
2 import net.sf.saxon.expr.TypeChecker;
3 import net.sf.saxon.expr.XPathContext;
4 import net.sf.saxon.om.ValueRepresentation;
5 import net.sf.saxon.trans.DynamicError;
6 import net.sf.saxon.trans.XPathException;
7 import net.sf.saxon.type.AtomicType;
8 import net.sf.saxon.type.ItemType;
9 import net.sf.saxon.value.AtomicValue;
10 import net.sf.saxon.value.EmptySequence;
11 import net.sf.saxon.value.ValidationErrorValue;
12 import net.sf.saxon.value.Value;
13
14
15 /**
16 * The Bindery class holds information about variables and their values. From Saxon 8.1, it is
17 * used only for global variables: local variables are now held in the XPathContext object.
18 *
19 * Variables are identified by a Binding object. Values will always be of class Value.
20 */

21
22 public final class Bindery {
23
24     private ValueRepresentation[] globals; // values of global variables and parameters
25
private boolean[] busy; // set to true while variable is being evaluated
26
private GlobalParameterSet globalParameters; // supplied global parameters
27
private SlotManager globalVariableMap; // contains the mapping of variable names to slot numbers
28

29     /**
30     * Define how many slots are needed for global variables
31     */

32
33     public void allocateGlobals(SlotManager map) {
34         globalVariableMap = map;
35         int n = map.getNumberOfVariables()+1;
36         globals = new ValueRepresentation[n];
37         busy = new boolean[n];
38         for (int i=0; i<n; i++) {
39             globals[i] = null;
40             busy[i] = false;
41         }
42     }
43
44     /**
45     * Define global parameters
46     * @param params The ParameterSet passed in by the user, eg. from the command line
47     */

48
49     public void defineGlobalParameters(GlobalParameterSet params) {
50         globalParameters = params;
51     }
52
53     /**
54     * Use global parameter. This is called when a global xsl:param element is processed.
55     * If a parameter of the relevant name was supplied, it is bound to the xsl:param element.
56     * Otherwise the method returns false, so the xsl:param default will be evaluated.
57     * @param fingerprint The fingerprint of the parameter
58     * @param binding The XSLParam element to bind its value to
59     * @return true if a parameter of this name was supplied, false if not
60     */

61
62     public boolean useGlobalParameter(int fingerprint, GlobalParam binding, XPathContext context) throws XPathException {
63         int slot = binding.getSlotNumber();
64         if (globals[slot] != null) {
65             return true;
66         }
67
68         if (globalParameters==null) {
69             return false;
70         }
71         Object JavaDoc obj = globalParameters.get(fingerprint);
72         if (obj==null) {
73             return false;
74         }
75
76         Value val;
77         try {
78             val = Value.convertJavaObjectToXPath(
79                     obj, binding.getRequiredType(), context.getController().getConfiguration());
80             if (val==null) {
81                 val = EmptySequence.getInstance();
82             }
83         } catch (XPathException err) {
84             err.setLocator(binding);
85             throw err;
86         }
87
88         ItemType reqItemType = binding.getRequiredType().getPrimaryType();
89         if (val instanceof AtomicValue && reqItemType instanceof AtomicType) {
90             // If the parameter is an atomic value, typically a string supplied on
91
// the command line, we attempt to convert it to the required type. This
92
// will not always succeed.
93
val = ((AtomicValue)val).convert((AtomicType)reqItemType, context, true);
94             if (val instanceof ValidationErrorValue) {
95                 throw ((ValidationErrorValue)val).getException();
96             }
97         } else {
98             // For any other parameter value, we verify that if conforms to the
99
// required type. This must be precise conformance, we don't attempt to
100
// do atomization or to convert untypedAtomic values
101
DynamicError err = TypeChecker.testConformance(val, binding.getRequiredType());
102             if (err != null) {
103                 throw err;
104             }
105         }
106         globals[slot] = val;
107         return true;
108     }
109
110     /**
111     * Provide a value for a global variable
112     * @param binding identifies the variable
113     * @param value the value of the variable
114     */

115
116     public void defineGlobalVariable(GlobalVariable binding, ValueRepresentation value) {
117         globals[binding.getSlotNumber()] = value;
118     }
119
120     /**
121     * Set/Unset a flag to indicate that a particular global variable is currently being
122     * evaluated.
123     * @throws net.sf.saxon.trans.XPathException If an attempt is made to set the flag when it is already set, this means
124     * the definition of the variable is circular.
125     */

126
127     public void setExecuting(GlobalVariable binding, boolean executing)
128     throws XPathException {
129         int slot = binding.getSlotNumber();
130         if (executing) {
131             if (busy[slot]) {
132                 throw new XPathException.Circularity("Circular definition");
133             }
134             // It would be better to detect circular references statically
135
// at compile time. However, this is not always possible, because they
136
// can arise via execution of templates or stylesheet functions.
137
busy[slot]=true;
138         } else {
139             busy[slot]=false;
140         }
141     }
142
143     /**
144     * Get the value of a global variable
145     * @param binding the Binding that establishes the unique instance of the variable
146     * @return the Value of the variable if defined, null otherwise.
147     */

148
149     public ValueRepresentation getGlobalVariableValue(GlobalVariable binding) {
150         return globals[binding.getSlotNumber()];
151     }
152
153      /**
154     * Get the value of a global variable whose slot number is known
155     * @param slot the slot number of the required variable
156     * @return the Value of the variable if defined, null otherwise.
157     */

158
159     public ValueRepresentation getGlobalVariable(int slot) {
160         return globals[slot];
161     }
162
163     /**
164     * Assign a new value to a global variable. Supports saxon:assign.
165     * @param binding identifies the local or global variable or parameter
166     */

167
168     public void assignGlobalVariable(GlobalVariable binding, ValueRepresentation value) {
169         defineGlobalVariable(binding, value);
170     }
171
172     /**
173      * Get the Global Variable Map, containing the mapping of variable names (fingerprints)
174      * to slot numbers. This is provided for use by debuggers.
175      */

176
177     public SlotManager getGlobalVariableMap() {
178         return globalVariableMap;
179     }
180
181     /**
182      * Get all the global variables, as an array. This is provided for use by debuggers
183      * that know the layout of the global variables within the array.
184      */

185
186     public ValueRepresentation[] getGlobalVariables() {
187         return globals;
188     }
189
190 }
191
192 //
193
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
194
// you may not use this file except in compliance with the License. You may obtain a copy of the
195
// License at http://www.mozilla.org/MPL/
196
//
197
// Software distributed under the License is distributed on an "AS IS" basis,
198
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
199
// See the License for the specific language governing rights and limitations under the License.
200
//
201
// The Original Code is: all this file.
202
//
203
// The Initial Developer of the Original Code is Michael H. Kay.
204
//
205
//
206
//
207
Popular Tags