001: package net.sf.saxon.style;
002:
003: import net.sf.saxon.Configuration;
004: import net.sf.saxon.Err;
005: import net.sf.saxon.expr.EarlyEvaluationContext;
006: import net.sf.saxon.expr.VariableReference;
007: import net.sf.saxon.expr.XPathContext;
008: import net.sf.saxon.functions.FunctionLibrary;
009: import net.sf.saxon.instruct.LocationMap;
010: import net.sf.saxon.om.NamePool;
011: import net.sf.saxon.om.NamespaceConstant;
012: import net.sf.saxon.om.NamespaceResolver;
013: import net.sf.saxon.om.QNameException;
014: import net.sf.saxon.trans.StaticError;
015: import net.sf.saxon.trans.XPathException;
016: import net.sf.saxon.type.AtomicType;
017: import net.sf.saxon.type.BuiltInAtomicType;
018:
019: import javax.xml.transform.SourceLocator;
020: import java.util.Comparator;
021: import java.util.Set;
022:
023: /**
024: * An ExpressionContext represents the context for an XPath expression written
025: * in the stylesheet.
026: */
027:
028: public class ExpressionContext implements XSLTStaticContext {
029:
030: private StyleElement element;
031: private NamePool namePool;
032:
033: public ExpressionContext(StyleElement styleElement) {
034: element = styleElement;
035: namePool = styleElement.getTargetNamePool();
036: }
037:
038: /**
039: * Get the system configuration
040: */
041:
042: public Configuration getConfiguration() {
043: return element.getPreparedStylesheet().getConfiguration();
044: }
045:
046: /**
047: * Construct a dynamic context for early evaluation of constant subexpressions
048: */
049:
050: public XPathContext makeEarlyEvaluationContext() {
051: return new EarlyEvaluationContext(this );
052: }
053:
054: /**
055: * Get the location map
056: */
057:
058: public LocationMap getLocationMap() {
059: return element.getPrincipalStylesheet().getLocationMap();
060: }
061:
062: /**
063: * Issue a compile-time warning
064: */
065:
066: public void issueWarning(String s, SourceLocator locator) {
067: element.issueWarning(s, locator);
068: }
069:
070: /**
071: * Get the NamePool used for compiling expressions
072: */
073:
074: public NamePool getNamePool() {
075: return namePool;
076: }
077:
078: /**
079: * Get the System ID of the entity containing the expression (used for diagnostics)
080: */
081:
082: public String getSystemId() {
083: return element.getSystemId();
084: }
085:
086: /**
087: * Get the line number of the expression within its containing entity
088: * Returns -1 if no line number is available
089: */
090:
091: public int getLineNumber() {
092: return element.getLineNumber();
093: }
094:
095: /**
096: * Get the Base URI of the element containing the expression, for resolving any
097: * relative URI's used in the expression.
098: * Used by the document() function.
099: */
100:
101: public String getBaseURI() {
102: return element.getBaseURI();
103: }
104:
105: /**
106: * Get the URI for a prefix, using this Element as the context for namespace resolution.
107: * The default namespace will not be used when the prefix is empty.
108: * @param prefix The prefix
109: * @throws XPathException if the prefix is not declared
110: */
111:
112: public String getURIForPrefix(String prefix) throws XPathException {
113: String uri = element.getURIForPrefix(prefix, false);
114: if (uri == null) {
115: StaticError err = new StaticError(
116: "Undeclared namespace prefix " + Err.wrap(prefix));
117: err.setErrorCode("XY0280");
118: throw err;
119: }
120: return uri;
121: }
122:
123: /**
124: * Get a copy of the Namespace Context
125: */
126:
127: public NamespaceResolver getNamespaceResolver() {
128: return element.makeNamespaceContext();
129: }
130:
131: /**
132: * Get a fingerprint for a name, using this as the context for namespace resolution
133: * @param qname The name as written, in the form "[prefix:]localname"
134: * @param useDefault Defines the action when there is no prefix. If true, use
135: * the default namespace URI (as for element names). If false, use no namespace URI
136: * (as for attribute names).
137: * @return -1 if the name is not already present in the name pool
138: */
139:
140: public int getFingerprint(String qname, boolean useDefault)
141: throws XPathException {
142:
143: String[] parts;
144: try {
145: parts = getConfiguration().getNameChecker().getQNameParts(
146: qname);
147: } catch (QNameException err) {
148: throw new StaticError(err.getMessage());
149: }
150: String prefix = parts[0];
151: if (prefix.equals("")) {
152: String uri = "";
153:
154: if (useDefault) {
155: uri = getURIForPrefix(prefix);
156: }
157:
158: return namePool.getFingerprint(uri, qname);
159:
160: } else {
161:
162: String uri = getURIForPrefix(prefix);
163: return namePool.getFingerprint(uri, parts[1]);
164: }
165: }
166:
167: /**
168: * Bind a variable to an object that can be used to refer to it
169: * @param fingerprint The fingerprint of the variable name
170: * @return a VariableDeclaration object that can be used to identify it in the Bindery
171: * @throws net.sf.saxon.trans.StaticError if the variable has not been declared
172: */
173:
174: public VariableReference bindVariable(int fingerprint)
175: throws StaticError {
176: return new VariableReference(element.bindVariable(fingerprint));
177: }
178:
179: /**
180: * Get the function library containing all the in-scope functions available in this static
181: * context
182: */
183:
184: public FunctionLibrary getFunctionLibrary() {
185: return element.getPrincipalStylesheet().getFunctionLibrary();
186: }
187:
188: /**
189: * Determine if an extension element is available
190: * @throws XPathException if the name is invalid or the prefix is not declared
191: */
192:
193: public boolean isElementAvailable(String qname)
194: throws XPathException {
195: try {
196: String[] parts = getConfiguration().getNameChecker()
197: .getQNameParts(qname);
198: String uri = getURIForPrefix(parts[0]);
199:
200: return element.getPreparedStylesheet()
201: .getStyleNodeFactory().isElementAvailable(uri,
202: parts[1]);
203: } catch (QNameException e) {
204: StaticError err = new StaticError("Invalid element name. "
205: + e.getMessage());
206: err.setErrorCode("XTDE1440");
207: throw err;
208: }
209: }
210:
211: /**
212: * Get a named collation.
213: * @param name The name of the required collation. Supply null to get the default collation.
214: * @return the collation; or null if the required collation is not found.
215: */
216:
217: public Comparator getCollation(String name) {
218: return element.getPrincipalStylesheet().findCollation(name);
219: }
220:
221: /**
222: * Get the default collation. Return null if no default collation has been defined
223: */
224:
225: public String getDefaultCollationName() {
226: return element.getDefaultCollationName();
227: //return element.getPrincipalStylesheet().getDefaultCollationName();
228: }
229:
230: /**
231: * Get the default XPath namespace, as a namespace code that can be looked up in the NamePool
232: */
233:
234: public short getDefaultElementNamespace() {
235: return element.getDefaultXPathNamespace();
236: }
237:
238: /**
239: * Get the default function namespace
240: */
241:
242: public String getDefaultFunctionNamespace() {
243: return NamespaceConstant.FN;
244: }
245:
246: /**
247: * Determine whether Backwards Compatible Mode is used
248: */
249:
250: public boolean isInBackwardsCompatibleMode() {
251: return element.backwardsCompatibleModeIsEnabled();
252: }
253:
254: /**
255: * Test whether a schema has been imported for a given namespace
256: * @param namespace the target namespace of the required schema
257: * @return true if a schema for this namespace has been imported
258: */
259:
260: public boolean isImportedSchema(String namespace) {
261: return getXSLStylesheet().isImportedSchema(namespace);
262: }
263:
264: /**
265: * Get the set of imported schemas
266: * @return a Set, the set of URIs representing the names of imported schemas
267: */
268:
269: public Set getImportedSchemaNamespaces() {
270: return getXSLStylesheet().getImportedSchemaTable();
271: }
272:
273: /**
274: * Determine whether a built-in type is available in this context. This method caters for differences
275: * between host languages as to which set of types are built in.
276: *
277: * @param type the supposedly built-in type. This will always be a type in the
278: * XS or XDT namespace.
279: * @return true if this type can be used in this static context
280: */
281:
282: public boolean isAllowedBuiltInType(AtomicType type) {
283: if (getConfiguration().isSchemaAware(Configuration.XSLT)) {
284: return true;
285: } else if (type instanceof BuiltInAtomicType) {
286: return ((BuiltInAtomicType) type).isAllowedInBasicXSLT();
287: } else {
288: return false;
289: }
290: }
291:
292: /**
293: * Get the XSLStylesheet object
294: */
295:
296: public XSLStylesheet getXSLStylesheet() {
297: return element.getPrincipalStylesheet();
298: }
299:
300: /**
301: * Get the stylesheet element containing this XPath expression
302: * @return the element in the tree representation of the source stylesheet
303: */
304:
305: public StyleElement getStyleElement() {
306: return element;
307: }
308: }
309:
310: //
311: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
312: // you may not use this file except in compliance with the License. You may obtain a copy of the
313: // License at http://www.mozilla.org/MPL/
314: //
315: // Software distributed under the License is distributed on an "AS IS" basis,
316: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
317: // See the License for the specific language governing rights and limitations under the License.
318: //
319: // The Original Code is: all this file.
320: //
321: // The Initial Developer of the Original Code is Michael H. Kay.
322: //
323: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
324: //
325: // Contributor(s): none.
326: //
|