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(STYLESHEETEXECUTIONCONTEXT_HEADER_GUARD_1357924680)
19 #define STYLESHEETEXECUTIONCONTEXT_HEADER_GUARD_1357924680
20 
21 
22 
23 // Base include file.  Must be first.
24 #include <xalanc/XSLT/XSLTDefinitions.hpp>
25 
26 
27 
28 #include <cstddef>
29 #include <cstdio>
30 #include <memory>
31 
32 
33 
34 // Base class header file...
35 #include <xalanc/XPath/XPathExecutionContext.hpp>
36 
37 
38 
39 
40 #include <xalanc/XalanDOM/XalanDOMString.hpp>
41 
42 
43 
44 #if defined(XALAN_AUTO_PTR_REQUIRES_DEFINITION)
45 #include <xalanc/PlatformSupport/XalanNumberFormat.hpp>
46 #endif
47 
48 
49 
50 #include <xalanc/Include/XalanMemMgrAutoPtr.hpp>
51 
52 
53 
54 
55 #include <xalanc/PlatformSupport/AttributeListImpl.hpp>
56 #include <xalanc/PlatformSupport/FormatterListener.hpp>
57 #include <xalanc/PlatformSupport/XalanCollationServices.hpp>
58 
59 
60 
61 #include <xalanc/XSLT/TopLevelArg.hpp>
62 
63 
64 
65 namespace XALAN_CPP_NAMESPACE {
66 
67 
68 
69 using std::FILE;
70 
71 
72 
73 class CountersTable;
74 class ElemTemplate;
75 class ElemTemplateElement;
76 class ElemVariable;
77 class FormatterListener;
78 class FormatterToText;
79 class GenerateEvent;
80 class PrefixResolver;
81 class NodeRefListBase;
82 class NodeSorter;
83 class PrintWriter;
84 class XalanQName;
85 class SelectionEvent;
86 class Stylesheet;
87 class StylesheetRoot;
88 class XalanOutputStream;
89 class TracerEvent;
90 class Writer;
91 class XalanDocument;
92 class XalanDocumentFragment;
93 class XalanElement;
94 class XalanNode;
95 class XalanNumberFormat;
96 class XPath;
97 class XObject;
98 class XObjectPtr;
99 class XResultTreeFrag;
100 
101 
102 
103 //
104 // An abstract class which provides support for executing stylesheets.
105 //
106 class XALAN_XSLT_EXPORT StylesheetExecutionContext : public XPathExecutionContext
107 {
108 public:
109 
110     typedef XalanSize_t     tl_size_type;
111 
112     typedef FormatterListener::size_type    fl_size_type;
113 
114     typedef std::ostream    StreamType;
115 
116     explicit
117     StylesheetExecutionContext(
118             MemoryManager&      theMemoryManager,
119             XObjectFactory*     theXObjectFactory = 0);
120 
121     virtual
122     ~StylesheetExecutionContext();
123 
124     // These interfaces are new...
125 
126     /**
127      * Determine whether conflicts should be reported.
128      *
129      * @return true if conflicts should not be warned
130      */
131     virtual bool
132     getQuietConflictWarnings() const = 0;
133 
134     /**
135      * If this function returns true, only text nodes can
136      * be copied to the result tree.
137      *
138      * @return true or false
139      */
140     virtual bool
141     getCopyTextNodesOnly() const = 0;
142 
143     /**
144      * Set the flag that determines if only text nodes
145      * can be copied to the result tree.
146      *
147      * @param copyTextNodesOnly The value of the flag
148      */
149     virtual void
150     pushCopyTextNodesOnly(bool copyTextNodesOnly) = 0;
151 
152     /**
153      * Pop the last flag setting that determines if only text nodes
154      * can be copied to the result tree.
155      */
156     virtual bool
157     popCopyTextNodesOnly() = 0;
158 
159     /*
160      * A class to manage setting and restoring the flag
161      * for restricting copying only text nodes to the
162      * result tree
163      */
164     class SetAndRestoreCopyTextNodesOnly
165     {
166     public:
167 
SetAndRestoreCopyTextNodesOnly(StylesheetExecutionContext & executionContext,bool fValue)168         SetAndRestoreCopyTextNodesOnly(
169             StylesheetExecutionContext&     executionContext,
170             bool                            fValue) :
171             m_executionContext(executionContext)
172         {
173             executionContext.pushCopyTextNodesOnly(fValue);
174         }
175 
~SetAndRestoreCopyTextNodesOnly()176         ~SetAndRestoreCopyTextNodesOnly()
177         {
178             m_executionContext.popCopyTextNodesOnly();
179         }
180 
181     private:
182 
183         // Not implemented...
184         SetAndRestoreCopyTextNodesOnly(const SetAndRestoreCopyTextNodesOnly&);
185 
186         SetAndRestoreCopyTextNodesOnly&
187         operator=(const SetAndRestoreCopyTextNodesOnly&);
188 
189         // Data members...
190         StylesheetExecutionContext&     m_executionContext;
191 
192     };
193 
194 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
195     /**
196      * Set the flag that determines if the current attribute should be executed
197      * @param processAttribute the value of the flag
198      */
199     virtual void
200     pushProcessCurrentAttribute(bool processAttribute) = 0;
201 
202     /**
203      * Pops the last flag setting that determines if the current attribute should be executed
204      */
205     virtual bool
206     popProcessCurrentAttribute() = 0;
207 
208     /**
209      * Set the flag that determines if an element's attributes should be skipped
210      *
211      * @param skipAttributes the value of the flag
212      */
213     virtual void
214     pushSkipElementAttributes(bool skipAttributes) = 0;
215 
216     /**
217      * Get the last flag setting that determines if an element's attributes should be skipped
218      * @returns the value of the flag
219      */
220     virtual bool
221     getSkipElementAttributes() const = 0;
222 
223     /**
224      * Pops the last flag setting that determines if an element's attributes should be skipped
225      */
226     virtual bool
227     popSkipElementAttributes() =  0;
228 
229     /**
230      * Set flag that determines if the if test was true
231      *
232      * @param executeIf the value of the flag
233      */
234     virtual void
235     pushExecuteIf(bool executeIf) = 0;
236 
237     /**
238      * Pop the flag that determines if the if test was true
239      *
240      * @param executeIf the value of the flag
241      */
242     virtual bool
243     popExecuteIf() = 0;
244 #endif
245 
246     /**
247      * Retrieve root document for stylesheet.  Note that
248      * this does not have to be a XalanDocument -- it can
249      * be any node in a document.
250      *
251      * @return root document
252      */
253     virtual XalanNode*
254     getRootDocument() const = 0;
255 
256     /**
257      * Set root document for stylesheet.  Note that
258      * this does not have to be a XalanDocument -- it can
259      * be any node in a document.
260      *
261      * @param theDocument root document
262      */
263     virtual void
264     setRootDocument(XalanNode*  theDocument) = 0;
265 
266     /**
267      * Set root stylesheet for stylesheet.
268      *
269      * @param theStylesheet root stylesheet
270      */
271     virtual void
272     setStylesheetRoot(const StylesheetRoot*     theStylesheet) = 0;
273 
274     /**
275      * Retrieve the current mode.
276      *
277      * @return QName for mode
278      */
279     virtual const XalanQName*
280     getCurrentMode() const = 0;
281 
282     /**
283      * Set the current mode.
284      *
285      * @param theMode QName for mode
286      */
287     virtual void
288     pushCurrentMode(const XalanQName* theMode) = 0;
289 
290 
291     /**
292      * Pop the current mode
293      */
294     virtual void
295     popCurrentMode() =0;
296 
297     /**
298      * Retrieve the current template
299      *
300      * @return The current template instance or null if there is no current template
301      */
302     virtual const ElemTemplate*
303     getCurrentTemplate() const = 0;
304 
305     /**
306      * Set the current template
307      *
308      * @param theTemplate The current template instance
309      */
310     virtual void
311     pushCurrentTemplate(const ElemTemplate*     theTemplate) = 0;
312 
313     virtual void
314     popCurrentTemplate() = 0;
315 
316 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
317     /*
318      * A class to manage pushing and popping the current
319      * template instance.
320      */
321     class PushAndPopCurrentTemplate
322     {
323     public:
324 
PushAndPopCurrentTemplate(StylesheetExecutionContext & executionContext,const ElemTemplate * theTemplate)325         PushAndPopCurrentTemplate(
326             StylesheetExecutionContext&     executionContext,
327             const ElemTemplate*             theTemplate) :
328             m_executionContext(executionContext)
329         {
330             executionContext.pushCurrentTemplate(theTemplate);
331         }
332 
~PushAndPopCurrentTemplate()333         ~PushAndPopCurrentTemplate()
334         {
335             m_executionContext.popCurrentTemplate();
336         }
337 
338     private:
339 
340         // Data members...
341         StylesheetExecutionContext&     m_executionContext;
342     };
343 #endif
344 
345     /**
346      * See if there is an element pending.
347      */
348     virtual bool
349     isElementPending() const = 0;
350 
351     /**
352      * Replace the contents of a pending attribute.
353      *
354      * @param theName           name of attribute
355      * @param theNewType        type of attribute
356      * @param theNewValue       new value of attribute
357      */
358     virtual void
359     replacePendingAttribute(
360             const XalanDOMChar*     theName,
361             const XalanDOMChar*     theNewType,
362             const XalanDOMChar*     theNewValue) = 0;
363 
364     /**
365      * Get the current formatter listener.
366      *
367      * @return pointer to formatter listener
368      */
369     virtual FormatterListener*
370     getFormatterListener() const = 0;
371 
372     /**
373      * Set the current formatter listener.
374      *
375      * @param flistener pointer to new formatter listener
376      */
377     virtual void
378     setFormatterListener(FormatterListener*     flistener) = 0;
379 
380     virtual void
381     pushOutputContext(FormatterListener*    flistener = 0) = 0;
382 
383     virtual void
384     popOutputContext() = 0;
385 
386     class OutputContextPushPop
387     {
388     public:
389 
390         /**
391          * Construct an object to push and pop the current output context.
392          *
393          * @param theExecutionContext a reference to the current execution context
394          * @param theNewListener the new FormatterListener to set.
395          */
OutputContextPushPop(StylesheetExecutionContext & theExecutionContext,FormatterListener * theNewListener=0)396         OutputContextPushPop(
397             StylesheetExecutionContext&     theExecutionContext,
398             FormatterListener*              theNewListener = 0) :
399             m_executionContext(theExecutionContext)
400         {
401             m_executionContext.pushOutputContext(theNewListener);
402         }
403 
~OutputContextPushPop()404         ~OutputContextPushPop()
405         {
406             m_executionContext.popOutputContext();
407         }
408 
409     private:
410 
411         StylesheetExecutionContext&     m_executionContext;
412     };
413 
414     /**
415      * Add a result attribute to the list of pending attributes.
416      *
417      * @param aname name of attribute
418      * @param value value of attribute
419      */
420     virtual void
421     addResultAttribute(
422             const XalanDOMString&   aname,
423             const XalanDOMString&   value) = 0;
424 
425     /**
426      * Add a result attribute to the list of pending attributes.
427      *
428      * @param aname name of attribute
429      * @param value value of attribute
430      */
431     virtual void
432     addResultAttribute(
433             const XalanDOMString&   aname,
434             const XalanDOMChar*     value) = 0;
435 
436     /**
437      * Add namespace attributes for a node to the list of pending attributes.
438      *
439      * @param src                 source node
440      */
441     virtual void
442     copyNamespaceAttributes(const XalanNode&    src) = 0;
443 
444     /**
445      * Retrieve the result prefix corresponding to a namespace.
446      *
447      * @param theNamespace namespace for prefix
448      *
449      * @return A pointer to a string containing the prefix, or 0 if the namespace is not mapped.
450      */
451     virtual const XalanDOMString*
452     getResultPrefixForNamespace(const XalanDOMString&   theNamespace) const = 0;
453 
454     /**
455      * Retrieve the result namespace corresponding to a prefix.
456      *
457      * @param thePrefix prefix for namespace
458      *
459      * @return A pointer to a string containing the namespace, or 0 if the prefix is not mapped.
460      */
461     virtual const XalanDOMString*
462     getResultNamespaceForPrefix(const XalanDOMString&   thePrefix) const = 0;
463 
464     /**
465      * Determine whether or not a prefix is in use on the pending element or
466      * the pending attributes.
467      *
468      * @param thePrefix prefix for namespace
469      *
470      * @return true if the prefix is in use, false if not.
471      */
472     virtual bool
473     isPendingResultPrefix(const XalanDOMString& thePrefix) = 0;
474 
475 
476     /**
477      * Generate a random namespace prefix guaranteed to be unique.
478      *
479      * @param theValue A string for returning the new prefix
480      */
481     virtual void
482     getUniqueNamespaceValue(XalanDOMString&     theValue) const = 0;
483 
484     /**
485      * Retrieve the current number of spaces to indent.
486      *
487      * @return number of spaces
488      */
489     virtual int
490     getIndent() const = 0;
491 
492     /**
493      * Set the current number of spaces to indent.
494      *
495      * @param indentAmount The number of spaces to indent.  Use -1 for the default amount.
496      */
497     virtual void
498     setIndent(int   indentAmount) = 0;
499 
500     /**
501      * Create and initialize an xpath and return it. This is to be used to
502      * create an XPath that is only used during execution.
503      *
504      * @param str      string expression for XPath evaluation
505      * @param resolver resolver for namespace resolution
506      * @return pointer to resulting XPath
507      */
508     virtual const XPath*
509     createMatchPattern(
510             const XalanDOMString&   str,
511             const PrefixResolver&   resolver) = 0;
512 
513     /**
514      * Return the XPath created by createMatchPattern().
515      *
516      * @param xpath The XPath to return.
517      */
518     virtual void
519     returnXPath(const XPath*    xpath) = 0;
520 
521     // A helper class to automatically return an XPath instance.
522     class XPathGuard
523     {
524     public:
525 
XPathGuard(StylesheetExecutionContext & context,const XPath * xpath=0)526         XPathGuard(
527                 StylesheetExecutionContext&     context,
528                 const XPath*                    xpath = 0) :
529             m_context(context),
530             m_xpath(xpath)
531         {
532         }
533 
~XPathGuard()534         ~XPathGuard()
535         {
536             if (m_xpath != 0)
537             {
538                 m_context.returnXPath(m_xpath);
539             }
540         }
541 
542         const XPath*
get() const543         get() const
544         {
545             return m_xpath;
546         }
547 
548         const XPath*
release()549         release()
550         {
551             const XPath* const  temp = m_xpath;
552 
553             m_xpath = 0;
554 
555             return temp;
556         }
557 
558         void
reset(const XPath * xpath)559         reset(const XPath*  xpath)
560         {
561             if (m_xpath != 0)
562             {
563                 m_context.returnXPath(m_xpath);
564             }
565 
566             m_xpath = xpath;
567         }
568 
569     private:
570 
571         StylesheetExecutionContext&     m_context;
572 
573         const XPath*                    m_xpath;
574     };
575 
576     typedef XalanVector<TopLevelArg>            ParamVectorType;
577 
578     /**
579      * Set a list of top level variables in the specified execution context
580      * stylesheet.
581      *
582      * @param topLevelParams   list of top level parameters
583      */
584     virtual void
585     pushTopLevelVariables(const ParamVectorType&    topLevelParams) = 0;
586 
587     /**
588      * Execute the supplied XPath and and create a
589      * variable in the current context.
590      *
591      * @param str         string expression for XPath evaluation
592      * @param contextNode current node in the source tree
593      * @param resolver    resolver for namespace resolution
594      * @return a pointer to the XObject result
595      */
596     virtual const XObjectPtr
597     createVariable(
598             const XPath&                xpath,
599             XalanNode*                  contextNode,
600             const PrefixResolver&       resolver) = 0;
601 
602 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
603     /**
604      * Create an ResultTreeFragment as a variable and push it
605      * on to the stack with the current context.
606      *
607      * @param templateChild result tree fragment to use.
608      * @param sourceNode source node
609      * @return a pointer to the XObject result
610      */
611     virtual const XObjectPtr
612     createVariable(
613             const ElemTemplateElement&  templateChild,
614             XalanNode*                  sourceNode) = 0;
615 #endif
616 
617     /**
618      * Execute an XPath using the provided expression,
619      * and push the result as a variable in the context of
620      * the supplied element.
621      *
622      * @param name        name of variable
623      * @param element     element marker for variable
624      * @param str         string expression for XPath evaluation
625      * @param contextNode current node in the source tree
626      * @param resolver    resolver for namespace resolution
627      * @return nothing
628      */
629     virtual void
630     pushVariable(
631             const XalanQName&           name,
632             const ElemTemplateElement*  element,
633             const XalanDOMString&       str,
634             XalanNode*                  contextNode,
635             const PrefixResolver&       resolver) = 0;
636 
637     /**
638      * Execute the supplied XPath and push the result as a
639      * variable in the current context.
640      *
641      * @param name        name of variable
642      * @param element     element marker for variable
643      * @param str         string expression for XPath evaluation
644      * @param contextNode current node in the source tree
645      * @param resolver    resolver for namespace resolution
646      * @return nothing
647      */
648     virtual void
649     pushVariable(
650             const XalanQName&           name,
651             const ElemTemplateElement*  element,
652             const XPath&                xpath,
653             XalanNode*                  contextNode,
654             const PrefixResolver&       resolver) = 0;
655 
656 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
657     /**
658      * Create an ResultTreeFragment as a variable and push it
659      * on to the stack with the current context.
660      *
661      * @param name    name of variable
662      * @param element element marker for variable
663      * @param templateChild result tree fragment to use.
664      * @param sourceNode source node
665      */
666     virtual void
667     pushVariable(
668             const XalanQName&           name,
669             const ElemTemplateElement*  element,
670             const ElemTemplateElement&  templateChild,
671             XalanNode*                  sourceNode) = 0;
672 #endif
673 
674     /**
675      * Push a named variable onto the variables stack.
676      * The variable has already been evaluated.
677      *
678      * @param name    name of variable
679      * @param val     pointer to XObject value
680      * @param element element marker for variable
681      */
682     virtual void
683     pushVariable(
684             const XalanQName&           name,
685             const XObjectPtr            val,
686             const ElemTemplateElement*  element) = 0;
687 
688     /**
689      * Push a named variable onto the processor variable stack
690      * The variable will be evaluated when first referenced.
691      *
692      * @param name    name of variable
693      * @param var     pointer to ElemVariable instance
694      * @param element element marker for variable
695      */
696     virtual void
697     pushVariable(
698             const XalanQName&           name,
699             const ElemVariable*         var,
700             const ElemTemplateElement*  element) = 0;
701 
702     /**
703      * Push a context marker onto the stack to let us know when to stop
704      * searching for a var.
705      */
706     virtual void
707     pushContextMarker() = 0;
708 
709     /**
710      * Pop the current context from the current context stack.
711      */
712     virtual void
713     popContextMarker() = 0;
714 
715 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
716     /*
717      * A class to manage pushing and popping an element's stack
718      * frame context.
719      */
720     class PushAndPopContextMarker
721     {
722     public:
723 
PushAndPopContextMarker(StylesheetExecutionContext & executionContext)724         PushAndPopContextMarker(StylesheetExecutionContext&     executionContext) :
725             m_executionContext(executionContext)
726         {
727             executionContext.pushContextMarker();
728         }
729 
PushAndPopContextMarker(StylesheetExecutionContext & executionContext,int & currentStackFrameIndex)730         PushAndPopContextMarker(
731                 StylesheetExecutionContext&     executionContext,
732                 int&                            currentStackFrameIndex) :
733             m_executionContext(executionContext)
734         {
735             currentStackFrameIndex = executionContext.getCurrentStackFrameIndex();
736 
737             executionContext.pushContextMarker();
738         }
739 
~PushAndPopContextMarker()740         ~PushAndPopContextMarker()
741         {
742             m_executionContext.popContextMarker();
743         }
744 
745         StylesheetExecutionContext&
getExecutionContext() const746         getExecutionContext() const
747         {
748             return m_executionContext;
749         }
750 
751     private:
752 
753         StylesheetExecutionContext&     m_executionContext;
754     };
755 #endif
756 
757     /**
758      * Resolve the params that were pushed by the caller.
759      */
760     virtual void
761     resolveTopLevelParams() = 0;
762 
763     /**
764      * Reset the vector of top level parameters.
765      */
766     virtual void
767     clearTopLevelParams() = 0;
768 
769 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
770     class ResolveAndClearTopLevelParams
771     {
772     public:
773 
ResolveAndClearTopLevelParams(StylesheetExecutionContext & executionContext)774         ResolveAndClearTopLevelParams(StylesheetExecutionContext&   executionContext) :
775             m_executionContext(executionContext)
776         {
777             m_executionContext.resolveTopLevelParams();
778         }
779 
~ResolveAndClearTopLevelParams()780         ~ResolveAndClearTopLevelParams()
781         {
782             m_executionContext.clearTopLevelParams();
783         }
784 
785     private:
786 
787         StylesheetExecutionContext&     m_executionContext;
788     };
789 
790     /**
791      * Given a template, search for the arguments and push them on the stack.
792      * Also, push default arguments on the stack.
793      *
794      * @param xslCallTemplateElement "call-template" element
795      */
796     virtual void
797     pushParams(const ElemTemplateElement&   xslCallTemplateElement) = 0;
798 
799 #else
800 
801     /**
802      *  Initiate context to accept a new set of parameters
803      */
804     virtual void beginParams() = 0;
805 
806     /**
807      *  Indicate parameter set is complete
808      */
809     virtual void endParams() = 0;
810 
811     /**
812      * Push a single paramter onto the latest initialized paramter set
813      * @param qName     the name of the parameter
814      * @param theValue  the value of the parameter
815      */
816     virtual void pushParam(const XalanQName& qName,const XObjectPtr& theValue) = 0;
817 #endif
818 
819     /**
820      * Given a name, return a string representing the value, but don't look in
821      * the global space.
822      *
823      * @param theName name of variable
824      * @return An XObjectPtr instance.  Call XObjectPtr::null() on the instance
825      *         to determine if the variable was found.  If XObjectPtr::null()
826      *         returns true, the variable was not found, and no other operations
827      *         on the XObject instance are permitted.
828      */
829     virtual const XObjectPtr
830     getParamVariable(const XalanQName&  theName) = 0;
831 
832     /**
833      * Push a frame marker for an element.
834      *
835      * @param elem the element
836      */
837     virtual void
838     pushElementFrame(const ElemTemplateElement*     elem) = 0;
839 
840     /**
841      * Pop a frame marker for an element.
842      *
843      * @param elem the element
844      */
845     virtual void
846     popElementFrame() = 0;
847 
848 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
849     /*
850      * A class to manage pushing and popping an element's stack
851      * frame context.
852      */
853     class PushAndPopElementFrame
854     {
855     public:
856 
PushAndPopElementFrame(StylesheetExecutionContext & executionContext,const ElemTemplateElement * element)857         PushAndPopElementFrame(
858             StylesheetExecutionContext&     executionContext,
859             const ElemTemplateElement*      element) :
860             m_executionContext(executionContext)
861         {
862             executionContext.pushElementFrame(element);
863         }
864 
~PushAndPopElementFrame()865         ~PushAndPopElementFrame()
866         {
867             m_executionContext.popElementFrame();
868         }
869 
870     private:
871 
872         StylesheetExecutionContext&     m_executionContext;
873     };
874 #endif
875 
876     /**
877      * Get the top of the global stack frame.
878      *
879      * @return current value of index
880      */
881     virtual int
882     getGlobalStackFrameIndex() const = 0;
883 
884     /**
885      * Get the top of the stack frame from where a search
886      * for a variable or param should take place.
887      *
888      * @return current value of index
889      */
890     virtual int
891     getCurrentStackFrameIndex() const = 0;
892 
893     /**
894      * Set the top of the stack frame from where a search
895      * for a variable or param should take place.
896      *
897      * @param currentStackFrameIndex new value of index
898      */
899     virtual void
900     pushCurrentStackFrameIndex(int currentStackFrameIndex = -1) =  0;
901 
902     /**
903      * Pop the last stack frame index setting
904      */
905     virtual void
906     popCurrentStackFrameIndex() = 0;
907 
908     /*
909      * A class to manage the state of the variable stacks frame index.
910      */
911     class SetAndRestoreCurrentStackFrameIndex
912     {
913     public:
914 
SetAndRestoreCurrentStackFrameIndex(StylesheetExecutionContext & executionContext,int newIndex)915         SetAndRestoreCurrentStackFrameIndex(
916             StylesheetExecutionContext&     executionContext,
917             int                             newIndex) :
918             m_executionContext(executionContext),
919             m_savedIndex(executionContext.getCurrentStackFrameIndex())
920         {
921             executionContext.pushCurrentStackFrameIndex(newIndex);
922         }
923 
~SetAndRestoreCurrentStackFrameIndex()924         ~SetAndRestoreCurrentStackFrameIndex()
925         {
926             m_executionContext.popCurrentStackFrameIndex();
927         }
928 
929     private:
930 
931         StylesheetExecutionContext&     m_executionContext;
932 
933         const int                       m_savedIndex;
934     };
935 
936 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
937     /*
938      * A class to manage stack state during execution.
939      */
940     class ParamsPushPop : public PushAndPopContextMarker
941     {
942     public:
943 
ParamsPushPop(StylesheetExecutionContext & executionContext,const ElemTemplateElement & xslCallTemplateElement)944         ParamsPushPop(
945                 StylesheetExecutionContext&     executionContext,
946                 const ElemTemplateElement&      xslCallTemplateElement) :
947             PushAndPopContextMarker(executionContext)
948         {
949             doPush(xslCallTemplateElement);
950         }
951 
ParamsPushPop(StylesheetExecutionContext & executionContext,const ElemTemplateElement & xslCallTemplateElement,int & savedStackFrameIndex)952         ParamsPushPop(
953                 StylesheetExecutionContext&     executionContext,
954                 const ElemTemplateElement&      xslCallTemplateElement,
955                 int&                            savedStackFrameIndex) :
956             PushAndPopContextMarker(executionContext, savedStackFrameIndex)
957         {
958             doPush(
959                 xslCallTemplateElement,
960                 savedStackFrameIndex);
961         }
962 
~ParamsPushPop()963         ~ParamsPushPop()
964         {
965         }
966 
967     private:
968 
969         void
970         doPush(
971             const ElemTemplateElement&      xslCallTemplateElement,
972             int                             stackFrameIndex);
973 
974         void
975         doPush(const ElemTemplateElement&   xslCallTemplateElement);
976     };
977 #endif
978 
979     /**
980      * Receive notification of the beginning of a document.
981      *
982      * <p>The SAX parser will invoke this method only once, before any
983      * other methods in this interface or in DTDHandler (except for
984      * setDocumentLocator).</p>
985      *
986      * @exception SAXException
987      */
988     virtual void
989     startDocument() = 0;
990 
991     /**
992      * Receive notification of the end of a document.
993      *
994      * <p>The SAX parser will invoke this method only once, and it will
995      * be the last method invoked during the parse.  The parser shall
996      * not invoke this method until it has either abandoned parsing
997      * (because of an unrecoverable error) or reached the end of
998      * input.</p>
999      *
1000      * @exception SAXException
1001      */
1002     virtual void
1003     endDocument() = 0;
1004 
1005     /**
1006      * Receive notification of the beginning of an element.
1007      *
1008      * @param name element type name
1009      */
1010     virtual void
1011     startElement(const XalanDOMChar*    name) = 0;
1012 
1013     /**
1014      * Receive notification of the end of an element.
1015      *
1016      * @param name element type name
1017      */
1018     virtual void
1019     endElement(const XalanDOMChar*  name) = 0;
1020 
1021     /**
1022      * Receive notification of character data.
1023      *
1024      * @param ch     pointer to characters from the XML document
1025      * @param start  start position in the array
1026      * @param length number of characters to read from the array
1027      */
1028     virtual void
1029     characters(
1030             const XalanDOMChar*     ch,
1031             fl_size_type            start,
1032             fl_size_type            length) = 0;
1033 
1034     /**
1035      * Receive notification of character data. If available, when the
1036      * disable-output-escaping attribute is used, output raw text without
1037      * escaping.
1038      *
1039      * @param ch     pointer to characters from the XML document
1040      * @param start  start position in the array
1041      * @param length number of characters to read from the array
1042      */
1043     virtual void
1044     charactersRaw(
1045             const XalanDOMChar*     ch,
1046             fl_size_type            start,
1047             fl_size_type            length) = 0;
1048 
1049     /**
1050      * Called when a Comment is to be constructed.
1051      *
1052      * @param   data    pointer to comment data
1053      */
1054     virtual void
1055     comment(const XalanDOMChar*     data) = 0;
1056 
1057     /**
1058      * Receive notification of a processing instruction.
1059      *
1060      * @param target processing instruction target
1061      * @param data   processing instruction data, or null if none was supplied
1062      */
1063     virtual void
1064     processingInstruction(
1065             const XalanDOMChar*     target,
1066             const XalanDOMChar*     data) = 0;
1067 
1068     /**
1069      * Flush the pending element.
1070      */
1071     virtual void
1072     flushPending() = 0;
1073 
1074     /**
1075      * Clone a node to the result tree
1076      *
1077      * @param node node to clone
1078      * @param locator The Locator, if any
1079      */
1080     virtual void
1081     cloneToResultTree(
1082             const XalanNode&    node,
1083             const Locator*      locator) = 0;
1084 
1085     /**
1086      * Clone a node to the result tree
1087      *
1088      * @param node                  node to clone
1089      * @param nodeType              the type of the node
1090      * @param overrideStrip         false if white space stripping should be done
1091      * @param shouldCloneAttributes true if attributes should be cloned
1092      * @param locator               The Locator, if any
1093      */
1094     virtual void
1095     cloneToResultTree(
1096             const XalanNode&        node,
1097             XalanNode::NodeType     nodeType,
1098             bool                    overrideStrip,
1099             bool                    shouldCloneAttributes,
1100             const Locator*          locator) = 0;
1101 
1102 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
1103     /**
1104      * Initiate creation of a result tree fragment
1105      * @param sourceNode the source Node
1106      */
1107     virtual void
1108     beginCreateXResultTreeFrag(
1109             XalanNode*                  sourceNode) = 0;
1110 
1111     /**
1112      * Indicate sthe completion of result tree fragment
1113      * @return a pointer to the result tree fragment
1114      */
1115     virtual const XObjectPtr
1116     endCreateXResultTreeFrag() = 0;
1117 
1118     /**
1119      * Initiate to put execution result in string
1120      *
1121      * @param theResult the string to contain the result
1122      */
1123     virtual void
1124     beginFormatToText(
1125             XalanDOMString&             theResult) = 0;
1126 
1127     /**
1128      * Indicates the completion of the result string
1129      *
1130      */
1131     virtual void
1132     endFormatToText() = 0;
1133 #else
1134     /**
1135      * Create an XObject that represents a Result tree fragment.
1136      *
1137      * @param templateChild result tree fragment to use.
1138      * @param sourceNode source node
1139      * @return XObject instance
1140      */
1141     virtual const XObjectPtr
1142     createXResultTreeFrag(
1143             const ElemTemplateElement&  templateChild,
1144             XalanNode*                  sourceNode) = 0;
1145 #endif
1146 
1147     /**
1148      * Output an object to the result tree by doing the right conversions.
1149      * This is public for access by extensions.
1150      *
1151      * @param obj the XObject to output
1152      * @param locator The Locator, if any
1153      */
1154     virtual void
1155     outputToResultTree(
1156             const XObject&      xobj,
1157             const Locator*      locator) = 0;
1158 
1159     /**
1160      * Given a result tree fragment, walk the tree and
1161      * output it to the result stream.
1162      *
1163      * @param theTree result tree fragment
1164      * @param locator The Locator, if any
1165      */
1166     virtual void
1167     outputResultTreeFragment(
1168             const XObject&      theTree,
1169             const Locator*      locator) = 0;
1170 
1171     /**
1172      * Determine the full XSLT Namespace URI.
1173      *
1174      * @return Xalan namespace URI
1175      */
1176     virtual const XalanDOMString&
1177     getXSLNameSpaceURL() const = 0;
1178 
1179     /**
1180      * Special Xalan namespace for built-in extensions.
1181      *
1182      * @return Xalan namespace for extensions
1183      */
1184     virtual const XalanDOMString&
1185     getXalanXSLNameSpaceURL() const = 0;
1186 
1187     /**
1188      * Determine if an element is on the recursion stack.
1189      *
1190      * @return true if element on stack
1191      */
1192     virtual bool
1193     findOnElementRecursionStack(const ElemTemplateElement*  theElement) const = 0;
1194 
1195     /**
1196      * Push an element onto the recursion stack.
1197      *
1198      * @param theElement pointer to element to push
1199      */
1200     virtual void
1201     pushOnElementRecursionStack(const ElemTemplateElement*  theElement) = 0;
1202 
1203     /**
1204      * Pop an element off the recursion stack.
1205      *
1206      * @return pointer to element popped
1207      */
1208     virtual const ElemTemplateElement*
1209     popElementRecursionStack() = 0;
1210 
1211     /**
1212      * Class for keeping track of elements pushed on the element recursion stack
1213      */
1214     class ElementRecursionStackPusher
1215     {
1216     public:
1217 
1218     /**
1219      * Construct an instance of the recursion stack pusher.
1220      *
1221      * @param executionContext current execution context
1222      * @param element pointer to element to push
1223      */
ElementRecursionStackPusher(StylesheetExecutionContext & executionContext,const ElemTemplateElement * element)1224         ElementRecursionStackPusher(
1225                     StylesheetExecutionContext&     executionContext,
1226                     const ElemTemplateElement*      element) :
1227             m_executionContext(executionContext)
1228         {
1229             m_executionContext.pushOnElementRecursionStack(element);
1230         }
1231 
~ElementRecursionStackPusher()1232         ~ElementRecursionStackPusher()
1233         {
1234             m_executionContext.popElementRecursionStack();
1235         }
1236 
1237     private:
1238 
1239         StylesheetExecutionContext&         m_executionContext;
1240     };
1241 
1242 
1243     /**
1244      * This is a hook that XResultTreeFrag instances (which are reference
1245      * counted), can notify the owning StylesheetExecutionContext instance
1246      * when they are dereferenced and can be cleaned up.
1247      *
1248      * @param theXResultTreeFrag The instance that is being returned.
1249      *
1250      * @return true if the XResultTreeFrag instance belongs to the execution context. false if not.
1251      */
1252     virtual bool
1253     returnXResultTreeFrag(XResultTreeFrag*  theXResultTreeFrag) = 0;
1254 
1255 
1256     enum eDummy
1257     {
1258         eDefaultXMLIndentAmount = 0,
1259         eDefaultHTMLIndentAmount = 0
1260     };
1261 
1262     /**
1263      * Enums to determine whether or not run-time escaping of URLs has been set.
1264      */
1265     enum eEscapeURLs
1266     {
1267         eEscapeURLsDefault,     // Use the value in the stylesheet
1268         eEscapeURLsNo,          // Don't escape URLs
1269         eEscapeURLsYes          // Escape URLs
1270     };
1271 
1272     /**
1273      * Get the value for run-time escaping of URLs.  This can
1274      * override the property specified by the stylesheet.  The
1275      * default behavior is to honor the property in the stylesheet.
1276      *
1277      * @return The value of the enum
1278      */
1279     virtual eEscapeURLs
1280     getEscapeURLs() const = 0;
1281 
1282     /**
1283      * Set the value for run-time escaping of URLs.  This can
1284      * override the property specified by the stylesheet.  The
1285      * default behavior is to honor the property in the stylesheet.
1286      *
1287      * @param value The value of the enum
1288      */
1289     virtual void
1290     setEscapeURLs(eEscapeURLs   value) = 0;
1291 
1292 
1293     /**
1294      * Enums to determine whether or not run-time omission of the META tag has been set.
1295      */
1296     enum eOmitMETATag
1297     {
1298         eOmitMETATagDefault,    // Use the value in the stylesheet
1299         eOmitMETATagNo,         // Don't omit the META tag
1300         eOmitMETATagYes         // Omit the META tag
1301     };
1302 
1303     /**
1304      * Get the value for run-time omission of URLs.  This can
1305      * override the property specified by the stylesheet.  The
1306      * default behavior is to honor the property in the stylesheet.
1307      *
1308      * @return The value of the enum
1309      */
1310     virtual eOmitMETATag
1311     getOmitMETATag() const = 0;
1312 
1313     /**
1314      * Get the value for run-time omission of URLs.  This can
1315      * override the property specified by the stylesheet.  The
1316      * default behavior is to honor the property in the stylesheet.
1317      *
1318      * @param value The value of the enum
1319      */
1320     virtual void
1321     setOmitMETATag(eOmitMETATag     value) = 0;
1322 
1323     /**
1324      * Create a new FormatterToXML instance.  The execution context
1325      * owns the instance and will delete it when reset.
1326      *
1327      * @param writer            character output stream to use
1328      * @param version           version of the output method
1329      * @param doIndent          true if output is to be indented
1330      * @param indent            number of spaces to indent at each nesting level
1331      * @param encoding          character encoding for the writer
1332      * @param mediaType         media type (MIME content type) of the data
1333      * @param doctypeSystem     system identifier to be used in the document
1334      *                          type declaration
1335      * @param doctypePublic     public identifier to be used in the document
1336      *                          type declaration
1337      * @param xmlDecl           true if the XSLT processor should output an XML
1338      *                          declaration
1339      * @param standalone        true if the XSLT processor should output a
1340      *                          standalone document declaration
1341      * @return a pointer to the new instance.
1342      */
1343 
1344     virtual FormatterListener*
1345     createFormatterToXML(
1346             Writer&                 writer,
1347             const XalanDOMString&   version = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
1348             bool                    doIndent = false,
1349             int                     indent = eDefaultXMLIndentAmount,
1350             const XalanDOMString&   encoding = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
1351             const XalanDOMString&   mediaType = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
1352             const XalanDOMString&   doctypeSystem = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
1353             const XalanDOMString&   doctypePublic = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
1354             bool                    xmlDecl = true,
1355             const XalanDOMString&   standalone = XalanDOMString(XalanMemMgrs::getDummyMemMgr())) = 0;
1356 
1357     /**
1358      * Create a new FormatterToHTML instance.  The execution context
1359      * owns the instance and will delete it when reset.
1360      *
1361      * @param writer            character output stream to use
1362      * @param encoding          character encoding for the writer
1363      * @param mediaType         media type (MIME content type) of the data
1364      * @param doctypeSystem     system identifier to be used in the document
1365      *                          type declaration
1366      * @param doctypePublic     public identifier to be used in the document
1367      *                          type declaration
1368      * @param doIndent          true if output is to be indented
1369      * @param indent            number of spaces to indent at each nesting level
1370      * @param escapeURLs        Whether or not to escape URLs according to the recommendation.  The default is true.
1371      * @param omitMetaTag       Whether or not to output a META TAG according to the recommendation.  The default is false.
1372      * @return a pointer to the new instance.
1373      */
1374     virtual FormatterListener*
1375     createFormatterToHTML(
1376             Writer&                 writer,
1377             const XalanDOMString&   encoding = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
1378             const XalanDOMString&   mediaType = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
1379             const XalanDOMString&   doctypeSystem = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
1380             const XalanDOMString&   doctypePublic = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
1381             bool                    doIndent = true,
1382             int                     indent = eDefaultHTMLIndentAmount,
1383             bool                    escapeURLs = true,
1384             bool                    omitMetaTag = false) = 0;
1385 
1386     /**
1387      * FormatterToText instance constructor.
1388      *
1389      * @param writer writer for output
1390      * @param encoding character encoding for the writer
1391      */
1392     virtual FormatterListener*
1393     createFormatterToText(
1394             Writer&                 writer,
1395             const XalanDOMString&   encoding) = 0;
1396 
1397 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
1398     class BorrowReturnFormatterToText
1399     {
1400     public:
1401 
1402         BorrowReturnFormatterToText(
1403                 StylesheetExecutionContext&     executionContext,
1404                 Writer&                         writer,
1405                 bool                            normalizeLinefeed = true,
1406                 bool                            handleIgnorableWhitespace = true);
1407 
~BorrowReturnFormatterToText()1408         ~BorrowReturnFormatterToText()
1409         {
1410             assert(m_formatter != 0);
1411 
1412             m_executionContext.returnFormatterToText(m_formatter);
1413         }
1414 
1415         FormatterToText&
operator *() const1416         operator*() const
1417         {
1418             assert(m_formatter != 0);
1419 
1420             return *m_formatter;
1421         }
1422 
1423         FormatterToText*
get() const1424         get() const
1425         {
1426             assert(m_formatter != 0);
1427 
1428             return m_formatter;
1429         }
1430 
1431         FormatterToText*
operator ->() const1432         operator->() const
1433         {
1434             return get();
1435         }
1436 
1437     private:
1438 
1439         StylesheetExecutionContext&     m_executionContext;
1440 
1441         FormatterToText*                m_formatter;
1442     };
1443 
1444 
1445     friend class BorrowReturnFormatterToText;
1446 #endif
1447 
1448 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
1449     /**
1450      * Get node sorter instance
1451      */
1452     virtual NodeSorter*
1453     getNodeSorter() = 0;
1454 
1455 #else
1456     /**
1457      * Borrow a cached NodeSorter instance.
1458      *
1459      * @return A pointer to the instance.
1460      */
1461     virtual NodeSorter*
1462     borrowNodeSorter() = 0;
1463 
1464     /**
1465      * Return a previously borrowed NodeSorter instance.
1466      *
1467      * @param theSorter A pointer the to previously borrowed instance.
1468      * @return true if the instance was previously borrowed, false if not.
1469      */
1470     virtual bool
1471     returnNodeSorter(NodeSorter*    theSorter) = 0;
1472 
1473     class BorrowReturnNodeSorter
1474     {
1475     public:
1476 
BorrowReturnNodeSorter(StylesheetExecutionContext & executionContext)1477         BorrowReturnNodeSorter(StylesheetExecutionContext&  executionContext) :
1478             m_executionContext(executionContext),
1479             m_sorter(executionContext.borrowNodeSorter())
1480         {
1481             assert(m_sorter != 0);
1482         }
1483 
~BorrowReturnNodeSorter()1484         ~BorrowReturnNodeSorter()
1485         {
1486             assert(m_sorter != 0);
1487 
1488             m_executionContext.returnNodeSorter(m_sorter);
1489         }
1490 
1491         NodeSorter&
operator *() const1492         operator*() const
1493         {
1494             assert(m_sorter != 0);
1495 
1496             return *m_sorter;
1497         }
1498 
1499         NodeSorter*
get() const1500         get() const
1501         {
1502             assert(m_sorter != 0);
1503 
1504             return m_sorter;
1505         }
1506 
1507         NodeSorter*
operator ->() const1508         operator->() const
1509         {
1510             return get();
1511         }
1512 
1513     private:
1514 
1515         StylesheetExecutionContext&     m_executionContext;
1516 
1517         NodeSorter*                     m_sorter;
1518     };
1519 #endif
1520 
1521     typedef XalanMemMgrAutoPtr<XalanNumberFormat>   XalanNumberFormatAutoPtr;
1522 
1523     /**
1524      * Create a new XalanNumberFormat instance.
1525      *
1526      * @return an XalanNumberFormatAutoPtr that owns a new
1527      * XalanNumberFormat instance.
1528      */
1529     virtual XalanNumberFormatAutoPtr
1530     createXalanNumberFormat() = 0;
1531 
1532 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
1533     /*
1534      * A class to manage the attribute sets that have been executed
1535      * by an element
1536      */
1537     struct UseAttributeSetIndexes
1538     {
UseAttributeSetIndexesXALAN_CPP_NAMESPACE::StylesheetExecutionContext::UseAttributeSetIndexes1539         UseAttributeSetIndexes() :
1540             attributeSetNameIndex(0),
1541             matchingAttributeSetIndex(0) {}
1542 
1543         size_type attributeSetNameIndex;
1544         size_type matchingAttributeSetIndex;
1545 
1546 
1547     };
1548 
1549     virtual void
1550     createUseAttributeSetIndexesOnStack() = 0;
1551 
1552     virtual UseAttributeSetIndexes&
1553     getUseAttributeSetIndexes() = 0;
1554 
1555     virtual void
1556     popUseAttributeSetIndexesFromStack() = 0;
1557 
1558     /**
1559      * Push the element that will invoke
1560      * non children elements (i.e templates, attribute-sets)
1561      *
1562      * @param invokers the element that will invoke non children elements
1563      */
1564     virtual void
1565     pushInvoker(const ElemTemplateElement * invoker) = 0;
1566 
1567     /**
1568      * Pop the element that invoked non children elements
1569      */
1570     virtual void
1571     popInvoker() = 0;
1572 
1573     /**
1574      * Get the lastest element that has invoked
1575      * a non-child element
1576      */
1577     virtual const ElemTemplateElement*
1578     getInvoker() const = 0;
1579 #endif
1580 
1581     /**
1582      * Determine the number of trace listeners.
1583      *
1584      * @return number of listeners
1585      */
1586     virtual tl_size_type
1587     getTraceListeners() const = 0;
1588 
1589     /**
1590      * Fire a generate event.
1591      *
1592      * @param ge generate event to fire
1593      */
1594     virtual void
1595     fireGenerateEvent(const GenerateEvent&  ge) = 0;
1596 
1597     /**
1598      * Fire a trace event.
1599      *
1600      * @param te trace event to fire
1601      */
1602     virtual void
1603     fireTraceEvent(const TracerEvent&   te) = 0;
1604 
1605     /**
1606      * Fire a selection event.
1607      *
1608      * @param se selection event to fire
1609      */
1610     virtual void
1611     fireSelectEvent(const SelectionEvent&   se) = 0;
1612 
1613     /**
1614      * If this is set to true, simple traces of template calls are made.
1615      *
1616      * @return true if traces made
1617      */
1618     virtual bool
1619     getTraceSelects() const = 0;
1620 
1621     /**
1622      * Compose a diagnostic trace of the current selection
1623      *
1624      * @param theStylesheetElement The executing stylesheet element
1625      * @param nl The list of selected nodes
1626      * @param xpath A pointer to the XPath which generated the list of nodes, if any.
1627      */
1628     virtual void
1629     traceSelect(
1630             const ElemTemplateElement&  theStylesheetElement,
1631             const NodeRefListBase&      nl,
1632             const XPath*                xpath) = 0;
1633 
1634     /**
1635      * Compare two strings using the collation of the
1636      * current locale.
1637      *
1638      * @param theLHS a string to compare
1639      * @param theRHS a string to compare
1640      * @param theCaseOrder the case order for the comparison
1641      * @return < 0 if theLHS is before theRHS, 0 if they are equal, or > 0 if theLHS is after theRHS
1642      */
1643     virtual int
1644     collationCompare(
1645             const XalanDOMString&               theLHS,
1646             const XalanDOMString&               theRHS,
1647             XalanCollationServices::eCaseOrder  theCaseOrder = XalanCollationServices::eDefault) = 0;
1648 
1649     /**
1650      * Compare two strings using the collation of the
1651      * supplied locale.
1652      *
1653      * @param theLHS a string to compare
1654      * @param theRHS a string to compare
1655      * @param theLocal a string that specifies the locale
1656      * @param theCaseOrder the case order for the comparison
1657      * @return < 0 if theLHS is before theRHS, 0 if they are equal, or > 0 if theLHS is after theRHS
1658      */
1659     virtual int
1660     collationCompare(
1661             const XalanDOMString&               theLHS,
1662             const XalanDOMString&               theRHS,
1663             const XalanDOMString&               theLocale,
1664             XalanCollationServices::eCaseOrder  theCaseOrder = XalanCollationServices::eDefault) = 0;
1665 
1666     /**
1667      * Compare two strings using the collation of the
1668      * current locale.
1669      *
1670      * @param theLHS a string to compare
1671      * @param theRHS a string to compare
1672      * @param theCaseOrder the case order for the comparison
1673      * @return < 0 if theLHS is before theRHS, 0 if they are equal, or > 0 if theLHS is after theRHS
1674      */
1675     virtual int
1676     collationCompare(
1677             const XalanDOMChar*                 theLHS,
1678             const XalanDOMChar*                 theRHS,
1679             XalanCollationServices::eCaseOrder  theCaseOrder = XalanCollationServices::eDefault) = 0;
1680 
1681     /**
1682      * Compare two strings using the collation of the
1683      * current locale.
1684      *
1685      * @param theLHS a string to compare
1686      * @param theRHS a string to compare
1687      * @param theLocal a string that specifies the locale
1688      * @param theCaseOrder the case order for the comparison
1689      * @return < 0 if theLHS is before theRHS, 0 if they are equal, or > 0 if theLHS is after theRHS
1690      */
1691     virtual int
1692     collationCompare(
1693             const XalanDOMChar*                 theLHS,
1694             const XalanDOMChar*                 theRHS,
1695             const XalanDOMChar*                 theLocale,
1696             XalanCollationServices::eCaseOrder  theCaseOrder = XalanCollationServices::eDefault) = 0;
1697 
1698     /**
1699      * Create a PrintWriter for the provided stream.
1700      *
1701      * @param theTextOutputStream The output stream for the PrintWriter.
1702      * @return The new instance.
1703      */
1704     virtual PrintWriter*
1705     createPrintWriter(XalanOutputStream*        theTextOutputStream) = 0;
1706 
1707     /**
1708      * Create a PrintWriter.  Create an appropriate output stream
1709      * using the provided file name and encoding.
1710      *
1711      * @param theFileName The file name for the output stream
1712      * @param theEncoding The encoding for the output stream
1713      * @return The new instance.
1714      */
1715     virtual PrintWriter*
1716     createPrintWriter(
1717             const XalanDOMString&       theFileName,
1718             const XalanDOMString&       theEncoding) = 0;
1719 
1720     /**
1721      * Create a PrintWriter using the provided ostream instance.
1722      *
1723      * @param theStream The output stream for the PrintWriter.
1724      * @return The new instance.
1725      */
1726     virtual PrintWriter*
1727     createPrintWriter(StreamType&   theStream) = 0;
1728 
1729     /**
1730      * Create a PrintWriter using the provided FILE instance.
1731      *
1732      * @param theStream The output stream for the PrintWriter.
1733      * @return The new instance.
1734      */
1735     virtual PrintWriter*
1736     createPrintWriter(FILE*     theStream) = 0;
1737 
1738     /**
1739      * Get the counters table, which is a table of cached
1740      * results that is used by ElemNumber.
1741      *
1742      * @return A reference to the counters table.
1743      */
1744     virtual CountersTable&
1745     getCountersTable() = 0;
1746 
1747     /**
1748      * Send character data from a node to the result tree.
1749      *
1750      * @param node The node to send.
1751      */
1752     virtual void
1753     characters(const XalanNode&     node) = 0;
1754 
1755     /**
1756      * Send character data from an XObject to the result tree.
1757      *
1758      * @param node The xobject to send.
1759      */
1760     virtual void
1761     characters(const XObjectPtr&    xobject) = 0;
1762 
1763     /**
1764      * Send raw character data from a node to the result tree.
1765      *
1766      * @param node The node to send.
1767      * @param length number of characters to read from the array
1768      */
1769     virtual void
1770     charactersRaw(const XalanNode&  node) = 0;
1771 
1772     /**
1773      * Send raw character data from an XObject to the result tree.
1774      *
1775      * @param node The xobject to send.
1776      */
1777     virtual void
1778     charactersRaw(const XObjectPtr&     xobject) = 0;
1779 
1780 
1781     // These interfaces are inherited from XPathExecutionContext...
1782 
1783     virtual void
1784     reset() = 0;
1785 
1786     virtual XalanNode*
1787     getCurrentNode() const = 0;
1788 
1789     virtual void
1790     pushCurrentNode(XalanNode*  theCurrentNode) = 0;
1791 
1792     virtual void
1793     popCurrentNode() = 0;
1794 
1795     virtual bool
1796     isNodeAfter(
1797             const XalanNode&    node1,
1798             const XalanNode&    node2) const = 0;
1799 
1800     virtual void
1801     pushContextNodeList(const NodeRefListBase&  theList) = 0;
1802 
1803     virtual void
1804     popContextNodeList() = 0;
1805 
1806     virtual const NodeRefListBase&
1807     getContextNodeList() const = 0;
1808 
1809     virtual size_type
1810     getContextNodeListLength() const = 0;
1811 
1812     virtual size_type
1813     getContextNodeListPosition(const XalanNode&     contextNode) const = 0;
1814 
1815     /**
1816      * Determine if an external element is available.
1817      *
1818      * @param theQName The QName of the element
1819      *
1820      * @return whether the given element is available or not
1821      */
1822     virtual bool
1823     elementAvailable(const XalanQName&  theQName) const = 0;
1824 
1825     /**
1826      * Determine if an external element is available by resolving
1827      * a string to a QName.
1828      *
1829      * @param theName The name of the element
1830      * @param locator A Locator instance for error reporting
1831      *
1832      * @return whether the given element is available or not
1833      */
1834     virtual bool
1835     elementAvailable(
1836             const XalanDOMString&   theName,
1837             const Locator*          locator) const = 0;
1838 
1839     /**
1840      * Determine if a function is available.
1841      *
1842      * @param theQName The QName of the function
1843      *
1844      * @return whether the function is available or not
1845      */
1846     virtual bool
1847     functionAvailable(const XalanQName&     theQName) const = 0;
1848 
1849     /**
1850      * Determine if a function is available.
1851      *
1852      * @param theName The name of the function
1853      * @param locator A Locator instance for error reporting
1854      *
1855      * @return whether the function is available or not
1856      */
1857     virtual bool
1858     functionAvailable(
1859             const XalanDOMString&   theName,
1860             const Locator*          locator) const = 0;
1861 
1862     virtual const XObjectPtr
1863     extFunction(
1864             const XalanDOMString&           theNamespace,
1865             const XalanDOMString&           functionName,
1866             XalanNode*                      context,
1867             const XObjectArgVectorType&     argVec,
1868             const Locator*                  locator) = 0;
1869 
1870     virtual XalanDocument*
1871     parseXML(
1872             MemoryManager&      theManager,
1873             const XalanDOMString&   urlString,
1874             const XalanDOMString&   base,
1875             ErrorHandler*           theErrorHandler = 0) const = 0;
1876 
1877     virtual MutableNodeRefList*
1878     borrowMutableNodeRefList() = 0;
1879 
1880     virtual bool
1881     returnMutableNodeRefList(MutableNodeRefList*    theList) = 0;
1882 
1883     virtual MutableNodeRefList*
1884     createMutableNodeRefList(MemoryManager& theManager) const = 0;
1885 
1886 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
1887 
1888     virtual MutableNodeRefList&
1889     createAndPushMutableNodeRefList() = 0;
1890 
1891     virtual void
1892     releaseAndPopMutableNodeRefList() = 0;
1893 
1894     virtual void
1895     pushXObjectPtr(const XObjectPtr& xobjectPtr) = 0;
1896 
1897     virtual void
1898     popXObjectPtr() = 0;
1899 
1900     virtual void
1901     createAndPushNodesToTransformList(const NodeRefListBase* nodeList) = 0;
1902 
1903     virtual XalanNode*
1904     getNextNodeToTransform() = 0;
1905 
1906     virtual void
1907     popNodesToTransformList() = 0;
1908 
1909     /**
1910      * Get a string that is cached on a stack
1911      * @returns a cached string
1912      */
1913     virtual XalanDOMString&
1914     getAndPushCachedString() = 0;
1915 
1916     /**
1917      * Gets the last string that was cached on the stack
1918      * @returns the last string to be cached
1919      */
1920     virtual XalanDOMString&
1921     getLastCachedString() = 0;
1922 
1923     /**
1924      * Gets the last string to be cached on the stack and
1925      * pops it from the stack.   The reference is valid until
1926      * the next request is made for a cached string
1927      *
1928      * @returns the last string to be cached
1929      */
1930     virtual XalanDOMString&
1931     getAndPopCachedString() = 0;
1932 #endif
1933 
1934     virtual XalanDOMString&
1935     getCachedString() = 0;
1936 
1937     virtual bool
1938     releaseCachedString(XalanDOMString&     theString) = 0;
1939 
1940 
1941     virtual void
1942     getNodeSetByKey(
1943             XalanNode*              context,
1944             const XalanQName&       qname,
1945             const XalanDOMString&   ref,
1946             const Locator*          locator,
1947             MutableNodeRefList&     nodelist) = 0;
1948 
1949     virtual void
1950     getNodeSetByKey(
1951             XalanNode*              context,
1952             const XalanDOMString&   name,
1953             const XalanDOMString&   ref,
1954             const Locator*          locator,
1955             MutableNodeRefList&     nodelist) = 0;
1956 
1957     virtual const XObjectPtr
1958     getVariable(
1959             const XalanQName&   name,
1960             const Locator*      locator = 0) = 0;
1961 
1962     virtual const PrefixResolver*
1963     getPrefixResolver() const = 0;
1964 
1965     virtual void
1966     setPrefixResolver(const PrefixResolver*     thePrefixResolver) = 0;
1967 
1968     virtual const XalanDOMString*
1969     getNamespaceForPrefix(const XalanDOMString&     prefix) const = 0;
1970 
1971     virtual const XalanDOMString&
1972     findURIFromDoc(const XalanDocument*     owner) const = 0;
1973 
1974     virtual const XalanDOMString&
1975     getUnparsedEntityURI(
1976             const XalanDOMString&   theName,
1977             const XalanDocument&    theDocument) const = 0;
1978 
1979     virtual bool
1980     shouldStripSourceNode(const XalanText&  node) = 0;
1981 
1982     virtual XalanDocument*
1983     getSourceDocument(const XalanDOMString&     theURI) const = 0;
1984 
1985     virtual void
1986     setSourceDocument(
1987             const XalanDOMString&   theURI,
1988             XalanDocument*          theDocument) = 0;
1989 
1990     virtual void
1991     formatNumber(
1992             double                  number,
1993             const XalanDOMString&   pattern,
1994             XalanDOMString&         theResult,
1995             const XalanNode*        context = 0,
1996             const Locator*          locator = 0) = 0;
1997 
1998     virtual void
1999     formatNumber(
2000             double                  number,
2001             const XalanDOMString&   pattern,
2002             const XalanDOMString&   dfsName,
2003             XalanDOMString&         theResult,
2004             const XalanNode*        context = 0,
2005             const Locator*          locator = 0) = 0;
2006 
2007     // These interfaces are inherited from ExecutionContext...
2008 
2009     virtual void
2010     problem(
2011             eSource                 source,
2012             eClassification         classification,
2013             const XalanDOMString&   msg,
2014             const Locator*          locator,
2015             const XalanNode*        sourceNode) = 0;
2016 
2017     virtual void
2018     problem(
2019             eSource                 source,
2020             eClassification         classification,
2021             const XalanDOMString&   msg,
2022             const XalanNode*        sourceNode) = 0;
2023 
2024 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
2025 protected:
2026     /**
2027      * Borrow a cached FormatterToText instance.
2028      *
2029      * @return A pointer to the instance.
2030      */
2031     virtual FormatterToText*
2032     borrowFormatterToText() = 0;
2033 
2034     /**
2035      * Return a previously borrowed FormatterToText instance.
2036      *
2037      * @param theFormatter A pointer the to previously borrowed instance.
2038      * @return true if the instance was previously borrowed, false if not.
2039      */
2040     virtual bool
2041     returnFormatterToText(FormatterToText*  theFormatter) = 0;
2042 #endif
2043 };
2044 
2045 
2046 
2047 }
2048 
2049 
2050 
2051 #endif  // STYLESHEETEXECUTIONCONTEXT_HEADER_GUARD_1357924680
2052