KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > style > StyleElement


1 package net.sf.saxon.style;
2
3 import net.sf.saxon.Err;
4 import net.sf.saxon.PreparedStylesheet;
5 import net.sf.saxon.Configuration;
6 import net.sf.saxon.event.LocationProvider;
7 import net.sf.saxon.expr.*;
8 import net.sf.saxon.instruct.*;
9 import net.sf.saxon.om.*;
10 import net.sf.saxon.pattern.*;
11 import net.sf.saxon.sort.SortKeyDefinition;
12 import net.sf.saxon.trace.InstructionInfo;
13 import net.sf.saxon.trace.Location;
14 import net.sf.saxon.trans.DynamicError;
15 import net.sf.saxon.trans.SaxonErrorCode;
16 import net.sf.saxon.trans.StaticError;
17 import net.sf.saxon.trans.XPathException;
18 import net.sf.saxon.tree.ElementWithAttributes;
19 import net.sf.saxon.type.*;
20 import net.sf.saxon.value.*;
21 import org.xml.sax.Locator JavaDoc;
22
23 import javax.xml.transform.SourceLocator JavaDoc;
24 import javax.xml.transform.TransformerConfigurationException JavaDoc;
25 import javax.xml.transform.TransformerException JavaDoc;
26 import java.math.BigDecimal JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.List JavaDoc;
30 import java.util.StringTokenizer JavaDoc;
31
32 /**
33  * Abstract superclass for all element nodes in the stylesheet. <BR>
34  * Note: this class implements Locator. The element
35  * retains information about its own location in the stylesheet, which is useful when
36  * an XSL error is found.
37  */

