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 #include "ElemTemplateElement.hpp"
19 
20 
21 
22 #include <cassert>
23 
24 
25 
26 #include <xercesc/sax/AttributeList.hpp>
27 
28 
29 
30 #include <xalanc/XalanDOM/XalanAttr.hpp>
31 #include <xalanc/XalanDOM/XalanDocument.hpp>
32 #include <xalanc/XalanDOM/XalanDOMException.hpp>
33 
34 
35 
36 #include <xalanc/PlatformSupport/AttributeListImpl.hpp>
37 #include <xalanc/PlatformSupport/DOMStringPrintWriter.hpp>
38 #include <xalanc/PlatformSupport/XalanMessageLoader.hpp>
39 #include <xalanc/PlatformSupport/XalanUnicode.hpp>
40 
41 
42 
43 #include <xalanc/DOMSupport/DOMServices.hpp>
44 
45 
46 
47 #include <xalanc/XMLSupport/FormatterToText.hpp>
48 
49 
50 
51 #include <xalanc/XPath/MutableNodeRefList.hpp>
52 #include <xalanc/XPath/XObjectFactory.hpp>
53 #include <xalanc/XPath/XPathExecutionContext.hpp>
54 #include <xalanc/XPath/XPath.hpp>
55 
56 
57 
58 #include "Constants.hpp"
59 #include "ElemCallTemplate.hpp"
60 #include "ElemForEach.hpp"
61 #include "ElemTemplate.hpp"
62 #include "ElemTextLiteral.hpp"
63 #include "NamespacesHandler.hpp"
64 #include "NodeSorter.hpp"
65 #include "Stylesheet.hpp"
66 #include "StylesheetConstructionContext.hpp"
67 #include "StylesheetExecutionContext.hpp"
68 #include "StylesheetRoot.hpp"
69 #include "SelectionEvent.hpp"
70 #include "TracerEvent.hpp"
71 
72 
73 
74 namespace XALAN_CPP_NAMESPACE {
75 
76 
77 
78 const XalanDOMString            ElemTemplateElement::s_emptyString(XalanMemMgrs::getDummyMemMgr());
79 
80 const XalanQNameByReference     ElemTemplateElement::s_emptyQName(s_emptyString, s_emptyString);
81 
82 
83 
ElemTemplateElement(StylesheetConstructionContext & constructionContext,Stylesheet & stylesheetTree,XalanFileLoc lineNumber,XalanFileLoc columnNumber,int xslToken)84 ElemTemplateElement::ElemTemplateElement(
85             StylesheetConstructionContext&  constructionContext,
86             Stylesheet&                     stylesheetTree,
87             XalanFileLoc                    lineNumber,
88             XalanFileLoc                    columnNumber,
89             int                             xslToken) :
90     PrefixResolver(),
91     m_stylesheet(stylesheetTree),
92     m_namespacesHandler(
93             constructionContext,
94             stylesheetTree.getNamespacesHandler(),
95             stylesheetTree.getNamespaces(),
96             stylesheetTree.getXSLTNamespaceURI()),
97     m_xslToken(xslToken),
98     m_parentNode(0),
99     m_nextSibling(0),
100     m_previousSibling(0),
101     m_firstChild(0),
102     m_locatorProxy(
103         lineNumber,
104         columnNumber,
105         constructionContext.getPooledString(stylesheetTree.getCurrentIncludeBaseIdentifier())),
106     m_flags(eCanGenerateAttributes)
107 {
108 }
109 
110 
111 
ElemTemplateElement(StylesheetConstructionContext & constructionContext,Stylesheet & stylesheetTree,int xslToken,const XalanDOMString & baseURI,XalanFileLoc lineNumber,XalanFileLoc columnNumber)112 ElemTemplateElement::ElemTemplateElement(
113             StylesheetConstructionContext&  constructionContext,
114             Stylesheet&                     stylesheetTree,
115             int                             xslToken,
116             const XalanDOMString&           baseURI,
117             XalanFileLoc                    lineNumber,
118             XalanFileLoc                    columnNumber) :
119     PrefixResolver(),
120     m_stylesheet(stylesheetTree),
121     m_namespacesHandler(constructionContext.getMemoryManager()),
122     m_xslToken(xslToken),
123     m_parentNode(0),
124     m_nextSibling(0),
125     m_previousSibling(0),
126     m_firstChild(0),
127     m_locatorProxy(
128         lineNumber,
129         columnNumber,
130         constructionContext.getPooledString(baseURI)),
131     m_flags(eCanGenerateAttributes)
132 {
133 }
134 
135 
136 
~ElemTemplateElement()137 ElemTemplateElement::~ElemTemplateElement()
138 {
139 }
140 
141 
142 
143 const Locator*
getLocator() const144 ElemTemplateElement::getLocator() const
145 {
146     return &m_locatorProxy;
147 }
148 
149 
150 
151 bool
isWhitespace() const152 ElemTemplateElement::isWhitespace() const
153 {
154     return false;
155 }
156 
157 
158 
159 bool
isAttrOK(const XalanDOMChar * attrName,const AttributeListType & atts,XalanSize_t which,StylesheetConstructionContext & constructionContext) const160 ElemTemplateElement::isAttrOK(
161             const XalanDOMChar*             attrName,
162             const AttributeListType&        atts,
163             XalanSize_t                     which,
164             StylesheetConstructionContext&  constructionContext) const
165 {
166     return m_stylesheet.isAttrOK(attrName, atts, which, constructionContext);
167 }
168 
169 
170 
171 bool
processSpaceAttr(const XalanDOMChar * elementName,const XalanDOMChar * aname,const AttributeListType & atts,XalanSize_t which,StylesheetConstructionContext & constructionContext)172 ElemTemplateElement::processSpaceAttr(
173             const XalanDOMChar*             elementName,
174             const XalanDOMChar*             aname,
175             const AttributeListType&        atts,
176             XalanSize_t                     which,
177             StylesheetConstructionContext&  constructionContext)
178 {
179     if(constructionContext.isXMLSpaceAttribute(
180             aname,
181             getStylesheet(),
182             getLocator()) == false)
183     {
184         return false;
185     }
186     else
187     {
188         const XalanDOMChar* const   spaceVal = atts.getValue(which);
189 
190         if(equals(spaceVal, Constants::ATTRVAL_PRESERVE) == true)
191         {
192             m_flags |= eSpacePreserve;
193         }
194         else if (equals(spaceVal, Constants::ATTRVAL_DEFAULT) == false)
195         {
196             error(
197                 constructionContext,
198                 XalanMessages::ElementHasIllegalAttributeValue_3Param,
199                 elementName,
200                 aname,
201                 spaceVal);
202         }
203 
204         return true;
205     }
206 }
207 
208 
209 
210 bool
isValidNCName(const XalanDOMString & s)211 ElemTemplateElement::isValidNCName(const XalanDOMString&    s)
212 {
213     return XalanQName::isValidNCName(s);
214 }
215 
216 
217 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
218 const ElemTemplateElement*
startElement(StylesheetExecutionContext & executionContext) const219 ElemTemplateElement::startElement(StylesheetExecutionContext&   executionContext) const
220 {
221     if(0 != executionContext.getTraceListeners())
222     {
223         executionContext.fireTraceEvent(
224             TracerEvent(executionContext, *this));
225     }
226     return 0;
227 }
228 
229 
230 
231 
232 void
endElement(StylesheetExecutionContext &) const233 ElemTemplateElement::endElement(StylesheetExecutionContext&     /*executionContext*/) const
234 {
235 }
236 
237 
238 
239 void
execute(StylesheetExecutionContext & executionContext) const240 ElemTemplateElement::execute(StylesheetExecutionContext&            executionContext) const
241 {
242     const ElemTemplateElement* const    invoker =
243             getParentNodeElem();
244 
245     const ElemTemplateElement*  currentElement = this;
246 
247     const ElemTemplateElement*  nextElement = 0;
248 
249     executionContext.pushInvoker(invoker);
250 
251     while (currentElement != 0)
252     {
253         nextElement = currentElement->startElement(executionContext);
254 
255         while (0 == nextElement)
256         {
257             currentElement->endElement(executionContext);
258 
259             if (currentElement->getInvoker(executionContext) == invoker)
260             {
261                 nextElement = 0;
262 
263                 break;
264             }
265 
266             const ElemTemplateElement* const    localInvoker =
267                 currentElement->getInvoker(executionContext);
268             assert(localInvoker != 0);
269 
270             nextElement =
271                 localInvoker->getNextChildElemToExecute(
272                         executionContext,
273                         currentElement);
274 
275             if (0 == nextElement)
276             {
277                 currentElement = currentElement->getInvoker(executionContext);
278             }
279         }
280 
281         currentElement = nextElement;
282     }
283 
284     executionContext.popInvoker();
285 }
286 
287 
288 
289 void
executeChildren(StylesheetExecutionContext & executionContext) const290 ElemTemplateElement::executeChildren(StylesheetExecutionContext&    executionContext) const
291 {
292     const ElemTemplateElement* element = beginExecuteChildren(executionContext);
293 
294     while (element != 0)
295     {
296         element->execute(executionContext);
297 
298         element = getNextChildElemToExecute(executionContext,element);
299     }
300 
301     endExecuteChildren(executionContext);
302 }
303 
304 
305 
306 const ElemTemplateElement*
beginExecuteChildren(StylesheetExecutionContext & executionContext) const307 ElemTemplateElement::beginExecuteChildren(StylesheetExecutionContext&   executionContext) const
308 {
309     if (hasParams() == true || hasVariables() == true)
310     {
311         assert(hasDirectTemplate() == false);
312 
313         executionContext.pushElementFrame(this);
314     }
315 
316     return getFirstChildElemToExecute(executionContext);
317 }
318 
319 
320 
321 void
endExecuteChildren(StylesheetExecutionContext & executionContext) const322 ElemTemplateElement::endExecuteChildren(StylesheetExecutionContext& executionContext) const
323 {
324     if (hasParams() == true || hasVariables() == true)
325     {
326         executionContext.popElementFrame();
327     }
328     else if (hasDirectTemplate() == true)
329     {
330         executionContext.popInvoker();
331         executionContext.popContextMarker();
332     }
333 }
334 
335 
336 
337 const ElemTemplateElement*
beginChildrenToString(StylesheetExecutionContext & executionContext,XalanDOMString & result) const338 ElemTemplateElement::beginChildrenToString(
339             StylesheetExecutionContext&     executionContext,
340             XalanDOMString&                 result) const
341 {
342     if (hasSingleTextChild() == true)
343     {
344         assert(m_textLiteralChild != 0);
345 
346         result.assign(m_textLiteralChild->getText(), m_textLiteralChild->getLength());
347 
348         return 0;
349     }
350     else
351     {
352         result.reserve(result.length() + 1024);
353 
354         executionContext.beginFormatToText(result);
355 
356         return beginExecuteChildren(executionContext);
357     }
358 }
359 
360 
361 
362 void
endChildrenToString(StylesheetExecutionContext & executionContext) const363 ElemTemplateElement::endChildrenToString(
364             StylesheetExecutionContext&     executionContext) const
365 {
366     if (hasSingleTextChild() == false)
367     {
368         endExecuteChildren(executionContext);
369 
370         executionContext.endFormatToText();
371     }
372 }
373 
374 
375 
376 const ElemTemplateElement*
getInvoker(StylesheetExecutionContext &) const377 ElemTemplateElement::getInvoker(StylesheetExecutionContext& /*executionContext*/) const
378 {
379     return getParentNodeElem();
380 }
381 #endif
382 
383 
384 
385 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
386 void
execute(StylesheetExecutionContext & executionContext) const387 ElemTemplateElement::execute(StylesheetExecutionContext&    executionContext) const
388 {
389     if(0 != executionContext.getTraceListeners())
390     {
391         executionContext.fireTraceEvent(
392             TracerEvent(executionContext, *this));
393     }
394 }
395 
396 
397 
398 void
executeChildren(StylesheetExecutionContext & executionContext) const399 ElemTemplateElement::executeChildren(StylesheetExecutionContext&    executionContext) const
400 {
401     if (hasChildren() == true)
402     {
403         if (hasDirectTemplate() == true)
404         {
405             assert(m_directTemplate != 0);
406 
407             // This is temporary, until we can process stylesheet in such a way that we
408             // can detect variable references...
409             const StylesheetExecutionContext::PushAndPopContextMarker   thePushAndPop(executionContext);
410 
411             m_directTemplate->execute(executionContext);
412         }
413         else
414         {
415             if (hasParams() == true || hasVariables() == true)
416             {
417                 const StylesheetExecutionContext::PushAndPopElementFrame    thePushAndPop(executionContext, this);
418 
419                 for (ElemTemplateElement* node = m_firstChild; node != 0; node = node->m_nextSibling)
420                 {
421                     node->execute(executionContext);
422                 }
423             }
424             else
425             {
426                 for (ElemTemplateElement* node = m_firstChild; node != 0; node = node->m_nextSibling)
427                 {
428                     node->execute(executionContext);
429                 }
430             }
431         }
432     }
433 }
434 
435 
436 
437 void
executeChildren(StylesheetExecutionContext & executionContext,XalanNode * sourceNode) const438 ElemTemplateElement::executeChildren(
439         StylesheetExecutionContext&     executionContext,
440         XalanNode*                      sourceNode) const
441 {
442     if (hasChildren() == true)
443     {
444         XalanNode* const    theCurrentNode = executionContext.getCurrentNode();
445 
446         if (theCurrentNode == sourceNode)
447         {
448             executeChildren(executionContext);
449         }
450         else
451         {
452             const XPathExecutionContext::CurrentNodePushAndPop  theCurrentNodePushAndPop(executionContext, sourceNode);
453 
454             executeChildren(executionContext);
455         }
456     }
457 }
458 
459 
460 
461 XalanDOMString&
doChildrenToString(StylesheetExecutionContext & executionContext,XalanDOMString & result) const462 ElemTemplateElement::doChildrenToString(
463             StylesheetExecutionContext&     executionContext,
464             XalanDOMString&                 result) const
465 {
466     reserve(result, length(result) + 1024);
467 
468     // Create a print writer and formatter to generate the children as
469     // a string.
470     DOMStringPrintWriter    thePrintWriter(result);
471 
472     // Borrow a FormatterToText, and don't normalize CR/LF, since we don't want
473     // this text to be normalized.  Finally, have the formatter handle any ignorable
474     // whitespace events.
475     StylesheetExecutionContext::BorrowReturnFormatterToText theFormatter(
476                     executionContext,
477                     thePrintWriter,
478                     false,
479                     true);
480 
481     // Create an object to set and restore the execution state.
482     StylesheetExecutionContext::OutputContextPushPop    theOutputContextPushPop(
483                         executionContext,
484                         theFormatter.get());
485 
486     theFormatter->startDocument();
487 
488     executeChildren(executionContext);
489 
490     theFormatter->endDocument();
491 
492     return result;
493 }
494 
495 
496 
497 const XalanDOMString&
childrenToString(StylesheetExecutionContext & executionContext,XalanDOMString & result) const498 ElemTemplateElement::childrenToString(
499             StylesheetExecutionContext&     executionContext,
500             XalanDOMString&                 result) const
501 {
502     if (hasSingleTextChild() == true)
503     {
504         assert(m_textLiteralChild != 0);
505 
506         assign(result, m_textLiteralChild->getText(), m_textLiteralChild->getLength());
507     }
508     else
509     {
510         doChildrenToString(executionContext, result);
511     }
512 
513     return result;
514 }
515 
516 
517 
518 void
childrenToResultAttribute(StylesheetExecutionContext & executionContext,const XalanDOMString & theName) const519 ElemTemplateElement::childrenToResultAttribute(
520             StylesheetExecutionContext&     executionContext,
521             const XalanDOMString&           theName) const
522 {
523     if (hasSingleTextChild() == true)
524     {
525         executionContext.addResultAttribute(
526                 theName,
527                 m_textLiteralChild->getText());
528     }
529     else
530     {
531         const StylesheetExecutionContext::GetCachedString   theResult(executionContext);
532 
533         childrenToString(executionContext, theResult.get());
534 
535         executionContext.addResultAttribute(
536                 theName,
537                 theResult.get());
538     }
539 }
540 
541 
542 
543 void
childrenToResultComment(StylesheetExecutionContext & executionContext) const544 ElemTemplateElement::childrenToResultComment(StylesheetExecutionContext&    executionContext) const
545 {
546     const StylesheetExecutionContext::GetCachedString   theGuard(executionContext);
547 
548     XalanDOMString&     theData = theGuard.get();
549 
550     childrenToString(executionContext, theData);
551 
552     XalanDOMString::iterator    theEnd =
553         theData.end();
554 
555     XalanDOMString::iterator    theCurrent =
556         theData.begin();
557 
558     // We need to fix up any occurrences of the sequence '--' in
559     // the comment's data by inserting a space between them.  Also,
560     // if the data ends with a '-', then we must append a space to
561     // the data.
562     while(theCurrent != theEnd)
563     {
564         const XalanDOMChar  theChar = *theCurrent;
565 
566         if (theChar == XalanUnicode::charHyphenMinus)
567         {
568             XalanDOMString::iterator    theNext =
569                 theCurrent + 1;
570 
571             if (theNext == theEnd ||
572                 *theNext == XalanUnicode::charHyphenMinus)
573             {
574                 theCurrent =
575                     theData.insert(
576                         theNext,
577                         XalanUnicode::charSpace);
578 
579                 theEnd = theData.end();
580             }
581         }
582 
583         ++theCurrent;
584     }
585 
586     executionContext.comment(theData.c_str());
587 }
588 
589 
590 
591 void
childrenToResultPI(StylesheetExecutionContext & executionContext,const XalanDOMString & theTarget) const592 ElemTemplateElement::childrenToResultPI(
593             StylesheetExecutionContext&     executionContext,
594             const XalanDOMString&           theTarget) const
595 {
596     const StylesheetExecutionContext::GetCachedString   theGuard(executionContext);
597 
598     XalanDOMString&     theData = theGuard.get();
599 
600     childrenToString(executionContext, theData);
601 
602     XalanDOMString::iterator    theEnd =
603         theData.end();
604 
605     XalanDOMString::iterator    theCurrent =
606         theData.begin();
607 
608     // We need to fix up any occurrences of the sequence '?>' in
609     // the PI's data by inserting a space between them.
610     while(theCurrent != theEnd)
611     {
612         const XalanDOMChar  theChar = *theCurrent;
613 
614         if (theChar == XalanUnicode::charQuestionMark)
615         {
616             XalanDOMString::iterator    theNext =
617                 theCurrent + 1;
618 
619             if (theNext != theEnd &&
620                 *theNext == XalanUnicode::charGreaterThanSign)
621             {
622                 theCurrent =
623                     theData.insert(
624                         theNext,
625                         XalanUnicode::charSpace);
626 
627                 theEnd = theData.end();
628 
629                 // Move forward, since we're not interested in
630                 // the '>' character.
631                 ++theCurrent;
632             }
633         }
634 
635         ++theCurrent;
636     }
637 
638     executionContext.processingInstruction(
639             theTarget.c_str(),
640             theData.c_str());
641 }
642 #endif
643 
644 
645 
646 
647 typedef StylesheetExecutionContext::GetCachedString     ECGetCachedString;
648 typedef StylesheetConstructionContext::GetCachedString  CCGetCachedString;
649 
650 
651 
652 void
error(StylesheetExecutionContext & theContext,XalanMessages::Codes theCode) const653 ElemTemplateElement::error(
654             StylesheetExecutionContext&     theContext,
655             XalanMessages::Codes            theCode) const
656 {
657     const ECGetCachedString     theGuard(theContext);
658 
659     theContext.problem(
660         StylesheetExecutionContext::eXSLTProcessor,
661         StylesheetExecutionContext::eError,
662         XalanMessageLoader::getMessage(
663             theGuard.get(),
664             theCode),
665         getLocator(),
666         theContext.getCurrentNode());
667 }
668 
669 
670 
671 void
error(StylesheetExecutionContext & theContext,XalanMessages::Codes theCode,const XalanDOMString & theToken) const672 ElemTemplateElement::error(
673             StylesheetExecutionContext&     theContext,
674             XalanMessages::Codes            theCode,
675             const XalanDOMString&           theToken) const
676 {
677     const ECGetCachedString     theGuard(theContext);
678 
679     theContext.problem(
680         StylesheetExecutionContext::eXSLTProcessor,
681         StylesheetExecutionContext::eError,
682         XalanMessageLoader::getMessage(
683             theGuard.get(),
684             theCode,
685             theToken),
686         getLocator(),
687         theContext.getCurrentNode());
688 }
689 
690 
691 
692 void
error(StylesheetExecutionContext & theContext,XalanMessages::Codes theCode,const Locator * theLocator) const693 ElemTemplateElement::error(
694             StylesheetExecutionContext&     theContext,
695             XalanMessages::Codes            theCode,
696             const Locator*                  theLocator) const
697 {
698     const ECGetCachedString     theGuard(theContext);
699 
700     theContext.problem(
701             StylesheetExecutionContext::eXSLTProcessor,
702             StylesheetExecutionContext::eError,
703         XalanMessageLoader::getMessage(
704             theGuard.get(),
705             theCode),
706         theLocator,
707         theContext.getCurrentNode());
708 }
709 
710 
711 
712 void
warn(StylesheetExecutionContext & theContext,XalanMessages::Codes theCode) const713 ElemTemplateElement::warn(
714             StylesheetExecutionContext&     theContext,
715             XalanMessages::Codes            theCode) const
716 {
717     const ECGetCachedString     theGuard(theContext);
718 
719     theContext.problem(
720         StylesheetExecutionContext::eXSLTProcessor,
721         StylesheetExecutionContext::eWarning,
722         XalanMessageLoader::getMessage(
723             theGuard.get(),
724             theCode),
725         getLocator(),
726         theContext.getCurrentNode());
727 }
728 
729 
730 
731 void
warn(StylesheetExecutionContext & theContext,XalanMessages::Codes theCode,const Locator * theLocator) const732 ElemTemplateElement::warn(
733             StylesheetExecutionContext&     theContext,
734             XalanMessages::Codes            theCode,
735             const Locator*                  theLocator) const
736 {
737     const ECGetCachedString     theGuard(theContext);
738 
739     theContext.problem(
740         StylesheetExecutionContext::eXSLTProcessor,
741         StylesheetExecutionContext::eWarning,
742         XalanMessageLoader::getMessage(
743             theGuard.get(),
744             theCode),
745         theLocator,
746         theContext.getCurrentNode());
747 }
748 
749 
750 
751 void
warn(StylesheetExecutionContext & theContext,XalanMessages::Codes theCode,const XalanDOMString & theToken) const752 ElemTemplateElement::warn(
753             StylesheetExecutionContext&     theContext,
754             XalanMessages::Codes            theCode,
755             const XalanDOMString&           theToken) const
756 {
757     const ECGetCachedString     theGuard(theContext);
758 
759     theContext.problem(
760         StylesheetExecutionContext::eXSLTProcessor,
761         StylesheetExecutionContext::eWarning,
762         XalanMessageLoader::getMessage(
763             theGuard.get(),
764             theCode,
765             theToken),
766         getLocator(),
767         theContext.getCurrentNode());
768 }
769 
770 
771 
772 void
warn(StylesheetConstructionContext & theContext,XalanMessages::Codes theCode,const XalanDOMChar * theToken1,const XalanDOMChar * theToken2,const XalanDOMChar * theToken3)773 ElemTemplateElement::warn(
774             StylesheetConstructionContext&  theContext,
775             XalanMessages::Codes            theCode,
776             const XalanDOMChar*             theToken1,
777             const XalanDOMChar*             theToken2,
778             const XalanDOMChar*             theToken3)
779 {
780     const CCGetCachedString     theGuard(theContext);
781 
782     theContext.problem(
783         StylesheetConstructionContext::eXSLTProcessor,
784         StylesheetConstructionContext::eWarning,
785         XalanMessageLoader::getMessage(
786             theGuard.get(),
787             theCode,
788             theToken1,
789             theToken2,
790             theToken3),
791         getLocator(),
792         0);
793 }
794 
795 
796 
797 void
error(StylesheetConstructionContext & theContext,XalanMessages::Codes theCode)798 ElemTemplateElement::error(
799             StylesheetConstructionContext&  theContext,
800             XalanMessages::Codes            theCode)
801 {
802     const CCGetCachedString     theGuard(theContext);
803 
804     theContext.problem(
805         StylesheetConstructionContext::eXSLTProcessor,
806         StylesheetConstructionContext::eError,
807         XalanMessageLoader::getMessage(
808             theGuard.get(),
809             theCode),
810         getLocator(),
811         0);
812 }
813 
814 
815 
816 void
error(StylesheetConstructionContext & theContext,XalanMessages::Codes theCode,const XalanDOMString & theToken,const Locator * theLocator)817 ElemTemplateElement::error(
818             StylesheetConstructionContext&  theContext,
819             XalanMessages::Codes            theCode,
820             const XalanDOMString&           theToken,
821             const Locator*                  theLocator)
822 {
823     const CCGetCachedString     theGuard(theContext);
824 
825     theContext.problem(
826         StylesheetConstructionContext::eXSLTProcessor,
827         StylesheetConstructionContext::eError,
828         XalanMessageLoader::getMessage(
829             theGuard.get(),
830             theCode,
831             theToken),
832         theLocator,
833         0);
834 }
835 
836 
837 
838 void
error(StylesheetConstructionContext & theContext,XalanMessages::Codes theCode,const XalanDOMString & theToken)839 ElemTemplateElement::error(
840             StylesheetConstructionContext&  theContext,
841             XalanMessages::Codes            theCode,
842             const XalanDOMString&           theToken)
843 {
844     const CCGetCachedString     theGuard(theContext);
845 
846     theContext.problem(
847         StylesheetConstructionContext::eXSLTProcessor,
848         StylesheetConstructionContext::eError,
849         XalanMessageLoader::getMessage(
850             theGuard.get(),
851             theCode,
852             theToken),
853         getLocator(),
854         0);
855 }
856 
857 
858 
859 void
error(StylesheetConstructionContext & theContext,XalanMessages::Codes theCode,const XalanDOMString & theToken1,const XalanDOMString & theToken2)860 ElemTemplateElement::error(
861             StylesheetConstructionContext&  theContext,
862             XalanMessages::Codes            theCode,
863             const XalanDOMString&           theToken1,
864             const XalanDOMString&           theToken2)
865 {
866     const CCGetCachedString     theGuard(theContext);
867 
868     theContext.problem(
869         StylesheetConstructionContext::eXSLTProcessor,
870         StylesheetConstructionContext::eError,
871         XalanMessageLoader::getMessage(
872             theGuard.get(),
873             theCode,
874             theToken1,
875             theToken2),
876         getLocator(),
877         0);
878 }
879 
880 
881 
882 void
error(StylesheetConstructionContext & theContext,XalanMessages::Codes theCode,const XalanDOMChar * theToken1,const XalanDOMChar * theToken2)883 ElemTemplateElement::error(
884             StylesheetConstructionContext&  theContext,
885             XalanMessages::Codes            theCode,
886             const XalanDOMChar*             theToken1,
887             const XalanDOMChar*             theToken2)
888 {
889     const CCGetCachedString     theGuard(theContext);
890 
891     theContext.problem(
892         StylesheetConstructionContext::eXSLTProcessor,
893         StylesheetConstructionContext::eError,
894         XalanMessageLoader::getMessage(
895             theGuard.get(),
896             theCode,
897             theToken1,
898             theToken2),
899         getLocator(),
900         0);
901 }
902 
903 
904 
905 void
error(StylesheetConstructionContext & theContext,XalanMessages::Codes theCode,const XalanDOMChar * theToken1,const XalanDOMChar * theToken2,const XalanDOMChar * theToken3)906 ElemTemplateElement::error(
907             StylesheetConstructionContext&  theContext,
908             XalanMessages::Codes            theCode,
909             const XalanDOMChar*             theToken1,
910             const XalanDOMChar*             theToken2,
911             const XalanDOMChar*             theToken3)
912 {
913     const CCGetCachedString     theGuard(theContext);
914 
915     theContext.problem(
916         StylesheetConstructionContext::eXSLTProcessor,
917         StylesheetConstructionContext::eError,
918         XalanMessageLoader::getMessage(
919             theGuard.get(),
920             theCode,
921             theToken1,
922             theToken2,
923             theToken3),
924         getLocator(),
925         0);
926 }
927 
928 
929 
930 const XalanQName&
getNameAttribute() const931 ElemTemplateElement::getNameAttribute() const
932 {
933     return s_emptyQName;
934 }
935 
936 
937 
938 void
addToStylesheet(StylesheetConstructionContext &,Stylesheet &)939 ElemTemplateElement::addToStylesheet(
940             StylesheetConstructionContext&  /* constructionContext */,
941             Stylesheet&                     /* theStylesheet */)
942 {
943     // An illegal call to addToStylesheet() was made during compilation of the stylesheet.
944     assert ( false );
945 }
946 
947 
948 
949 void
processSortElement(StylesheetConstructionContext & constructionContext,Stylesheet &,const AttributeListType &,const Locator * locator)950 ElemTemplateElement::processSortElement(
951             StylesheetConstructionContext&  constructionContext,
952             Stylesheet&                     /* theStylesheet */,
953             const AttributeListType&        /* atts */,
954             const Locator*                  locator)
955 {
956     error(
957         constructionContext,
958         XalanMessages::ElementIsNotAllowedAtThisPosition_1Param,
959         Constants::ELEMNAME_SORT_WITH_PREFIX_STRING,
960         locator);
961 }
962 
963 
964 
965 void
setDefaultTemplate(bool value)966 ElemTemplateElement::setDefaultTemplate(bool    value)
967 {
968     m_flags |= eDefaultTemplate;
969 
970     for (ElemTemplateElement* node = m_firstChild; node != 0; node = node->m_nextSibling)
971     {
972         node->setDefaultTemplate(value);
973     }
974 }
975 
976 
977 
978 ElemTemplateElement*
getFirstChildElem() const979 ElemTemplateElement::getFirstChildElem() const
980 {
981     return m_firstChild;
982 }
983 
984 
985 
986 void
setFirstChildElem(ElemTemplateElement * theElement)987 ElemTemplateElement::setFirstChildElem(ElemTemplateElement*     theElement)
988 {
989     m_firstChild = theElement;
990 }
991 
992 
993 
994 ElemTemplateElement*
getLastChildElem() const995 ElemTemplateElement::getLastChildElem() const
996 {
997     ElemTemplateElement* lastChild = 0;
998 
999     for (ElemTemplateElement* node = m_firstChild; node != 0; node = node->m_nextSibling)
1000     {
1001         lastChild = node;
1002     }
1003 
1004     return lastChild;
1005 }
1006 
1007 
1008 
1009 ElemTemplateElement*
getNextSiblingElem() const1010 ElemTemplateElement::getNextSiblingElem() const
1011 {
1012     return m_nextSibling;
1013 }
1014 
1015 
1016 
1017 void
setNextSiblingElem(ElemTemplateElement * theSibling)1018 ElemTemplateElement::setNextSiblingElem(ElemTemplateElement*    theSibling)
1019 {
1020     m_nextSibling = theSibling;
1021 }
1022 
1023 
1024 
1025 ElemTemplateElement*
getPreviousSiblingElem() const1026 ElemTemplateElement::getPreviousSiblingElem() const
1027 {
1028     return m_previousSibling;
1029 }
1030 
1031 
1032 
1033 void
setPreviousSiblingElem(ElemTemplateElement * theSibling)1034 ElemTemplateElement::setPreviousSiblingElem(ElemTemplateElement*    theSibling)
1035 {
1036     m_previousSibling = theSibling;
1037 }
1038 
1039 
1040 
1041 ElemTemplateElement*
getParentNodeElem() const1042 ElemTemplateElement::getParentNodeElem() const
1043 {
1044     return m_parentNode;
1045 }
1046 
1047 
1048 
1049 void
setParentNodeElem(ElemTemplateElement * theParent)1050 ElemTemplateElement::setParentNodeElem(ElemTemplateElement*     theParent)
1051 {
1052     m_parentNode = theParent;
1053 }
1054 
1055 
1056 
1057 ElemTemplateElement*
appendChildElem(ElemTemplateElement * newChild)1058 ElemTemplateElement::appendChildElem(ElemTemplateElement*   newChild)
1059 {
1060     assert(newChild != 0);
1061     assert(newChild->getXSLToken() != StylesheetConstructionContext::ELEMNAME_TEXT);
1062     assert(newChild->getXSLToken() != StylesheetConstructionContext::ELEMNAME_UNDEFINED);
1063 
1064     if (childTypeAllowed(newChild->getXSLToken()) == false)
1065     {
1066         throw XalanDOMException(XalanDOMException::HIERARCHY_REQUEST_ERR);
1067     }
1068     else if(0 == m_firstChild)
1069     {
1070         m_firstChild = newChild;
1071 
1072         newChild->setPreviousSiblingElem(0);
1073     }
1074     else
1075     {
1076         ElemTemplateElement* const  last = getLastChildElem();
1077         assert(last != 0);
1078 
1079         last->setNextSiblingElem(newChild);
1080 
1081         newChild->setPreviousSiblingElem(last);
1082     }
1083 
1084     newChild->setParentNodeElem(this);
1085     newChild->setNextSiblingElem(0);
1086 
1087     return newChild;
1088 }
1089 
1090 
1091 
1092 const XPath*
getXPath(XalanSize_t) const1093 ElemTemplateElement::getXPath(XalanSize_t   /* index */) const
1094 {
1095     return 0;
1096 }
1097 
1098 
1099 
1100 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
1101 const ElemTemplateElement*
findTemplateToTransformChild(StylesheetExecutionContext & executionContext,const ElemTemplateElement & xslInstruction,const ElemTemplateElement * theTemplate,XalanNode * child) const1102 ElemTemplateElement::findTemplateToTransformChild(
1103             StylesheetExecutionContext&     executionContext,
1104             const ElemTemplateElement&      xslInstruction,
1105             const ElemTemplateElement*      theTemplate,
1106             XalanNode*                      child) const
1107 {
1108     assert(child != 0);
1109 
1110     return findTemplateToTransformChild(
1111         executionContext,
1112         xslInstruction,
1113         theTemplate,
1114         child,
1115         child->getNodeType());
1116 }
1117 
1118 
1119 const ElemTemplateElement*
findTemplateToTransformChild(StylesheetExecutionContext & executionContext,const ElemTemplateElement & xslInstruction,const ElemTemplateElement * theTemplate,XalanNode * child,XalanNode::NodeType nodeType) const1120 ElemTemplateElement::findTemplateToTransformChild(
1121             StylesheetExecutionContext&     executionContext,
1122             const ElemTemplateElement&      xslInstruction,
1123             const ElemTemplateElement*      theTemplate,
1124             XalanNode*                      child,
1125             XalanNode::NodeType             nodeType) const
1126 {
1127     assert(child != 0);
1128 
1129     if(0 == theTemplate)
1130     {
1131         // Find the XSL template that is the best match for the
1132         // element...
1133         const bool          isApplyImports = xslInstruction.getXSLToken() ==
1134             StylesheetConstructionContext::ELEMNAME_APPLY_IMPORTS;
1135         assert(isApplyImports == false || executionContext.getCurrentTemplate() != 0);
1136 
1137         const Stylesheet*   stylesheetTree = isApplyImports == true ?
1138                                 &executionContext.getCurrentTemplate()->getStylesheet() :
1139                                 &getStylesheet().getStylesheetRoot();
1140 
1141         theTemplate = stylesheetTree->findTemplate(
1142                         executionContext,
1143                         child,
1144                         nodeType,
1145                         *executionContext.getCurrentMode(),
1146                         isApplyImports);
1147     }
1148 
1149     if(0 == theTemplate)
1150     {
1151         switch(nodeType)
1152         {
1153         case XalanNode::DOCUMENT_FRAGMENT_NODE:
1154         case XalanNode::ELEMENT_NODE:
1155             theTemplate = getStylesheet().getStylesheetRoot().getDefaultRule();
1156             break;
1157 
1158         case XalanNode::CDATA_SECTION_NODE:
1159         case XalanNode::TEXT_NODE:
1160             theTemplate = getStylesheet().getStylesheetRoot().getDefaultTextRule();
1161             break;
1162 
1163         case XalanNode::ATTRIBUTE_NODE:
1164             if (DOMServices::isNamespaceDeclaration(static_cast<const XalanAttr&>(*child)) == false)
1165             {
1166                 theTemplate = getStylesheet().getStylesheetRoot().getDefaultTextRule();
1167             }
1168             break;
1169 
1170         case XalanNode::DOCUMENT_NODE:
1171             theTemplate = getStylesheet().getStylesheetRoot().getDefaultRootRule();
1172             break;
1173 
1174         default:
1175             break;
1176         }
1177     }
1178 
1179     if(0 != theTemplate)
1180     {
1181         if(theTemplate == getStylesheet().getStylesheetRoot().getDefaultTextRule())
1182         {
1183             switch(nodeType)
1184             {
1185             case XalanNode::CDATA_SECTION_NODE:
1186             case XalanNode::TEXT_NODE:
1187                 executionContext.cloneToResultTree(
1188                     *child,
1189                     XalanNode::TEXT_NODE,
1190                     true,
1191                     false,
1192                     getLocator());
1193                 break;
1194 
1195             case XalanNode::ATTRIBUTE_NODE:
1196                 {
1197                     const XalanDOMString&   val = child->getNodeValue();
1198 
1199                     const XalanDOMString::size_type     len = val.length();
1200 
1201                     if (len > 0)
1202                     {
1203                         executionContext.characters(
1204                             val.c_str(),
1205                             0,
1206                             len);
1207                     }
1208                 }
1209                 break;
1210 
1211             default:
1212                 assert(false);
1213                 break;
1214             }
1215         }
1216         else
1217         {
1218             if(0 != executionContext.getTraceListeners())
1219             {
1220                 const TracerEvent   te(executionContext,
1221                                        *theTemplate);
1222 
1223                 executionContext.fireTraceEvent(te);
1224             }
1225 
1226             return theTemplate;
1227         }
1228     }
1229     return 0;
1230 }
1231 
1232 
1233 
1234 #else
1235 void
transformChild(StylesheetExecutionContext & executionContext,const ElemTemplateElement & xslInstruction,const ElemTemplateElement * theTemplate,XalanNode * child) const1236 ElemTemplateElement::transformChild(
1237             StylesheetExecutionContext&     executionContext,
1238             const ElemTemplateElement&      xslInstruction,
1239             const ElemTemplateElement*      theTemplate,
1240             XalanNode*                      child) const
1241 {
1242     assert(child != 0);
1243 
1244     transformChild(
1245         executionContext,
1246         xslInstruction,
1247         theTemplate,
1248         child,
1249         child->getNodeType());
1250 }
1251 
1252 
1253 
1254 
1255 void
transformChild(StylesheetExecutionContext & executionContext,const ElemTemplateElement & xslInstruction,const ElemTemplateElement * theTemplate,XalanNode * child,XalanNode::NodeType nodeType) const1256 ElemTemplateElement::transformChild(
1257             StylesheetExecutionContext&     executionContext,
1258             const ElemTemplateElement&      xslInstruction,
1259             const ElemTemplateElement*      theTemplate,
1260             XalanNode*                      child,
1261             XalanNode::NodeType             nodeType) const
1262 {
1263     assert(child != 0);
1264 
1265     if(0 == theTemplate)
1266     {
1267         // Find the XSL template that is the best match for the
1268         // element...
1269         const bool          isApplyImports = xslInstruction.getXSLToken() ==
1270             StylesheetConstructionContext::ELEMNAME_APPLY_IMPORTS;
1271         assert(isApplyImports == false || executionContext.getCurrentTemplate() != 0);
1272 
1273         const Stylesheet*   stylesheetTree = isApplyImports == true ?
1274                                 &executionContext.getCurrentTemplate()->getStylesheet() :
1275                                 &getStylesheet().getStylesheetRoot();
1276 
1277         theTemplate = stylesheetTree->findTemplate(
1278                         executionContext,
1279                         child,
1280                         nodeType,
1281                         *executionContext.getCurrentMode(),
1282                         isApplyImports);
1283     }
1284 
1285     if(0 == theTemplate)
1286     {
1287         switch(nodeType)
1288         {
1289         case XalanNode::DOCUMENT_FRAGMENT_NODE:
1290         case XalanNode::ELEMENT_NODE:
1291             theTemplate = getStylesheet().getStylesheetRoot().getDefaultRule();
1292             break;
1293 
1294         case XalanNode::CDATA_SECTION_NODE:
1295         case XalanNode::TEXT_NODE:
1296         case XalanNode::ATTRIBUTE_NODE:
1297             theTemplate = getStylesheet().getStylesheetRoot().getDefaultTextRule();
1298             break;
1299 
1300         case XalanNode::DOCUMENT_NODE:
1301             theTemplate = getStylesheet().getStylesheetRoot().getDefaultRootRule();
1302             break;
1303 
1304         default:
1305             break;
1306         }
1307     }
1308 
1309     if(0 != theTemplate)
1310     {
1311         if(theTemplate == getStylesheet().getStylesheetRoot().getDefaultTextRule())
1312         {
1313             switch(nodeType)
1314             {
1315             case XalanNode::CDATA_SECTION_NODE:
1316             case XalanNode::TEXT_NODE:
1317                 executionContext.cloneToResultTree(
1318                     *child,
1319                     XalanNode::TEXT_NODE,
1320                     true,
1321                     false,
1322                     getLocator());
1323                 break;
1324 
1325             case XalanNode::ATTRIBUTE_NODE:
1326                 {
1327                     const XalanDOMString&   val = child->getNodeValue();
1328 
1329                     const XalanDOMString::size_type     len = length(val);
1330 
1331                     if (len > 0)
1332                     {
1333                         executionContext.characters(
1334                             val.c_str(),
1335                             0,
1336                             len);
1337                     }
1338                 }
1339                 break;
1340 
1341             default:
1342                 assert(false);
1343                 break;
1344             }
1345         }
1346         else
1347         {
1348             if(0 != executionContext.getTraceListeners())
1349             {
1350                 const TracerEvent   te(executionContext,
1351                                        *theTemplate);
1352 
1353                 executionContext.fireTraceEvent(te);
1354             }
1355 
1356             theTemplate->executeChildren(executionContext, child);
1357         }
1358     }
1359 }
1360 #endif
1361 
1362 
1363 
1364 void
postConstruction(StylesheetConstructionContext & constructionContext,const NamespacesHandler & theParentHandler)1365 ElemTemplateElement::postConstruction(
1366             StylesheetConstructionContext&  constructionContext,
1367             const NamespacesHandler&        theParentHandler)
1368 {
1369     namespacesPostConstruction(
1370             constructionContext,
1371             theParentHandler,
1372             m_namespacesHandler);
1373 
1374     if (hasChildren() == true)
1375     {
1376         for (ElemTemplateElement* node = m_firstChild; node != 0; node = node->m_nextSibling)
1377         {
1378             node->postConstruction(constructionContext, m_namespacesHandler);
1379 
1380             const int   theToken = node->getXSLToken();
1381 
1382             if (hasVariables() == false &&
1383                 (theToken == StylesheetConstructionContext::ELEMNAME_VARIABLE ||
1384                  theToken == StylesheetConstructionContext::ELEMNAME_PARAM))
1385             {
1386                 m_flags |= eHasVariables;
1387             }
1388 
1389             if (hasParams() == false &&
1390                 theToken == StylesheetConstructionContext::ELEMNAME_WITH_PARAM)
1391             {
1392                 m_flags |= eHasParams;
1393             }
1394         }
1395 
1396         assert(m_firstChild != 0);
1397 
1398         const int   theToken = m_firstChild->getXSLToken();
1399 
1400         // There are opportunities for optimization if there's only one
1401         // xsl:text child node.  See childrenToString()...
1402         if (theToken == StylesheetConstructionContext::ELEMNAME_TEXT_LITERAL_RESULT &&
1403             m_firstChild->getNextSiblingElem() == 0)
1404         {
1405             m_flags |= eHasSingleTextChild;
1406         }
1407         else if (theToken == StylesheetConstructionContext::ELEMNAME_CALL_TEMPLATE &&
1408                  m_firstChild->getNextSiblingElem() == 0)
1409         {
1410             // Just a single xsl:call-template child, so we don't need to
1411             // execute it if it has no params -- we can just execute the
1412             // template directly...
1413             if (m_firstChild->hasParams() == false)
1414             {
1415                 m_flags |= eHasDirectTemplate;
1416 
1417                 ElemCallTemplate* const     theCallTemplateChild =
1418                     static_cast<ElemCallTemplate*>(m_firstChild);
1419 
1420                 m_directTemplate = theCallTemplateChild->getTemplate();
1421             }
1422         }
1423         else if (canGenerateAttributes() == false &&
1424                  theToken != StylesheetConstructionContext::ELEMNAME_LITERAL_RESULT)
1425         {
1426             m_flags |= eCanGenerateAttributes;
1427         }
1428     }
1429 }
1430 
1431 
1432 
1433 void
namespacesPostConstruction(StylesheetConstructionContext & constructionContext,const NamespacesHandler & theParentHandler,NamespacesHandler & theHandler)1434 ElemTemplateElement::namespacesPostConstruction(
1435             StylesheetConstructionContext&  constructionContext,
1436             const NamespacesHandler&        theParentHandler,
1437             NamespacesHandler&              theHandler)
1438 {
1439     theHandler.postConstruction(
1440             constructionContext,
1441             true,
1442             getElementName(),
1443             &theParentHandler);
1444 }
1445 
1446 
1447 
1448 const XalanDOMString*
getNamespaceForPrefix(const XalanDOMString & prefix) const1449 ElemTemplateElement::getNamespaceForPrefix(const XalanDOMString&    prefix) const
1450 {
1451     return getNamespaceForPrefixInternal(prefix);
1452 }
1453 
1454 
1455 
1456 bool
processPrefixControl(StylesheetConstructionContext & constructionContext,const Stylesheet & stylesheetTree,const XalanDOMString & localName,const XalanDOMChar * attrValue)1457 ElemTemplateElement::processPrefixControl(
1458             StylesheetConstructionContext&  constructionContext,
1459             const Stylesheet&               stylesheetTree,
1460             const XalanDOMString&           localName,
1461             const XalanDOMChar*             attrValue)
1462 {
1463     if(equals(localName, Constants::ATTRNAME_EXTENSIONELEMENTPREFIXES))
1464     {
1465         m_namespacesHandler.processExtensionElementPrefixes(
1466                 constructionContext,
1467                 attrValue,
1468                 stylesheetTree.getNamespaces());
1469 
1470         return true;
1471     }
1472     else if (equals(localName, Constants::ATTRNAME_EXCLUDE_RESULT_PREFIXES))
1473     {
1474         m_namespacesHandler.processExcludeResultPrefixes(
1475                 constructionContext,
1476                 attrValue,
1477                 stylesheetTree.getNamespaces());
1478 
1479         return true;
1480     }
1481     else
1482     {
1483         return false;
1484     }
1485 }
1486 
1487 
1488 
1489 const XalanDOMString*
getNamespaceForPrefixInternal(const XalanDOMString & prefix) const1490 ElemTemplateElement::getNamespaceForPrefixInternal(const XalanDOMString&    prefix) const
1491 {
1492     const XalanDOMString*   nameSpace = 0;
1493 
1494     if(getFinishedConstruction() == false)
1495     {
1496         nameSpace = getStylesheet().getNamespaceForPrefixFromStack(prefix);
1497     }
1498     else
1499     {
1500         if (equals(prefix, DOMServices::s_XMLString) == true)
1501         {
1502             nameSpace = &DOMServices::s_XMLNamespaceURI;
1503         }
1504         else
1505         {
1506             nameSpace = getNamespacesHandler().getNamespace(prefix);
1507 
1508             if(nameSpace == 0)
1509             {
1510                 if (m_parentNode != 0)
1511                 {
1512                     nameSpace = m_parentNode->getNamespaceForPrefixInternal(prefix);
1513                 }
1514 
1515                 // Try one last time with the stylesheet...
1516                 if (nameSpace == 0)
1517                 {
1518                    nameSpace = getStylesheet().getNamespaceForPrefix(prefix);
1519                 }
1520             }
1521         }
1522     }
1523 
1524     return nameSpace;
1525 }
1526 
1527 
1528 
1529 const XalanDOMString&
getURI() const1530 ElemTemplateElement::getURI() const
1531 {
1532     return m_locatorProxy.getURI();
1533 }
1534 
1535 
1536 
LocatorProxy(XalanFileLoc theLineNumber,XalanFileLoc theColumnNumber,const XalanDOMString & theURI)1537 ElemTemplateElement::LocatorProxy::LocatorProxy(
1538             XalanFileLoc            theLineNumber,
1539             XalanFileLoc            theColumnNumber,
1540             const XalanDOMString&   theURI) :
1541     m_lineNumber(theLineNumber),
1542     m_columnNumber(theColumnNumber),
1543     m_uri(theURI)
1544 {
1545 }
1546 
1547 
1548 
~LocatorProxy()1549 ElemTemplateElement::LocatorProxy::~LocatorProxy()
1550 {
1551 }
1552 
1553 
1554 
1555 XalanFileLoc
getLineNumber() const1556 ElemTemplateElement::LocatorProxy::getLineNumber() const
1557 {
1558     return m_lineNumber;
1559 }
1560 
1561 
1562 
1563 XalanFileLoc
getColumnNumber() const1564 ElemTemplateElement::LocatorProxy::getColumnNumber() const
1565 {
1566     return m_columnNumber;
1567 }
1568 
1569 
1570 
1571 const XMLCh*
getPublicId() const1572 ElemTemplateElement::LocatorProxy::getPublicId() const
1573 {
1574     return 0;
1575 }
1576 
1577 
1578 
1579 const XMLCh*
getSystemId() const1580 ElemTemplateElement::LocatorProxy::getSystemId() const
1581 {
1582     return m_uri.size() == 0 ? 0 : m_uri.c_str();
1583 }
1584 
1585 
1586 
1587 bool
childTypeAllowed(int) const1588 ElemTemplateElement::childTypeAllowed(int   /* xslToken */) const
1589 {
1590     return true;
1591 }
1592 
1593 
1594 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
1595 const ElemTemplateElement*
getNextChildElemToExecute(StylesheetExecutionContext & executionContext,const ElemTemplateElement * currentElem) const1596 ElemTemplateElement::getNextChildElemToExecute(StylesheetExecutionContext& executionContext,
1597                                  const ElemTemplateElement* currentElem) const
1598 {
1599     if (hasDirectTemplate() == true)
1600     {
1601         return 0;
1602     }
1603 
1604     assert(currentElem != 0);
1605 
1606     const ElemTemplateElement* nextElement;
1607 
1608     while((nextElement = currentElem->getNextSiblingElem()) != 0
1609           && !executeChildElement(executionContext, nextElement))
1610     {
1611         currentElem = nextElement;
1612     }
1613 
1614     return nextElement;
1615 
1616 }
1617 
1618 
1619 
1620 const ElemTemplateElement*
getFirstChildElemToExecute(StylesheetExecutionContext & executionContext) const1621 ElemTemplateElement::getFirstChildElemToExecute(StylesheetExecutionContext& executionContext) const
1622 {
1623     if (hasDirectTemplate() == true)
1624     {
1625         assert(m_directTemplate != 0);
1626 
1627         executionContext.pushContextMarker();
1628         executionContext.pushInvoker(this);
1629 
1630         return m_directTemplate;
1631     }
1632 
1633     const ElemTemplateElement * firstElement = getFirstChildElem();
1634 
1635     if (firstElement != 0 && !executeChildElement(executionContext, firstElement))
1636     {
1637         firstElement = ElemTemplateElement::getNextChildElemToExecute(executionContext,firstElement);
1638     }
1639 
1640     return firstElement;
1641 
1642 }
1643 
1644 
1645 
1646 bool
executeChildElement(StylesheetExecutionContext &,const ElemTemplateElement *) const1647 ElemTemplateElement::executeChildElement(
1648             StylesheetExecutionContext& /*executionContext*/,
1649             const ElemTemplateElement*  /*element*/) const
1650 {
1651     return true;
1652 }
1653 #endif
1654 
1655 }
1656