1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the  "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 #if !defined(XALAN_ELEMTEMPLATEELEMENT_HEADER_GUARD)
19 #define XALAN_ELEMTEMPLATEELEMENT_HEADER_GUARD
20 
21 
22 
23 // Base include file.  Must be first.
24 #include <xalanc/XSLT/XSLTDefinitions.hpp>
25 
26 
27 
28 #include <xalanc/XalanDOM/XalanDOMString.hpp>
29 #include <xalanc/XalanDOM/XalanNode.hpp>
30 
31 
32 
33 #include <xalanc/PlatformSupport/DOMStringHelper.hpp>
34 #include <xalanc/PlatformSupport/PrefixResolver.hpp>
35 #include <xalanc/PlatformSupport/XalanLocator.hpp>
36 
37 
38 
39 #include <xalanc/XPath/XalanQNameByReference.hpp>
40 
41 
42 
43 #include <xalanc/XSLT/NamespacesHandler.hpp>
44 
45 
46 
47 #include "LocalMsgIndex.hpp"
48 
49 
50 
51 namespace XERCES_CPP_NAMESPACE
52 {
53     class AttributeList;
54     class Locator;
55 }
56 
57 
58 
59 namespace XALAN_CPP_NAMESPACE {
60 
61 
62 
63 typedef xercesc::AttributeList    AttributeListType;
64 typedef xercesc::Locator          LocatorType;
65 
66 
67 using xercesc::AttributeList;
68 using xercesc::Locator;
69 class ElemTemplate;
70 class ElemTextLiteral;
71 class NamespacesHandler;
72 class Stylesheet;
73 class StylesheetConstructionContext;
74 class StylesheetExecutionContext;
75 class XPath;
76 
77 
78 
79 class XALAN_XSLT_EXPORT ElemTemplateElement : public PrefixResolver
80 {
81 
82 public:
83 
84     /**
85      * Construct a template element instance.
86      *
87      * @param constructionContext  context when object constructed
88      * @param stylesheetTree       owning stylesheet
89      * @param lineNumber           line in the XSLT file where the element occurs
90      * @param columnNumber         column index in the XSLT file where the
91      *                             element occurs
92      * @param xslToken             an integer representing the type of instance.
93      */
94     ElemTemplateElement(
95             StylesheetConstructionContext&  constructionContext,
96             Stylesheet&                     stylesheetTree,
97             XalanFileLoc                    lineNumber,
98             XalanFileLoc                    columnNumber,
99             int                             xslToken);
100 
101     /**
102      * Special constructor used by dummy elements which do not exist in the
103      * final stylesheet.
104      *
105      * @param constructionContext  context when object constructed
106      * @param stylesheetTree       owning stylesheet
107      * @param baseURI              The base URI of the XSLT file where the element occurs.
108      * @param lineNumber           line in the XSLT file where the element occurs
109      * @param columnNumber         column index in the XSLT file where the
110      *                             element occurs
111      * @param xslToken             an integer representing the type of instance.
112      */
113     ElemTemplateElement(
114             StylesheetConstructionContext&  constructionContext,
115             Stylesheet&                     stylesheetTree,
116             int                             xslToken,
117             const XalanDOMString&           baseURI = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
118             XalanFileLoc                    lineNumber = XalanLocator::getUnknownValue(),
119             XalanFileLoc                    columnNumber = XalanLocator::getUnknownValue());
120 
121     virtual
122     ~ElemTemplateElement();
123 
124     /**
125      * Get the Locator for the node.  This may return 0.
126      *
127      * @return The Locator for the node.
128      */
129     virtual const Locator*
130     getLocator() const;
131 
132     /**
133      * See if this is a xmlns attribute or in a non-XSLT.
134      *
135      * @param attrName qualified name of attribute
136      * @param atts    attribute list where the element comes from (not used at
137      *                this time)
138      * @param which   index into the attribute list (not used at this time)
139      * @param constructionContext The current construction context
140      * @return        true if this is a namespace name
141      */
142     virtual bool
143     isAttrOK(
144             const XalanDOMChar*             attrName,
145             const AttributeListType&        atts,
146             XalanSize_t                     which,
147             StylesheetConstructionContext&  constructionContext) const;
148 
149     /**
150      * Tell whether or not this is a xml:space attribute and, if so, process it.
151      *
152      * @param elementName  name of the element with the attribute
153      * @param aname  name of the attribute in question
154      * @param atts   attribute list that owns the attribute
155      * @param which  index of the attribute into the attribute list
156      * @param constructionContext The current construction context
157      * @return       true if this is a xml:space attribute
158      */
159     bool
160     processSpaceAttr(
161             const XalanDOMChar*             elementName,
162             const XalanDOMChar*             aname,
163             const AttributeListType&        atts,
164             XalanSize_t                     which,
165             StylesheetConstructionContext&  constructionContext);
166 
167     /**
168      * Validate that the string is an NCName.
169      *
170      * @param s name in question
171      * @return  true if the string is a valid NCName according to XML rules
172      * @see http://www.w3.org/TR/REC-xml-names#NT-NCName
173      */
174     static bool
175     isValidNCName(const XalanDOMString&     s);
176 
177 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
178 
179     /**
180      * Completes  "pre-processing" before any sub-elements are invoked
181      * (i.e. children, attribute sets and templates).   If there are
182      * no sub-elements it executes the primary function of the element.
183      *
184      * @param executionContext  context to execute this element
185      */
186     virtual const ElemTemplateElement*
187     startElement(StylesheetExecutionContext&    executionContext) const;
188 
189     /**
190      * Completes  "post-processing" afer any sub-elements are invoked
191      * (i.e. children, attribute sets and templates).   If there are
192      * no sub-elements it does nothing
193      *
194      * @param executionContext  context to execute this element
195      */
196     virtual void
197     endElement(StylesheetExecutionContext&      executionContext) const;
198 
199     /**
200      * Execute the element.
201      *
202      * @param execute   context to execute this element
203      */
204     virtual void
205     execute(StylesheetExecutionContext&     executionContext) const;
206 
207     /**
208      * Execute the children of this element.
209      *
210      * @param execute   context to execute this element
211      */
212     virtual void
213     executeChildren(StylesheetExecutionContext&     executionContext) const;
214 
215     /**
216      * Returns the element that invoked this element.
217      * @returns element that invoked this element.
218      */
219     virtual const ElemTemplateElement*
220     getInvoker(StylesheetExecutionContext&  executionContext) const;
221 
222 #else
223 
224     /**
225      * Execute the element's primary function.  Subclasses of this function may
226      * recursively execute down the element tree.
227      *
228      * @param executionContext  The current execution context
229      */
230     virtual void
231     execute(StylesheetExecutionContext&     executionContext) const;
232 
233     /**
234      * Process the children of a template.
235      *
236      * @param processor  XSLT processor instance
237      */
238     virtual void
239     executeChildren(StylesheetExecutionContext&     executionContext) const;
240 
241     /**
242      * Set the current node and process the children of a template.
243      *
244      * @param processor  XSLT processor instance
245      * @param sourceNode current node
246      */
247     virtual void
248     executeChildren(
249             StylesheetExecutionContext&     executionContext,
250             XalanNode*                      sourceNode) const;
251 
252     /**
253      * Take the contents of a template element, process it, and
254      * convert it to a string.  Returns a const reference to
255      * the resulting string value.  Note that this may _not_ be
256      * the XalanDOMString instance passed in, if an optimization
257      * is available to return a pre-existing string.
258      *
259      * @param executionContext  The current execution context
260      * @param result result of executing the elements children
261      * @result a reference to a string containing the result.
262      */
263     const XalanDOMString&
264     childrenToString(
265             StylesheetExecutionContext&     executionContext,
266             XalanDOMString&                 result) const;
267 
268     /**
269      * Take the contents of a template element, process it, and
270      * convert it to a string.  Then, add an attribute to the
271      * result tree using the provided name and the string value.
272      *
273      * @param executionContext  The current execution context
274      * @param theName The name for the result attribute
275      */
276     void
277     childrenToResultAttribute(
278             StylesheetExecutionContext&     executionContext,
279             const XalanDOMString&           theName) const;
280 
281     /**
282      * Take the contents of a template element, process it, and
283      * convert it to a string.  Then, add a comment to the
284      * result tree using the string value.
285      *
286      * @param executionContext  The current execution context
287      */
288     void
289     childrenToResultComment(StylesheetExecutionContext& executionContext) const;
290 
291     /**
292      * Take the contents of a template element, process it, and
293      * convert it to a string.  Then, add a processing instruction
294      * to the result tree using the string value, and the provided
295      * target.
296      *
297      * @param executionContext  The current execution context
298      * @param theName The name for the result attribute
299      */
300     void
301     childrenToResultPI(
302             StylesheetExecutionContext&     executionContext,
303             const XalanDOMString&           theTarget) const;
304 
305     /**
306      * Get an integer representation of the element type.
307      *
308      * @return integer representation of the element, defined in the Constants
309      *         class
310      * @see class Constants
311      */
312 #endif
313 
314     int
getXSLToken() const315     getXSLToken() const
316     {
317         return m_xslToken;
318     }
319 
320     /**
321      * Tell if the element will generate text which is XML whitespace.
322      *
323      * @return true if the text is pure whitespace
324      */
325     virtual bool
326     isWhitespace() const;
327 
328     /**
329      * Get a string for the name of the element.  Useful for debugging purposes,
330      * and error reporting.
331      *
332      * @return A string containing the name of the element.
333      */
334     virtual const XalanDOMString&
335     getElementName() const = 0;
336 
337     /**
338      * Get the QName associated with any name attribute of this element.
339      * If the element has no name attribute, this will be an empty QName.
340      *
341      * @return A string containing the name of the element.
342      */
343     virtual const XalanQName&
344     getNameAttribute() const;
345 
346     /**
347      * Called during compilation when an instance is not parented by
348      * another element, and thus, is a child of the stylesheet..
349      *
350      * @param constructionContext  The current construction context
351      * @param theStylesheet The owning stylesheet
352      * @return nothing
353      */
354     virtual void
355     addToStylesheet(
356             StylesheetConstructionContext&  constructionContext,
357             Stylesheet&                     theStylesheet);
358 
359     /**
360      * Called during compilation to process xsl:sort elements in
361      * the stylesheet.
362      *
363      * @param constructionContext  The current construction context
364      * @param theStylesheet The owning stylesheet
365      * @param atts The list of attributes for the sort element
366      * @param locator A Locator instance for error reporting, if available.
367      *
368      * @return nothing
369      */
370     virtual void
371     processSortElement(
372             StylesheetConstructionContext&  constructionContext,
373             Stylesheet&                     theStylesheet,
374             const AttributeListType&        atts,
375             const Locator*                  locator = 0);
376 
377     /**
378      * Sets a flag indicating this is the default template
379      *
380      * @param value The value of flag.
381      */
382     virtual void
383     setDefaultTemplate(bool     value);
384 
385     /**
386      * Get the namespaces handler for this element.
387      *
388      * @return The element's NamespacesHandler instance.
389      */
390     const NamespacesHandler&
getNamespacesHandler() const391     getNamespacesHandler() const
392     {
393         return m_namespacesHandler;
394     }
395 
396     /**
397      * Retrieve the stylesheet from which this element comes
398      *
399      * @return reference to source stylesheet
400      */
401     const Stylesheet&
getStylesheet() const402     getStylesheet() const
403     {
404         return m_stylesheet;
405     }
406 
407     /**
408      * Set the flag indicating construction of the element is completed.
409      *
410      * @param fValue  The value to set
411      */
412     void
setFinishedConstruction(bool fValue)413     setFinishedConstruction(bool    fValue)
414     {
415         setFlag(eFinishedConstruction, fValue);
416     }
417 
418     /**
419      * Get the flag indicating construction of the element is completed.
420      */
421     bool
getFinishedConstruction() const422     getFinishedConstruction() const
423     {
424         return getFlag(eFinishedConstruction);
425     }
426 
427     /**
428      * Called after construction is completed.
429      */
430     virtual void
431     postConstruction(
432             StylesheetConstructionContext&  constructionContext,
433             const NamespacesHandler&        theParentHandler);
434 
435     // Type-safe getters/setters...
436 
437     /**
438      * Get the first child.
439      *
440      * @return first child node of this node
441      */
442     virtual ElemTemplateElement*
443     getFirstChildElem() const;
444 
445 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
446     /**
447      * Method to initiate the execution of the element's children.
448      *
449      * @param executionContext  context to execute this element
450      * @returns the first child element to execute
451      */
452     virtual const ElemTemplateElement*
453     beginExecuteChildren(
454             StylesheetExecutionContext& executionContext) const;
455 
456 
457     /**
458      * Method to indicate the execution of the element's children
459      * is complete
460      *
461      * @param executionContext  context to execute this element
462      */
463     virtual void
464     endExecuteChildren(
465             StylesheetExecutionContext& executionContext) const;
466 
467     /**
468      * Method to initiate output from the children
469      * to a string.
470      *
471      * @param executionContext      context to execute this element
472      * @param result                string to contain the final result
473      * @returns                     the first child element to execute
474      */
475     const ElemTemplateElement*
476     beginChildrenToString(
477             StylesheetExecutionContext&     executionContext,
478             XalanDOMString&                 result) const;
479 
480 
481     /**
482      * Method to indicate string output from the children is
483      * complete.
484      *
485      * @param executionContext      context to execute this element
486      */
487     void
488     endChildrenToString(
489             StylesheetExecutionContext&     executionContext) const;
490 #endif
491 
492 
493     /**
494      * Set the first child.
495      *
496      * theChild - the new value for the first child.
497      *
498      * @return nothing
499      */
500     virtual void
501     setFirstChildElem(ElemTemplateElement*  theChild);
502 
503     /**
504      * Get the last child.
505      *
506      * @return last child node of this node
507      */
508     virtual ElemTemplateElement*
509     getLastChildElem() const;
510 
511     /**
512      * Get the next sibling.
513      *
514      * @return next sibling node of this node
515      */
516     virtual ElemTemplateElement*
517     getNextSiblingElem() const;
518 
519 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
520 
521     /**
522      * Returns the next sub-element
523      *(i.e. children, attribute-sets, templates) to execute.
524      *
525      * @param executionContext      context to execute element
526      * @param currentElem           the last sub-element to be executed
527      * @returns                     next sub-element to execute,  0 only if no more sub-elements to execute
528      */
529     virtual const ElemTemplateElement*
530     getNextChildElemToExecute(
531             StylesheetExecutionContext& executionContext,
532             const ElemTemplateElement*  currentElem) const;
533 
534     /**
535      * Returns the first sub-element
536      *(i.e. children, attribute-sets, templates) to execute.
537      *
538      * @param executionContext      context to execute element
539      * @returns                     first sub-element to execute,  0 only if no sub-elements to execute
540      */
541     virtual const ElemTemplateElement*
542     getFirstChildElemToExecute(
543             StylesheetExecutionContext& executionContext) const;
544 
545     /**
546      * Filters sub-elements that should be executed
547      *
548      * @param executionContext      context to execute element
549      * @param element               the element to be executed
550      * @returns                     true if element should be executed, false otherwise
551      */
552     virtual bool executeChildElement(
553             StylesheetExecutionContext& executionContext,
554             const ElemTemplateElement* element) const;
555 #endif
556 
557     /**
558      * Set the next sibling.
559      *
560      * theSibling - the new value for the next sibling.
561      *
562      * @return nothing
563      */
564     virtual void
565     setNextSiblingElem(ElemTemplateElement*     theSibling);
566 
567     /**
568      * Get the previous sibling.
569      *
570      * @return previous sibling node of this node
571      */
572     virtual ElemTemplateElement*
573     getPreviousSiblingElem() const;
574 
575     /**
576      * Set the previous sibling.
577      *
578      * theSibling - the new value for the previous sibling.
579      *
580      * @return nothing
581      */
582     virtual void
583     setPreviousSiblingElem(ElemTemplateElement*     theSibling);
584 
585     /**
586      * Get the parent node.
587      *
588      * @return parent node of this node
589      */
590     virtual ElemTemplateElement*
591     getParentNodeElem() const;
592 
593     /**
594      * Set the parent node.
595      *
596      * theParent - the new value for the parent.
597      *
598      * @return nothing
599      */
600     virtual void
601     setParentNodeElem(ElemTemplateElement*      theParent);
602 
603     /**
604      * Append a child.
605      *
606      * theParent - the new value for the parent.
607      *
608      * @return nothing
609      */
610     virtual ElemTemplateElement*
611     appendChildElem(ElemTemplateElement*    newChild);
612 
613     /**
614      * Get XPath pattern/expression of one of the element atribute
615      *
616      * @index   number of the attribute. If an attribute has more
617      *              then one attribute with pattern/expression,the order of
618      *              the returned expressions are undefined
619      *
620      * @return pointer or null
621      */
622     virtual const XPath*
623     getXPath(XalanSize_t    index) const;
624 
625     // These interfaces are inherited from PrefixResolver...
626 
627     virtual const XalanDOMString*
628     getNamespaceForPrefix(const XalanDOMString& prefix) const;
629 
630     virtual const XalanDOMString&
631     getURI() const;
632 
633     // A class that implements the XalanLocator
634     // abstract base class.  ElemTemplateElement
635     // uses this class to provide locator information.
636     class LocatorProxy : public XalanLocator
637     {
638     public:
639 
640         LocatorProxy(
641                     XalanFileLoc            theLineNumber,
642                     XalanFileLoc            theColumnNumber,
643                     const XalanDOMString&   theURI);
644 
645         virtual
646         ~LocatorProxy();
647 
648         virtual const XMLCh*
649         getPublicId() const;
650 
651         virtual const XMLCh*
652         getSystemId() const;
653 
654         virtual XalanFileLoc
655         getLineNumber() const;
656 
657         virtual XalanFileLoc
658         getColumnNumber() const;
659 
660         const XalanDOMString&
getURI() const661         getURI() const
662         {
663             return m_uri;
664         }
665 
666     private:
667 
668         // Not implemented...
669         LocatorProxy(const LocatorProxy&);
670 
671         LocatorProxy&
672         operator=(const LocatorProxy&);
673 
674         bool
675         operator==(const LocatorProxy&) const;
676 
677         // data members...
678         const XalanFileLoc      m_lineNumber;
679 
680         const XalanFileLoc      m_columnNumber;
681 
682         const XalanDOMString&   m_uri;
683     };
684 
685 
686     XalanFileLoc
getLineNumber() const687     getLineNumber() const
688     {
689         return m_locatorProxy.getLineNumber();
690     }
691 
692     XalanFileLoc
getColumnNumber() const693     getColumnNumber() const
694     {
695         return m_locatorProxy.getColumnNumber();
696     }
697 
698     bool
hasParams() const699     hasParams() const
700     {
701         return getFlag(eHasParams);
702     }
703 
704     bool
hasVariables() const705     hasVariables() const
706     {
707         return getFlag(eHasVariables);
708     }
709 
710     bool
hasSingleTextChild() const711     hasSingleTextChild() const
712     {
713         return getFlag(eHasSingleTextChild);
714     }
715 
716     bool
hasChildren() const717     hasChildren() const
718     {
719         return m_firstChild != 0 ? true : false;
720     }
721 
722     bool
hasDirectTemplate() const723     hasDirectTemplate() const
724     {
725         return getFlag(eHasDirectTemplate);
726     }
727 
728     bool
canGenerateAttributes() const729     canGenerateAttributes() const
730     {
731         return getFlag(eCanGenerateAttributes);
732     }
733 
734     bool
isDefaultTemplate() const735     isDefaultTemplate() const
736     {
737         return getFlag(eDefaultTemplate);
738     }
739 
740 protected:
741 
742     void
canGenerateAttributes(bool value)743     canGenerateAttributes(bool  value)
744     {
745         setFlag(eCanGenerateAttributes, value);
746     }
747 
748     void
hasPrefix(bool value)749     hasPrefix(bool  value)
750     {
751         setFlag(eHasPrefix, value);
752     }
753 
754     bool
hasPrefix() const755     hasPrefix() const
756     {
757         return getFlag(eHasPrefix);
758     }
759 
760     void
preserveSpace(bool value)761     preserveSpace(bool  value)
762     {
763         setFlag(eSpacePreserve, value);
764     }
765 
766     bool
preserveSpace() const767     preserveSpace() const
768     {
769         return getFlag(eSpacePreserve);
770     }
771 
772     void
disableOutputEscaping(bool value)773     disableOutputEscaping(bool  value)
774     {
775         setFlag(eDisableOutputEscaping, value);
776     }
777 
778     bool
disableOutputEscaping() const779     disableOutputEscaping() const
780     {
781         return getFlag(eDisableOutputEscaping);
782     }
783 
784     /**
785      * Process the exclude-result-prefixes or the extension-element-prefixes
786      * attributes, for the purpose of prefix exclusion.
787      *
788      * @param constructionContext  context when object consructed
789      * @param stylesheetTree The current Stylesheet object.
790      * @param localName The local name of the attribute.
791      * @param attrValue The value of the attribute.
792      */
793     bool
794     processPrefixControl(
795             StylesheetConstructionContext&  constructionContext,
796             const Stylesheet&               stylesheetTree,
797             const XalanDOMString&           localName,
798             const XalanDOMChar*             attrValue);
799 
800     /**
801      * Get the namespace for a given prefix.
802      *
803      * @param prefix The prefix to search for
804      * @param fExists If not null, set to true if the namespace was defined.
805      * @return The namespace string.
806      */
807     const XalanDOMString*
808     getNamespaceForPrefixInternal(const XalanDOMString&     prefix) const;
809 
810 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
811     /**
812      * Given an element, find the corresponding
813      * template.
814      *
815      * @param executionContext  The current execution context
816      * @param xslInstruction    The calling element
817      * @param template          The template to use if xsl:for-each, or null.
818      * @param child             The source context node.
819      * @returns                 matching template if any.  Returns 0 if no matching template or corresponds to a default rule.
820      */
821     virtual const ElemTemplateElement*
822     findTemplateToTransformChild(
823             StylesheetExecutionContext&     executionContext,
824             const ElemTemplateElement&      xslInstruction,
825             const ElemTemplateElement*      theTemplate,
826             XalanNode*                      child) const;
827 
828     /**
829      * Given an element, find the corresponding
830      * template.
831      *
832      * @param executionContext  The current execution context
833      * @param xslInstruction    The calling element
834      * @param template          The template to use if xsl:for-each, or null.
835      * @param child             The source context node.
836      * @param nodeType The type of child.
837      * @returns                 matching template if any.  Returns 0 if no matching template or corresponds to a default rule.
838      */
839     virtual const ElemTemplateElement*
840     findTemplateToTransformChild(
841             StylesheetExecutionContext&     executionContext,
842             const ElemTemplateElement&      xslInstruction,
843             const ElemTemplateElement*      theTemplate,
844             XalanNode*                      child,
845             XalanNode::NodeType             nodeType) const;
846 #else
847     /**
848      * Given an element, find the corresponding
849      * template and process the contents.
850      *
851      * @param executionContext The current execution context
852      * @param xslInstruction The calling element
853      * @param template The template to use if xsl:for-each, or null.
854      * @param child The source context node.
855      */
856     virtual void
857     transformChild(
858             StylesheetExecutionContext&     executionContext,
859             const ElemTemplateElement&      xslInstruction,
860             const ElemTemplateElement*      theTemplate,
861             XalanNode*                      child) const;
862 
863     /**
864      * Given an element, find the corresponding
865      * template and process the contents.
866      *
867      * @param executionContext The current execution context
868      * @param xslInstruction The calling element
869      * @param template The template to use if xsl:for-each, or null.
870      * @param child The source context node.
871      * @param nodeType The type of child.
872      */
873     virtual void
874     transformChild(
875             StylesheetExecutionContext&     executionContext,
876             const ElemTemplateElement&      xslInstruction,
877             const ElemTemplateElement*      theTemplate,
878             XalanNode*                      child,
879             XalanNode::NodeType             nodeType) const;
880 #endif
881 
882     /**
883      * Given an xsl token type, determine whether or not a child
884      * of that type is allowed.  This is so derived types can
885      * determine whether a particular type of child is allowed for
886      * the instance.  It is called from appendChildElem().
887      *
888      * The default is to allow no types (no children)
889      *
890      * @param xslToken The xsl token value of the child.
891      *
892      * @return true if the child is allowed, or false if not.
893      */
894     virtual bool
895     childTypeAllowed(int    xslToken) const;
896 
897     /**
898      * Called after construction is completed.  This is a hook for
899      * deriving classes to handle post-construction with the
900      * instances HamespaceHandler instance, which is otherwise only
901      * available through a const accessor.
902      */
903     virtual void
904     namespacesPostConstruction(
905             StylesheetConstructionContext&  constructionContext,
906             const NamespacesHandler&        theParentHandler,
907             NamespacesHandler&              theHandler);
908 
909     const NamespacesHandler&
getNamespaces() const910     getNamespaces() const
911     {
912         return m_namespacesHandler;
913     }
914 
915     /**
916      * A convenience function for loading a message
917      * and reporting an error through the provided
918      * StylesheetExecutionContext instance.
919      *
920      * @param theContext The StylesheetExecutionContext to use
921      * @param theCode The code of the message
922      */
923     void
924     error(
925             StylesheetExecutionContext&     theContext,
926             XalanMessages::Codes            theCode) const;
927 
928     /**
929      * A convenience function for loading a message
930      * and reporting an error through the provided
931      * StylesheetExecutionContext instance.
932      *
933      * @param theContext The StylesheetExecutionContext to use
934      * @param theCode The code of the message
935      * @param theToken The substitution token for the message
936      */
937     void
938     error(
939             StylesheetExecutionContext&     theContext,
940             XalanMessages::Codes            theCode,
941             const XalanDOMString&           theToken) const;
942 
943     /**
944      * A convenience function for loading a message
945      * and reporting an error through the provided
946      * StylesheetExecutionContext instance.
947      *
948      * @param theContext The StylesheetExecutionContext to use
949      * @param theCode The code of the message
950      * @param theLocator The Locator instance to use, if any
951      */
952     void
953     error(
954             StylesheetExecutionContext&     theContext,
955             XalanMessages::Codes            theCode,
956             const Locator*                  theLocator) const;
957 
958     /**
959      * A convenience function for loading a message
960      * and reporting a warning through the provided
961      * StylesheetExecutionContext instance.
962      *
963      * @param theContext The StylesheetExecutionContext to use
964      * @param theCode The code of the message
965      */
966     void
967     warn(
968             StylesheetExecutionContext&     theContext,
969             XalanMessages::Codes            theCode) const;
970 
971     /**
972      * A convenience function for loading a message
973      * and reporting a warning through the provided
974      * StylesheetExecutionContext instance.
975      *
976      * @param theContext The StylesheetExecutionContext to use
977      * @param theCode The code of the message
978      * @param theToken The substitution token for the message
979      */
980     void
981     warn(
982             StylesheetExecutionContext&     theContext,
983             XalanMessages::Codes            theCode,
984             const XalanDOMString&           theToken) const;
985 
986     /**
987      * A convenience function for loading a message
988      * and reporting a warning through the provided
989      * StylesheetExecutionContext instance.
990      *
991      * @param theContext The StylesheetExecutionContext to use
992      * @param theCode The code of the message
993      * @param theLocator The Locator instance to use, if any
994      */
995     void
996     warn(
997             StylesheetExecutionContext&     theContext,
998             XalanMessages::Codes            theCode,
999             const Locator*                  theLocator) const;
1000 
1001     /**
1002      * A convenience function for loading a message
1003      * and reporting an error through the provided
1004      * StylesheetConstructionContext instance.
1005      *
1006      * @param theContext The StylesheetConstructionContext to use
1007      * @param theCode The code of the message
1008      */
1009     void
1010     error(
1011             StylesheetConstructionContext&  theContext,
1012             XalanMessages::Codes            theCode);
1013 
1014     /**
1015      * A convenience function for loading a message
1016      * and reporting an error through the provided
1017      * StylesheetConstructionContext instance.
1018      *
1019      * @param theContext The StylesheetConstructionContext to use
1020      * @param theCode The code of the message
1021      * @param theToken The substitution token for the message
1022      * @param theLocator The Locator instance to use, if any
1023      */
1024     void
1025     error(
1026             StylesheetConstructionContext&  theContext,
1027             XalanMessages::Codes            theCode,
1028             const XalanDOMString&           theToken);
1029 
1030     /**
1031      * A convenience function for loading a message
1032      * and reporting an error through the provided
1033      * StylesheetConstructionContext instance.
1034      *
1035      * @param theContext The StylesheetConstructionContext to use
1036      * @param theCode The code of the message
1037      * @param theToken The substitution token for the message
1038      * @param theLocator The Locator instance to use, if any
1039      */
1040     void
1041     error(
1042             StylesheetConstructionContext&  theContext,
1043             XalanMessages::Codes            theCode,
1044             const XalanDOMString&           theToken,
1045             const Locator*                  theLocator);
1046 
1047     /**
1048      * A convenience function for loading a message
1049      * and reporting an error through the provided
1050      * StylesheetConstructionContext instance.
1051      *
1052      * @param theContext The StylesheetConstructionContext to use
1053      * @param theCode The code of the message
1054      * @param theToken1 The first substitution token for the message
1055      * @param theToken2 The second substitution token for the message
1056      */
1057     void
1058     error(
1059             StylesheetConstructionContext&  theContext,
1060             XalanMessages::Codes            theCode,
1061             const XalanDOMString&           theToken1,
1062             const XalanDOMString&           theToken2);
1063 
1064     /**
1065      * A convenience function for loading a message
1066      * and reporting an error through the provided
1067      * StylesheetConstructionContext instance.
1068      *
1069      * @param theContext The StylesheetConstructionContext to use
1070      * @param theCode The code of the message
1071      * @param theToken1 The first substitution token for the message
1072      * @param theToken2 The second substitution token for the message
1073      */
1074     void
1075     error(
1076             StylesheetConstructionContext&  theContext,
1077             XalanMessages::Codes            theCode,
1078             const XalanDOMChar*             theToken1,
1079             const XalanDOMChar*             theToken2);
1080 
1081     /**
1082      * A convenience function for loading a message
1083      * and reporting an error through the provided
1084      * StylesheetConstructionContext instance.
1085      *
1086      * @param theContext The StylesheetConstructionContext to use
1087      * @param theCode The code of the message
1088      * @param theToken1 The first substitution token for the message
1089      * @param theToken2 The second substitution token for the message
1090      * @param theToken3 The third substitution token for the message
1091      */
1092     void
1093     error(
1094             StylesheetConstructionContext&  theContext,
1095             XalanMessages::Codes            theCode,
1096             const XalanDOMChar*             theToken1,
1097             const XalanDOMChar*             theToken2,
1098             const XalanDOMChar*             theToken3);
1099 
1100     /**
1101      * A convenience function for loading a message
1102      * and reporting a warning through the provided
1103      * StylesheetConstructionContext instance.
1104      *
1105      * @param theContext The StylesheetConstructionContext to use
1106      * @param theCode The code of the message
1107      * @param theToken1 The first substitution token for the message
1108      * @param theToken2 The second substitution token for the message
1109      * @param theToken3 The third substitution token for the message
1110      */
1111     void
1112     warn(
1113             StylesheetConstructionContext&  theContext,
1114             XalanMessages::Codes            theCode,
1115             const XalanDOMChar*             theToken1,
1116             const XalanDOMChar*             theToken2,
1117             const XalanDOMChar*             theToken3);
1118 
1119     // A handy empty XalanDOMString instance for
1120     // derived classes to use.
1121     static const XalanDOMString     s_emptyString;
1122 
1123 private:
1124 
1125     enum eFlags
1126     {
1127         eHasParams = 1,
1128         eHasSingleTextChild = 2,
1129         eHasVariables = 4,
1130         eHasDirectTemplate = 8,
1131         eCanGenerateAttributes = 16,
1132         eDefaultTemplate = 32,
1133         eSpacePreserve = 64,
1134         eFinishedConstruction = 128,
1135         eHasPrefix = 256,
1136         eDisableOutputEscaping = 512
1137     };
1138 
1139     bool
getFlag(eFlags theFlag) const1140     getFlag(eFlags  theFlag) const
1141     {
1142         return m_flags & theFlag ? true : false;
1143     }
1144 
1145     void
setFlag(eFlags theFlag,bool theValue)1146     setFlag(
1147             eFlags  theFlag,
1148             bool    theValue)
1149     {
1150         if (theValue == true)
1151         {
1152             m_flags |= theFlag;
1153         }
1154         else
1155         {
1156             m_flags &= ~theFlag;
1157         }
1158     }
1159 
1160 
1161 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
1162     /**
1163      * Take the contents of a template element, process it, and
1164      * convert it to a string.
1165      *
1166      * @param executionContext  The current execution context
1167      * @param result result of executing the elements children
1168      * @result a reference to a string containing the result.
1169      */
1170     XalanDOMString&
1171     doChildrenToString(
1172             StylesheetExecutionContext&     executionContext,
1173             XalanDOMString&                 result) const;
1174 #endif
1175 
1176     Stylesheet&             m_stylesheet;
1177 
1178     /*
1179      * This object handles all result tree namespace processing.
1180      */
1181     NamespacesHandler       m_namespacesHandler;
1182 
1183     const int               m_xslToken;
1184 
1185     ElemTemplateElement*    m_parentNode;
1186     ElemTemplateElement*    m_nextSibling;
1187     ElemTemplateElement*    m_previousSibling;
1188 
1189     union
1190     {
1191         ElemTemplateElement*    m_firstChild;
1192         const ElemTemplate*     m_directTemplate;
1193         const ElemTextLiteral*  m_textLiteralChild;
1194     };
1195 
1196     LocatorProxy            m_locatorProxy;
1197 
1198     unsigned short          m_flags;
1199 
1200     static const XalanQNameByReference      s_emptyQName;
1201 
1202     // Not implemented...
1203     ElemTemplateElement(const ElemTemplateElement&);
1204 
1205     ElemTemplateElement&
1206     operator=(const ElemTemplateElement&);
1207 
1208     bool
1209     operator==(const ElemTemplateElement&) const;
1210 };
1211 
1212 
1213 
1214 }
1215 
1216 
1217 
1218 #endif  // XALAN_ELEMTEMPLATEELEMENT_HEADER_GUARD
1219