38
39 public abstract class StyleElement extends ElementWithAttributes
40         implements Locator JavaDoc, Container, InstructionInfo {
41
42     protected short[] extensionNamespaces = null; // a list of URI codes
43
private short[] excludedNamespaces = null; // a list of URI codes
44
protected BigDecimal JavaDoc version = null;
45     protected StaticContext staticContext = null;
46     protected StaticError validationError = null;
47     protected int reportingCircumstances = REPORT_ALWAYS;
48     protected String JavaDoc defaultXPathNamespace = null;
49     protected String JavaDoc defaultCollationName = null;
50     private int lineNumber; // maintained here because it's more efficient
51
// than using the lineNumberMap
52
private boolean explaining = false;
53     // true if saxon:explain="yes"
54
private int objectNameCode = -1;
55     // for instructions that define an XSLT named object, the name of that object
56
private XSLStylesheet containingStylesheet;
57
58     // Conditions under which an error is to be reported
59

60     public static final int REPORT_ALWAYS = 1;
61     public static final int REPORT_UNLESS_FORWARDS_COMPATIBLE = 2;
62     public static final int REPORT_IF_INSTANTIATED = 3;
63
64     /**
65      * Constructor
66      */

67
68     public StyleElement() {
69     }
70
71     public Executable getExecutable() {
72         return getPrincipalStylesheet().getExecutable();
73     }
74
75     /**
76      * Get the LocationProvider allowing location identifiers to be resolved.
77      */

78
79     public LocationProvider getLocationProvider() {
80         return getExecutable().getLocationMap();
81     }
82
83     /**
84      * Get the namepool to be used at run-time, this namepool holds the names used in
85      * all XPath expressions and patterns
86      */

87
88     public NamePool getTargetNamePool() {
89         return getPrincipalStylesheet().getTargetNamePool();
90     }
91
92     /**
93      * Get the static context for expressions on this element
94      *
95      * @return the static context
96      */

97
98     public StaticContext getStaticContext() {
99         if (staticContext == null) {
100             staticContext = new ExpressionContext(this);
101         }
102         return staticContext;
103     }
104
105     public int getLineNumber() {
106         return lineNumber;
107     }
108
109     public void setLineNumber(int lineNumber) {
110         this.lineNumber = lineNumber;
111     }
112
113     /**
114      * Determine whether saxon:explain has been set to "yes"
115      */

116
117     protected boolean isExplaining() {
118         return explaining;
119     }
120
121     /**
122      * Make this node a substitute for a temporary one previously added to the tree. See
123      * StyleNodeFactory for details. "A node like the other one in all things but its class".
124      * Note that at this stage, the node will not yet be known to its parent, though it will
125      * contain a reference to its parent; and it will have no children.
126      */

127
128     public void substituteFor(StyleElement temp) {
129         this.parent = temp.parent;
130         this.attributeList = temp.attributeList;
131         this.namespaceList = temp.namespaceList;
132         this.nameCode = temp.nameCode;
133         this.sequence = temp.sequence;
134         this.extensionNamespaces = temp.extensionNamespaces;
135         this.excludedNamespaces = temp.excludedNamespaces;
136         this.version = temp.version;
137         this.root = temp.root;
138         this.staticContext = temp.staticContext;
139         this.validationError = temp.validationError;
140         this.reportingCircumstances = temp.reportingCircumstances;
141         this.lineNumber = temp.lineNumber;
142     }
143
144     /**
145      * Set a validation error
146      */

147
148     protected void setValidationError(TransformerException JavaDoc reason,
149                                       int circumstances) {
150         validationError = StaticError.makeStaticError(reason);
151         reportingCircumstances = circumstances;
152     }
153
154     /**
155      * Determine whether this node is an instruction. The default implementation says it isn't.
156      */

157
158     public boolean isInstruction() {
159         return false;
160     }
161
162     /**
163      * Determine the type of item returned by this instruction (only relevant if
164      * it is an instruction). Default implementation returns Type.ITEM, indicating
165      * that we don't know, it might be anything. Returns null in the case of an element
166      * such as xsl:sort or xsl:variable that can appear in a sequence constructor but
167      * contributes nothing to the result sequence.
168      *
169      * @return the item type returned
170      */

171
172     protected ItemType getReturnedItemType() {
173         return AnyItemType.getInstance();
174     }
175
176     /**
177      * Get the most general type of item returned by the children of this instruction
178      *
179      * @return the lowest common supertype of the item types returned by the children
180      */

181
182     protected ItemType getCommonChildItemType() {
183         ItemType t = NoNodeTest.getInstance();
184         AxisIterator children = iterateAxis(Axis.CHILD);
185         while (true) {
186             NodeInfo next = (NodeInfo)children.next();
187             if (next == null) {
188                 return t;
189             }
190             if (next instanceof StyleElement) {
191                 ItemType ret = ((StyleElement)next).getReturnedItemType();
192                 if (ret != null) {
193                     t = Type.getCommonSuperType(t, ret);
194                 }
195             } else {
196                 t = Type.getCommonSuperType(t, NodeKindTest.TEXT);
197             }
198             if (t == AnyItemType.getInstance()) {
199                 return t; // no point looking any further
200
}
201         }
202     }
203
204     /**
205      * Mark tail-recursive calls on templates and functions.
206      * For most instructions, this does nothing.
207      */

208
209     public void markTailCalls() {
210         // no-op
211
}
212
213     /**
214      * Determine whether this type of element is allowed to contain a sequence constructor
215      */

216
217     public boolean mayContainSequenceConstructor() {
218         return false;
219     }
220
221     /**
222      * Determine whether this type of element is allowed to contain an xsl:fallback
223      * instruction
224      */

225
226     public boolean mayContainFallback() {
227         return mayContainSequenceConstructor();
228     }
229
230     /**
231      * Get the containing XSLStylesheet element
232      */

233
234     public XSLStylesheet getContainingStylesheet() {
235         if (containingStylesheet == null) {
236             if (this instanceof XSLStylesheet) {
237                 containingStylesheet = (XSLStylesheet)this;
238             } else {
239                 containingStylesheet = ((StyleElement)getParent()).getContainingStylesheet();
240             }
241         }
242         return containingStylesheet;
243     }
244
245     /**
246      * Get the import precedence of this stylesheet element.
247      */

248
249     public int getPrecedence() {
250         return getContainingStylesheet().getPrecedence();
251     }
252
253     /**
254      * Get the URI for a namespace prefix using the in-scope namespaces for
255      * this element in the stylesheet
256      *
257      * @param prefix The namespace prefix: may be the empty string
258      * @param useDefault True if the default namespace is to be used when the
259      * prefix is "".
260      * @return the namespace URI if the prefix is bound to a namespace; "" if the
261      * prefix ("") is bound to no namespace; null if the prefix is not bound.
262      */

263
264 // public String getURIForPrefix(String prefix, boolean useDefault) {
265
// if ("".equals(prefix) && !useDefault) {
266
// return "";
267
// } else {
268
// try {
269
// short uricode = getURICodeForPrefix(prefix);
270
// return getNamePool().getURIFromURICode(uricode);
271
// } catch (NamespaceException e) {
272
// return null;
273
// }
274
// }
275
// }
276

277     /**
278      * Make a NameCode, using this Element as the context for namespace resolution, and
279      * registering the code in the namepool. If the name is unprefixed, the
280      * default namespace is <b>not</b> used.
281      *
282      * @param qname The name as written, in the form "[prefix:]localname". The name must have
283      * already been validated as a syntactically-correct QName.
284      * @throws XPathException if the qname is not a lexically-valid QName, or if the name
285      * is in a reserved namespace.
286      * @throws NamespaceException if the prefix of the qname has not been declared
287      */

288
289     public final int makeNameCode(String JavaDoc qname)
290             throws XPathException, NamespaceException {
291
292         NamePool namePool = getTargetNamePool();
293         String JavaDoc[] parts;
294         try {
295             parts = Name.getQNameParts(qname);
296         } catch (QNameException err) {
297             StaticError e2 = new StaticError(err.getMessage());
298             e2.setErrorCode("XTSE0020");
299             throw e2;
300         }
301         String JavaDoc prefix = parts[0];
302         if ("".equals(prefix)) {
303             return namePool.allocate(prefix, (short)0, qname);
304
305         } else {
306
307             String JavaDoc uri = getURIForPrefix(prefix, false);
308             if (uri == null) {
309                 throw new NamespaceException(prefix);
310             }
311             if (NamespaceConstant.isReserved(uri)) {
312                 StaticError err = new StaticError("Namespace prefix " + prefix + " refers to a reserved namespace");
313                 err.setErrorCode("XTSE0080");
314                 throw err;
315             }
316             return namePool.allocate(prefix, uri, parts[1]);
317         }
318
319     }
320
321     /**
322      * Make a NamespaceContext object representing the list of in-scope namespaces. The NamePool
323      * used for numeric codes in the NamespaceContext will be the target name pool.
324      */

325
326     public SavedNamespaceContext makeNamespaceContext() {
327         return new SavedNamespaceContext(getInScopeNamespaceCodes(), getNamePool());
328     }
329
330     /**
331      * Process the attributes of this element and all its children
332      */

333
334     public void processAllAttributes() throws XPathException {
335         staticContext = new ExpressionContext(this);
336         processAttributes();
337         AxisIterator kids = iterateAxis(Axis.CHILD);
338         while (true) {
339             NodeInfo child = (NodeInfo)kids.next();
340             if (child == null) {
341                 return;
342             }
343             if (child instanceof StyleElement) {
344                 ((StyleElement)child).processAllAttributes();
345                 if (((StyleElement)child).explaining) {
346                     // saxon:explain on any element in a template/function now causes an explanation at the
347
// level of the template/function
348
explaining = true;
349                 }
350             }
351         }
352     }
353
354     /**
355      * Get an attribute value given the Clark name of the attribute (that is,
356      * the name in {uri}local format).
357      */

358
359     public String JavaDoc getAttributeValue(String JavaDoc clarkName) {
360         int fp = getNamePool().allocateClarkName(clarkName);
361         return getAttributeValue(fp);
362     }
363
364     /**
365      * Process the attribute list for the element. This is a wrapper method that calls
366      * prepareAttributes (provided in the subclass) and traps any exceptions
367      */

368
369     public final void processAttributes() throws XPathException {
370         try {
371             prepareAttributes();
372         } catch (XPathException err) {
373             if (forwardsCompatibleModeIsEnabled()) {
374                 setValidationError(err, REPORT_IF_INSTANTIATED);
375             } else {
376                 compileError(err);
377             }
378         }
379     }
380
381     /**
382      * Check whether an unknown attribute is permitted.
383      *
384      * @param nc The name code of the attribute name
385      */

386
387     protected void checkUnknownAttribute(int nc) throws XPathException {
388
389         String JavaDoc attributeURI = getNamePool().getURI(nc);
390         String JavaDoc elementURI = getURI();
391         String JavaDoc clarkName = getNamePool().getClarkName(nc);
392
393         if (clarkName.equals(StandardNames.SAXON_EXPLAIN)) {
394             explaining = "yes".equals(getAttributeValue(nc & 0xfffff));
395         }
396
397         if (forwardsCompatibleModeIsEnabled()) {
398             // then unknown attributes are permitted and ignored
399
return;
400         }
401
402         // allow xsl:extension-element-prefixes etc on an extension element
403

404         if (isInstruction() &&
405                 clarkName.startsWith('{' + NamespaceConstant.XSLT) &&
406                 !(elementURI.equals(NamespaceConstant.XSLT)) &&
407                 (clarkName.endsWith("}default-collation") ||
408                 clarkName.endsWith("}xpath-default-namespace") ||
409                 clarkName.endsWith("}extension-element-prefixes") ||
410                 clarkName.endsWith("}exclude-result-prefixes") ||
411                 clarkName.endsWith("}version") ||
412                 clarkName.endsWith("}use-when"))) {
413             return;
414         }
415
416         // allow standard attributes on an XSLT element
417

418         if (elementURI.equals(NamespaceConstant.XSLT) &&
419                 (clarkName == StandardNames.DEFAULT_COLLATION ||
420                 clarkName == StandardNames.XPATH_DEFAULT_NAMESPACE ||
421                 clarkName == StandardNames.EXTENSION_ELEMENT_PREFIXES ||
422                 clarkName == StandardNames.EXCLUDE_RESULT_PREFIXES ||
423                 clarkName == StandardNames.VERSION ||
424                 clarkName == StandardNames.USE_WHEN)) {
425             return;
426         }
427
428         if ("".equals(attributeURI) || NamespaceConstant.XSLT.equals(attributeURI)) {
429             compileError("Attribute " + Err.wrap(getNamePool().getDisplayName(nc), Err.ATTRIBUTE) +
430                     " is not allowed on element " + Err.wrap(getDisplayName(), Err.ELEMENT), "XTSE0010");
431         }
432     }
433
434
435     /**
436      * Set the attribute list for the element. This is called to process the attributes (note
437      * the distinction from processAttributes in the superclass).
438      * Must be supplied in a subclass
439      */

440
441     public abstract void prepareAttributes() throws XPathException;
442
443     /**
444      * Find the last child instruction of this instruction. Returns null if
445      * there are no child instructions, or if the last child is a text node.
446      */

447
448     protected StyleElement getLastChildInstruction() {
449         StyleElement last = null;
450         AxisIterator kids = iterateAxis(Axis.CHILD);
451         while (true) {
452             NodeInfo child = (NodeInfo)kids.next();
453             if (child == null) {
454                 return last;
455             }
456             if (child instanceof StyleElement) {
457                 last = (StyleElement)child;
458             } else {
459                 last = null;
460             }
461         }
462     }
463
464     /**
465      * Make an expression in the context of this stylesheet element
466      */

467
468     public Expression makeExpression(String JavaDoc expression)
469             throws XPathException {
470         try {
471             Expression exp = ExpressionTool.make(expression,
472                     staticContext,
473                     0, Token.EOF,
474                     getLineNumber());
475             return exp;
476         } catch (XPathException err) {
477             err.setLocator(this);
478             if (!forwardsCompatibleModeIsEnabled()) {
479                 compileError(err);
480             } else if (err.isTypeError()) {
481                 compileError(err);
482             }
483             ErrorExpression erexp = new ErrorExpression(err);
484             erexp.setLocationId(allocateLocationId(getSystemId(), getLineNumber()));
485             erexp.setParentExpression(this);
486             return erexp;
487         }
488     }
489
490     /**
491      * Make a pattern in the context of this stylesheet element
492      */

493
494     public Pattern makePattern(String JavaDoc pattern)
495             throws XPathException {
496         try {
497             return Pattern.make(pattern, staticContext, getPrincipalStylesheet().getExecutable());
498         } catch (XPathException err) {
499             if (forwardsCompatibleModeIsEnabled()) {
500                 compileWarning("Invalid pattern, ignored because in forwards-compatibility mode. " +
501                         err.getMessage(), err.getErrorCodeLocalPart());
502                 return new NodeTestPattern(NoNodeTest.getInstance());
503             } else {
504                 compileError(err);
505                 return new NodeTestPattern(AnyNodeTest.getInstance());
506             }
507         }
508     }
509
510     /**
511      * Make an attribute value template in the context of this stylesheet element
512      */

513
514     public Expression makeAttributeValueTemplate(String JavaDoc expression)
515             throws XPathException {
516         try {
517             return AttributeValueTemplate.make(expression, getLineNumber(), staticContext);
518         } catch (XPathException err) {
519             compileError(err);
520             return new StringValue(expression);
521         }
522     }
523
524     /**
525      * Process an attribute whose value is a SequenceType
526      */

527
528     public SequenceType makeSequenceType(String JavaDoc sequenceType)
529             throws XPathException {
530         getStaticContext();
531         try {
532             ExpressionParser parser = new ExpressionParser();
533             return parser.parseSequenceType(sequenceType, staticContext);
534         } catch (XPathException err) {
535             compileError(err);
536 // recovery path after reporting an error, e.g. undeclared namespace prefix
537
return SequenceType.ANY_SEQUENCE;
538         }
539     }
540
541     /**
542      * Process the [xsl:]extension-element-prefixes attribute if there is one
543      *
544      * @param nc the Clark name of the attribute required
545      */

546
547     protected void processExtensionElementAttribute(String JavaDoc nc)
548             throws XPathException {
549         String JavaDoc ext = getAttributeValue(nc);
550         if (ext != null) {
551             // go round twice, once to count the values and next to add them to the array
552
int count = 0;
553             StringTokenizer JavaDoc st1 = new StringTokenizer JavaDoc(ext);
554             while (st1.hasMoreTokens()) {
555                 st1.nextToken();
556                 count++;
557             }
558             extensionNamespaces = new short[count];
559             count = 0;
560             StringTokenizer JavaDoc st2 = new StringTokenizer JavaDoc(ext);
561             while (st2.hasMoreTokens()) {
562                 String JavaDoc s = st2.nextToken();
563                 if ("#default".equals(s)) {
564                     s = "";
565                 }
566                 try {
567                     short uriCode = getURICodeForPrefix(s);
568                     extensionNamespaces[count++] = uriCode;
569                 } catch (NamespaceException err) {
570                     extensionNamespaces = null;
571                     compileError(err.getMessage(), "XT0280");
572                 }
573             }
574         }
575     }
576
577     /**
578      * Process the [xsl:]exclude-result-prefixes attribute if there is one
579      *
580      * @param nc the Clark name of the attribute required
581      */

582
583     protected void processExcludedNamespaces(String JavaDoc nc)
584             throws XPathException {
585         String JavaDoc ext = getAttributeValue(nc);
586         if (ext != null) {
587             if ("#all".equals(ext.trim())) {
588                 int[] codes = getInScopeNamespaceCodes();
589                 excludedNamespaces = new short[codes.length];
590                 for (int i = 0; i < codes.length; i++) {
591                     excludedNamespaces[i] = (short)(codes[i] & 0xffff);
592                 }
593             } else {
594                 // go round twice, once to count the values and next to add them to the array
595
int count = 0;
596                 StringTokenizer JavaDoc st1 = new StringTokenizer JavaDoc(ext);
597                 while (st1.hasMoreTokens()) {
598                     st1.nextToken();
599                     count++;
600                 }
601                 excludedNamespaces = new short[count];
602                 count = 0;
603                 StringTokenizer JavaDoc st2 = new StringTokenizer JavaDoc(ext);
604                 while (st2.hasMoreTokens()) {
605                     String JavaDoc s = st2.nextToken();
606                     if ("#default".equals(s)) {
607                         s = "";
608                     } else if ("#all".equals(s)) {
609                         compileError("In exclude-result-prefixes, cannot mix #all with other values", "XTSE0020");
610                     }
611                     try {
612                         short uriCode = getURICodeForPrefix(s);
613                         excludedNamespaces[count++] = uriCode;
614                     } catch (NamespaceException err) {
615                         excludedNamespaces = null;
616                         compileError(err.getMessage(), "XTSE0280");
617                     }
618                 }
619             }
620         }
621     }
622
623     /**
624      * Process the [xsl:]version attribute if there is one
625      *
626      * @param nc the Clark name of the attribute required
627      */

628
629     protected void processVersionAttribute(String JavaDoc nc) throws XPathException {
630         String JavaDoc v = getAttributeValue(nc);
631         if (v != null) {
632             AtomicValue val = DecimalValue.makeDecimalValue(v, true);
633             if (val instanceof ValidationErrorValue) {
634                 compileError("The version attribute must be a decimal literal");
635             }
636             version = ((DecimalValue)val).getValue();
637         }
638     }
639
640     /**
641      * Get the numeric value of the version number on this element,
642      * or inherited from its ancestors
643      */

644
645     public BigDecimal JavaDoc getVersion() {
646         if (version == null) {
647             NodeInfo node = getParent();
648             if (node instanceof StyleElement) {
649                 version = ((StyleElement)node).getVersion();
650             } else {
651                 version = new BigDecimal JavaDoc("2.0"); // defensive programming
652
}
653         }
654         return version;
655     }
656
657     /**
658      * Determine whether forwards-compatible mode is enabled for this element
659      */

660
661     public boolean forwardsCompatibleModeIsEnabled() {
662         return getVersion().compareTo(BigDecimal.valueOf(2)) > 0;
663     }
664
665     /**
666      * Determine whether backwards-compatible mode is enabled for this element
667      */

668
669     public boolean backwardsCompatibleModeIsEnabled() {
670         return getVersion().compareTo(BigDecimal.valueOf(2)) < 0;
671     }
672
673     /**
674      * Process the [xsl:]default-xpath-namespace attribute if there is one
675      *
676      * @param nc the Clark name of the attribute required
677      */

678
679     protected void processDefaultCollationAttribute(String JavaDoc nc) throws XPathException {
680         String JavaDoc v = getAttributeValue(nc);
681         if (v != null) {
682             StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(v);
683             while (st.hasMoreTokens()) {
684                 String JavaDoc uri = st.nextToken();
685                 if (uri.equals(NamespaceConstant.CODEPOINT_COLLATION_URI)) {
686                     defaultCollationName = uri;
687                     return;
688                 } else if (uri.startsWith("http://saxon.sf.net/")) {
689                     defaultCollationName = uri;
690                     return;
691                 } else if (getPrincipalStylesheet().getExecutable().getNamedCollation(uri) != null) {
692                     defaultCollationName = uri;
693                     return;
694                 }
695                 // if not recognized, try the next URI in order
696
}
697             compileError("No recognized collation URI found in default-collation attribute", "XTSE0125");
698         }
699     }
700
701     /**
702      * Get the default collation for this element
703      */

704
705     protected String JavaDoc getDefaultCollationName() {
706         StyleElement e = this;
707         while (true) {
708             if (e.defaultCollationName != null) {
709                 return e.defaultCollationName;
710             }
711             NodeInfo p = e.getParent();
712             if (!(p instanceof StyleElement)) {
713                 break;
714             }
715             e = (StyleElement)p;
716         }
717         return getPrincipalStylesheet().getDefaultCollationName();
718     }
719
720     /**
721      * Check whether a particular extension element namespace is defined on this node.
722      * This checks this node only, not the ancestor nodes.
723      * The implementation checks whether the prefix is included in the
724      * [xsl:]extension-element-prefixes attribute.
725      *
726      * @param uriCode the namespace URI code being tested
727      */

728
729     protected boolean definesExtensionElement(short uriCode) {
730         if (extensionNamespaces == null) {
731             return false;
732         }
733         for (int i = 0; i < extensionNamespaces.length; i++) {
734             if (extensionNamespaces[i] == uriCode) {
735                 return true;
736             }
737         }
738         return false;
739     }
740
741     /**
742      * Check whether a namespace uri defines an extension element. This checks whether the
743      * namespace is defined as an extension namespace on this or any ancestor node.
744      *
745      * @param uriCode the namespace URI code being tested
746      */

747
748     public boolean isExtensionNamespace(short uriCode) {
749         NodeInfo anc = this;
750         while (anc instanceof StyleElement) {
751             if (((StyleElement)anc).definesExtensionElement(uriCode)) {
752                 return true;
753             }
754             anc = anc.getParent();
755         }
756         return false;
757     }
758
759     /**
760      * Check whether this node excludes a particular namespace from the result.
761      * This method checks this node only, not the ancestor nodes.
762      *
763      * @param uriCode the code of the namespace URI being tested
764      */

765
766     protected boolean definesExcludedNamespace(short uriCode) {
767         if (excludedNamespaces == null) {
768             return false;
769         }
770         for (int i = 0; i < excludedNamespaces.length; i++) {
771             if (excludedNamespaces[i] == uriCode) {
772                 return true;
773             }
774         }
775         return false;
776     }
777
778     /**
779      * Check whether a namespace uri defines an namespace excluded from the result.
780      * This checks whether the namespace is defined as an excluded namespace on this
781      * or any ancestor node.
782      *
783      * @param uriCode the code of the namespace URI being tested
784      */

785
786     public boolean isExcludedNamespace(short uriCode) {
787         if (uriCode == NamespaceConstant.XSLT_CODE) {
788             return true;
789         }
790         if (isExtensionNamespace(uriCode)) {
791             return true;
792         }
793         NodeInfo anc = this;
794         while (anc instanceof StyleElement) {
795             if (((StyleElement)anc).definesExcludedNamespace(uriCode)) {
796                 return true;
797             }
798             anc = anc.getParent();
799         }
800         return false;
801     }
802
803     /**
804      * Process the [xsl:]default-xpath-namespace attribute if there is one
805      *
806      * @param nc the Clark name of the attribute required
807      */

808
809     protected void processDefaultXPathNamespaceAttribute(String JavaDoc nc) throws TransformerConfigurationException JavaDoc {
810         String JavaDoc v = getAttributeValue(nc);
811         if (v != null) {
812             defaultXPathNamespace = v;
813         }
814     }
815
816     /**
817      * Get the default XPath namespace code applicable to this element
818      */

819
820     protected short getDefaultXPathNamespace() {
821         NodeInfo anc = this;
822         while (anc instanceof StyleElement) {
823             String JavaDoc x = ((StyleElement)anc).defaultXPathNamespace;
824             if (x != null) {
825                 return getTargetNamePool().allocateCodeForURI(x);
826             }
827             anc = anc.getParent();
828         }
829         return NamespaceConstant.NULL_CODE;
830         // indicates that the default namespace is the null namespace
831
}
832
833     /**
834      * Get the Schema type definition for a type named in the stylesheet (in a
835      * "type" attribute).
836      *
837      * @throws XPathException
838      * if the type is not declared in an
839      * imported schema, or is not a built-in type
840      */

841
842     public SchemaType getSchemaType(String JavaDoc typeAtt) throws XPathException {
843         try {
844             String JavaDoc[] parts = Name.getQNameParts(typeAtt);
845             String JavaDoc lname = parts[1];
846             String JavaDoc uri;
847             if ("".equals(parts[0])) {
848                 // Name is unprefixed: use the default-xpath-namespace
849
short uricode = getDefaultXPathNamespace();
850                 uri = getTargetNamePool().getURIFromURICode(uricode);
851                 nameCode = getTargetNamePool().allocate(parts[0], uricode, lname);
852             } else {
853      &nbs