001: package net.sf.saxon.style;
002:
003: import net.sf.saxon.Configuration;
004: import net.sf.saxon.expr.EarlyEvaluationContext;
005: import net.sf.saxon.expr.VariableReference;
006: import net.sf.saxon.expr.XPathContext;
007: import net.sf.saxon.functions.ConstructorFunctionLibrary;
008: import net.sf.saxon.functions.FunctionLibrary;
009: import net.sf.saxon.functions.FunctionLibraryList;
010: import net.sf.saxon.functions.SystemFunctionLibrary;
011: import net.sf.saxon.instruct.LocationMap;
012: import net.sf.saxon.om.NamePool;
013: import net.sf.saxon.om.NamespaceConstant;
014: import net.sf.saxon.om.NamespaceResolver;
015: import net.sf.saxon.om.QNameException;
016: import net.sf.saxon.trans.StaticError;
017: import net.sf.saxon.trans.XPathException;
018: import net.sf.saxon.type.AtomicType;
019: import net.sf.saxon.type.BuiltInAtomicType;
020:
021: import javax.xml.transform.SourceLocator;
022: import javax.xml.transform.TransformerException;
023: import java.util.Collections;
024: import java.util.Comparator;
025: import java.util.Set;
026:
027: /**
028: * This class implements the static context used for evaluating use-when expressions in XSLT 2.0
029: */
030:
031: public class UseWhenStaticContext implements XSLTStaticContext {
032:
033: public Configuration config;
034: public NamespaceResolver namespaceContext;
035: public FunctionLibrary functionLibrary;
036: public LocationMap locationMap;
037: public StyleNodeFactory nodeFactory;
038: public String baseURI;
039: public short defaultXPathNamespace;
040:
041: public UseWhenStaticContext(Configuration config,
042: NamespaceResolver namespaceContext) {
043: this .config = config;
044: this .namespaceContext = namespaceContext;
045: this .locationMap = new LocationMap();
046:
047: FunctionLibraryList lib = new FunctionLibraryList();
048: lib.addFunctionLibrary(new SystemFunctionLibrary(
049: SystemFunctionLibrary.USE_WHEN));
050: lib.addFunctionLibrary(getConfiguration()
051: .getVendorFunctionLibrary());
052: lib.addFunctionLibrary(new ConstructorFunctionLibrary(
053: getConfiguration()));
054: if (config.isAllowExternalFunctions()) {
055: lib.addFunctionLibrary(config.getExtensionBinder());
056: }
057: functionLibrary = lib;
058: }
059:
060: /**
061: * Get the system configuration
062: */
063:
064: public Configuration getConfiguration() {
065: return config;
066: }
067:
068: /**
069: * Construct a dynamic context for early evaluation of constant subexpressions
070: */
071:
072: public XPathContext makeEarlyEvaluationContext() {
073: return new EarlyEvaluationContext(this );
074: }
075:
076: /**
077: * Get the location map
078: */
079:
080: public LocationMap getLocationMap() {
081: return locationMap;
082: }
083:
084: /**
085: * Issue a compile-time warning
086: */
087:
088: public void issueWarning(String s, SourceLocator locator) {
089: StaticError err = new StaticError(s);
090: err.setLocator(locator);
091: try {
092: config.getErrorListener().warning(err);
093: } catch (TransformerException e) {
094: // ignore response
095: }
096: }
097:
098: /**
099: * Get the System ID of the container of the expression. This is the containing
100: * entity (file) and is therefore useful for diagnostics. Use getBaseURI() to get
101: * the base URI, which may be different.
102: */
103:
104: public String getSystemId() {
105: return baseURI;
106: }
107:
108: /**
109: * Get the line number of the expression within its containing entity
110: * Returns -1 if no line number is available
111: */
112:
113: public int getLineNumber() {
114: return -1;
115: }
116:
117: /**
118: * Get the Base URI of the stylesheet element, for resolving any relative URI's used
119: * in the expression.
120: * Used by the document(), doc(), resolve-uri(), and base-uri() functions.
121: * May return null if the base URI is not known.
122: */
123:
124: public String getBaseURI() {
125: return baseURI;
126: }
127:
128: /**
129: * Get the URI for a namespace prefix. The default namespace is NOT used
130: * when the prefix is empty.
131: *
132: * @param prefix The prefix
133: * @throws net.sf.saxon.trans.XPathException
134: * if the prefix is not declared
135: */
136:
137: public String getURIForPrefix(String prefix) throws XPathException {
138: return namespaceContext.getURIForPrefix(prefix, false);
139: }
140:
141: /**
142: * Get the NamePool used for compiling expressions
143: */
144:
145: public NamePool getNamePool() {
146: return getConfiguration().getNamePool();
147: }
148:
149: /**
150: * Bind a variable used in this element to the XSLVariable element in which it is declared
151: */
152:
153: public VariableReference bindVariable(int fingerprint)
154: throws StaticError {
155: StaticError err = new StaticError(
156: "Variables cannot be used in a use-when expression");
157: err.setErrorCode("XO0008");
158: throw err;
159: }
160:
161: /**
162: * Get the function library containing all the in-scope functions available in this static
163: * context
164: */
165:
166: public FunctionLibrary getFunctionLibrary() {
167: return functionLibrary;
168: }
169:
170: /**
171: * Get a named collation.
172: *
173: * @param name The name of the required collation. Supply null to get the default collation.
174: * @return the collation; or null if the required collation is not found.
175: */
176:
177: public Comparator getCollation(String name) {
178: return null;
179: }
180:
181: /**
182: * Get the name of the default collation.
183: *
184: * @return the name of the default collation; or the name of the codepoint collation
185: * if no default collation has been defined
186: */
187:
188: public String getDefaultCollationName() {
189: return NamespaceConstant.CODEPOINT_COLLATION_URI;
190: }
191:
192: /**
193: * Get the default XPath namespace, as a namespace code that can be looked up in the NamePool
194: */
195:
196: public short getDefaultElementNamespace() {
197: return defaultXPathNamespace;
198: }
199:
200: /**
201: * Get the default function namespace
202: */
203:
204: public String getDefaultFunctionNamespace() {
205: return NamespaceConstant.FN;
206: }
207:
208: /**
209: * Determine whether Backwards Compatible Mode is used
210: */
211:
212: public boolean isInBackwardsCompatibleMode() {
213: return false;
214: }
215:
216: /**
217: * Determine whether a Schema for a given target namespace has been imported. Note that the
218: * in-scope element declarations, attribute declarations and schema types are the types registered
219: * with the (schema-aware) configuration, provided that their namespace URI is registered
220: * in the static context as being an imported schema namespace. (A consequence of this is that
221: * within a Configuration, there can only be one schema for any given namespace, including the
222: * null namespace).
223: */
224:
225: public boolean isImportedSchema(String namespace) {
226: return false;
227: }
228:
229: /**
230: * Get the set of imported schemas
231: *
232: * @return a Set, the set of URIs representing the names of imported schemas
233: */
234:
235: public Set getImportedSchemaNamespaces() {
236: return Collections.EMPTY_SET;
237: }
238:
239: /**
240: * Determine whether a built-in type is available in this context. This method caters for differences
241: * between host languages as to which set of types are built in.
242: *
243: * @param type the supposedly built-in type. This will always be a type in the
244: * XS or XDT namespace.
245: * @return true if this type can be used in this static context
246: */
247:
248: public boolean isAllowedBuiltInType(AtomicType type) {
249: if (getConfiguration().isSchemaAware(Configuration.XSLT)) {
250: return true;
251: } else if (type instanceof BuiltInAtomicType) {
252: return ((BuiltInAtomicType) type).isAllowedInBasicXSLT();
253: } else {
254: return false;
255: }
256: }
257:
258: /**
259: * Get a namespace resolver to resolve the namespaces declared in this static context.
260: *
261: * @return a namespace resolver.
262: */
263:
264: public NamespaceResolver getNamespaceResolver() {
265: return namespaceContext;
266: }
267:
268: /**
269: * Determine if an extension element is available
270: * @throws net.sf.saxon.trans.XPathException if the name is invalid or the prefix is not declared
271: */
272:
273: public boolean isElementAvailable(String qname)
274: throws XPathException {
275: try {
276: String[] parts = getConfiguration().getNameChecker()
277: .getQNameParts(qname);
278: String uri = getURIForPrefix(parts[0]);
279: if (nodeFactory == null) {
280: nodeFactory = new StyleNodeFactory(config);
281: }
282: return nodeFactory.isElementAvailable(uri, parts[1]);
283: } catch (QNameException e) {
284: StaticError err = new StaticError("Invalid element name. "
285: + e.getMessage());
286: err.setErrorCode("XTDE1440");
287: throw err;
288: }
289: }
290:
291: /**
292: * Set the base URI
293: */
294:
295: public void setBaseURI(String uri) {
296: baseURI = uri;
297: }
298:
299: /**
300: * Set the default namespace for elements and types
301: */
302:
303: public void setDefaultElementNamespace(short code) {
304: defaultXPathNamespace = code;
305: }
306:
307: }
|