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
19 #include "StylesheetExecutionContextDefault.hpp"
20
21
22
23 #include <algorithm>
24 #include <cassert>
25
26
27
28 #include <xalanc/Include/STLHelper.hpp>
29
30
31
32 #include <xalanc/PlatformSupport/DOMStringPrintWriter.hpp>
33 #include <xalanc/PlatformSupport/XalanOutputStream.hpp>
34 #include <xalanc/PlatformSupport/XalanNumberFormat.hpp>
35 #include <xalanc/PlatformSupport/XalanOutputStreamPrintWriter.hpp>
36 #include <xalanc/PlatformSupport/XalanStdOutputStream.hpp>
37 #include <xalanc/PlatformSupport/XalanFileOutputStream.hpp>
38 #include <xalanc/PlatformSupport/XalanFStreamOutputStream.hpp>
39 #include <xalanc/PlatformSupport/XalanMessageLoader.hpp>
40 #include <xalanc/PlatformSupport/XalanTranscodingServices.hpp>
41
42
43
44 #include <xalanc/XPath/XObjectFactory.hpp>
45 #include <xalanc/XPath/XPath.hpp>
46 #include <xalanc/XPath/XPathEnvSupport.hpp>
47 #include <xalanc/XPath/XPathExecutionContext.hpp>
48 #include <xalanc/XPath/XObject.hpp>
49
50
51
52 #include <xalanc/XMLSupport/XalanXMLSerializerFactory.hpp>
53 #include <xalanc/XMLSupport/FormatterToHTML.hpp>
54 #include <xalanc/XMLSupport/FormatterToText.hpp>
55 #include <xalanc/XMLSupport/XMLParserLiaison.hpp>
56
57
58
59 #include <xalanc/XalanSourceTree/FormatterToSourceTree.hpp>
60 #include <xalanc/XalanSourceTree/XalanSourceTreeDocument.hpp>
61 #include <xalanc/XalanSourceTree/XalanSourceTreeDocumentFragment.hpp>
62
63
64
65 #include "Constants.hpp"
66 #include "ElemTemplateElement.hpp"
67 #include "ElemWithParam.hpp"
68 #include "KeyTable.hpp"
69 #include "StylesheetConstructionContextDefault.hpp"
70 #include "StylesheetRoot.hpp"
71 #include "XSLTEngineImpl.hpp"
72 #include "XSLTProcessorException.hpp"
73
74
75
76 //#define XALAN_VQ_SPECIAL_TRACE
77 #if defined(XALAN_VQ_SPECIAL_TRACE)
78 #include "C:/Program Files/Rational/Quantify/pure.h"
79 #endif
80
81
82
83 namespace XALAN_CPP_NAMESPACE {
84
85
86
87 StylesheetExecutionContextDefault::XalanNumberFormatFactory StylesheetExecutionContextDefault::s_defaultXalanNumberFormatFactory;
88
89 StylesheetExecutionContextDefault::XalanNumberFormatFactory* StylesheetExecutionContextDefault::s_xalanNumberFormatFactory =
90 &StylesheetExecutionContextDefault::getDefaultXalanNumberFormatFactory();
91
92 const StylesheetExecutionContextDefault::DefaultCollationCompareFunctor StylesheetExecutionContextDefault::s_defaultCollationFunctor;
93
94
95
StylesheetExecutionContextDefault(MemoryManager & theManager,XSLTEngineImpl & xsltProcessor,XPathEnvSupport & theXPathEnvSupport,DOMSupport & theDOMSupport,XObjectFactory & theXObjectFactory,XalanNode * theCurrentNode,const NodeRefListBase * theContextNodeList,const PrefixResolver * thePrefixResolver)96 StylesheetExecutionContextDefault::StylesheetExecutionContextDefault(
97 MemoryManager& theManager,
98 XSLTEngineImpl& xsltProcessor,
99 XPathEnvSupport& theXPathEnvSupport,
100 DOMSupport& theDOMSupport,
101 XObjectFactory& theXObjectFactory,
102 XalanNode* theCurrentNode,
103 const NodeRefListBase* theContextNodeList,
104 const PrefixResolver* thePrefixResolver) :
105 StylesheetExecutionContext(theManager, &theXObjectFactory),
106 m_xpathExecutionContextDefault(theXPathEnvSupport,
107 theDOMSupport,
108 theXObjectFactory,
109 theCurrentNode,
110 theContextNodeList,
111 thePrefixResolver),
112 m_xsltProcessor(&xsltProcessor),
113 m_rootDocument(0),
114 m_elementRecursionStack(theManager),
115 m_stylesheetRoot(0),
116 m_formatterListeners(theManager),
117 m_printWriters(theManager),
118 m_outputStreams(theManager),
119 m_collationCompareFunctor(0),
120 m_formatNumberFunctor(0),
121 m_variablesStack(theManager),
122 m_paramsVector(theManager),
123 m_matchPatternCache(theManager),
124 m_keyTables(theManager),
125 m_countersTable(theManager),
126 m_sourceTreeResultTreeFactory(),
127 m_mode(0),
128 m_currentTemplateStack(theManager),
129 m_indentAmount(-1),
130 m_xresultTreeFragAllocator(theManager, eXResultTreeFragAllocatorBlockSize),
131 m_documentFragmentAllocator(theManager, eDocumentFragmentAllocatorBlockSize),
132 m_documentAllocator(theManager, eDocumentAllocatorBlockSize),
133 m_copyTextNodesOnlyStack(theManager),
134 m_modeStack(theManager),
135 m_currentIndexStack(theManager),
136 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
137 m_xobjectPtrStack(theManager),
138 m_mutableNodeRefListStack(theManager),
139 m_nodesToTransformStack(theManager),
140 m_processCurrentAttributeStack(theManager),
141 m_executeIfStack(theManager),
142 m_stringStack(theManager),
143 m_formatterToTextStack(theManager),
144 m_skipElementAttributesStack(theManager),
145 m_formatterToSourceTreeStack(theManager),
146 m_paramsVectorStack(theManager),
147 m_elementInvokerStack(theManager),
148 m_useAttributeSetIndexesStack(theManager),
149 m_nodeSorter(theManager),
150 #else
151 m_formatterToTextCache(theManager),
152 m_formatterToSourceTreeCache(theManager),
153 m_nodeSorterCache(theManager),
154 #endif
155 m_usePerInstanceDocumentFactory(false),
156 m_escapeURLs(eEscapeURLsDefault),
157 m_omitMETATag(eOmitMETATagDefault)
158 {
159 m_currentTemplateStack.push_back(0);
160 }
161
162
163
StylesheetExecutionContextDefault(MemoryManager & theManager,XalanNode * theCurrentNode,const NodeRefListBase * theContextNodeList,const PrefixResolver * thePrefixResolver)164 StylesheetExecutionContextDefault::StylesheetExecutionContextDefault(
165 MemoryManager& theManager,
166 XalanNode* theCurrentNode,
167 const NodeRefListBase* theContextNodeList,
168 const PrefixResolver* thePrefixResolver) :
169 StylesheetExecutionContext(theManager),
170 m_xpathExecutionContextDefault(theManager,
171 theCurrentNode,
172 theContextNodeList,
173 thePrefixResolver),
174 m_xsltProcessor(0),
175 m_rootDocument(0),
176 m_elementRecursionStack(theManager),
177 m_stylesheetRoot(0),
178 m_formatterListeners(theManager),
179 m_printWriters(theManager),
180 m_outputStreams(theManager),
181 m_collationCompareFunctor(0),
182 m_formatNumberFunctor(0),
183 m_variablesStack(theManager),
184 m_paramsVector(theManager),
185 m_matchPatternCache(theManager),
186 m_keyTables(theManager),
187 m_countersTable(theManager),
188 m_sourceTreeResultTreeFactory(),
189 m_mode(0),
190 m_currentTemplateStack(theManager),
191 m_indentAmount(-1),
192 m_xresultTreeFragAllocator(theManager, eXResultTreeFragAllocatorBlockSize),
193 m_documentFragmentAllocator(theManager, eDocumentFragmentAllocatorBlockSize),
194 m_documentAllocator(theManager, eDocumentAllocatorBlockSize),
195 m_copyTextNodesOnlyStack(theManager),
196 m_modeStack(theManager),
197 m_currentIndexStack(theManager),
198 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
199 m_xobjectPtrStack(theManager),
200 m_mutableNodeRefListStack(theManager),
201 m_nodesToTransformStack(theManager),
202 m_processCurrentAttributeStack(theManager),
203 m_executeIfStack(theManager),
204 m_stringStack(theManager),
205 m_formatterToTextStack(theManager),
206 m_skipElementAttributesStack(theManager),
207 m_formatterToSourceTreeStack(theManager),
208 m_paramsVectorStack(theManager),
209 m_elementInvokerStack(theManager),
210 m_useAttributeSetIndexesStack(theManager),
211 m_nodeSorter(theManager),
212 #else
213 m_formatterToTextCache(theManager),
214 m_formatterToSourceTreeCache(theManager),
215 m_nodeSorterCache(theManager),
216 #endif
217 m_usePerInstanceDocumentFactory(false),
218 m_escapeURLs(eEscapeURLsDefault),
219 m_omitMETATag(eOmitMETATagDefault)
220 {
221 m_currentTemplateStack.push_back(0);
222 }
223
224
225
226 StylesheetExecutionContextDefault*
create(MemoryManager & theManager,XalanNode * theCurrentNode,const NodeRefListBase * theContextNodeList,const PrefixResolver * thePrefixResolver)227 StylesheetExecutionContextDefault::create(
228 MemoryManager& theManager,
229 XalanNode* theCurrentNode,
230 const NodeRefListBase* theContextNodeList,
231 const PrefixResolver* thePrefixResolver)
232 {
233 typedef StylesheetExecutionContextDefault ThisType;
234
235 XalanAllocationGuard theGuard(theManager, theManager.allocate(sizeof(ThisType)));
236
237 ThisType* const theResult =
238 new (theGuard.get()) ThisType(
239 theManager,
240 theCurrentNode,
241 theContextNodeList,
242 thePrefixResolver);
243 theGuard.release();
244
245 return theResult;
246 }
247
248
249
~StylesheetExecutionContextDefault()250 StylesheetExecutionContextDefault::~StylesheetExecutionContextDefault()
251 {
252 reset();
253 }
254
255
256
257 void
problem(eSource source,eClassification classification,const XalanDOMString & msg,const Locator * locator,const XalanNode * sourceNode)258 StylesheetExecutionContextDefault::problem(
259 eSource source,
260 eClassification classification,
261 const XalanDOMString& msg,
262 const Locator* locator,
263 const XalanNode* sourceNode)
264 {
265 m_xsltProcessor->problem(
266 source,
267 classification,
268 msg,
269 locator,
270 sourceNode);
271 }
272
273
274
275 void
problem(eSource source,eClassification classification,const XalanDOMString & msg,const XalanNode * sourceNode)276 StylesheetExecutionContextDefault::problem(
277 eSource source,
278 eClassification classification,
279 const XalanDOMString& msg,
280 const XalanNode* sourceNode)
281 {
282 m_xsltProcessor->problem(
283 source,
284 classification,
285 msg,
286 sourceNode);
287 }
288
289
290
291 bool
getQuietConflictWarnings() const292 StylesheetExecutionContextDefault::getQuietConflictWarnings() const
293 {
294 assert(m_xsltProcessor != 0);
295
296 return m_xsltProcessor->getQuietConflictWarnings();
297 }
298
299
300
301 bool
getCopyTextNodesOnly() const302 StylesheetExecutionContextDefault::getCopyTextNodesOnly() const
303 {
304 if (m_copyTextNodesOnlyStack.size() == 0)
305 {
306 return false;
307 }
308 else
309 {
310 return m_copyTextNodesOnlyStack.back();
311 }
312 }
313
314
315
316
317
318 XalanNode*
getRootDocument() const319 StylesheetExecutionContextDefault::getRootDocument() const
320 {
321 return m_rootDocument;
322 }
323
324
325
326 void
setRootDocument(XalanNode * theDocument)327 StylesheetExecutionContextDefault::setRootDocument(XalanNode* theDocument)
328 {
329 m_rootDocument = theDocument;
330 }
331
332
333
334 void
setStylesheetRoot(const StylesheetRoot * theStylesheet)335 StylesheetExecutionContextDefault::setStylesheetRoot(const StylesheetRoot* theStylesheet)
336 {
337 assert(m_xsltProcessor != 0);
338
339 m_stylesheetRoot = theStylesheet;
340
341 m_hasPreserveOrStripConditions = theStylesheet->hasPreserveOrStripSpaceElements();
342
343 m_xsltProcessor->setStylesheetRoot(theStylesheet);
344
345 if (theStylesheet == 0)
346 {
347 m_xsltProcessor->setExecutionContext(0);
348 }
349 else
350 {
351 m_xsltProcessor->setExecutionContext(this);
352
353 m_countersTable.resize(theStylesheet->getElemNumberCount());
354 }
355 }
356
357
358
359 const XalanQName*
getCurrentMode() const360 StylesheetExecutionContextDefault::getCurrentMode() const
361 {
362 if (m_modeStack.size() == 0)
363 {
364 return 0;
365 }
366 else
367 {
368 return m_modeStack.back();
369 }
370 }
371
372
373
374 void
pushCurrentMode(const XalanQName * theMode)375 StylesheetExecutionContextDefault::pushCurrentMode(const XalanQName* theMode)
376 {
377 m_modeStack.push_back(theMode);
378 }
379
380
381
382 void
popCurrentMode()383 StylesheetExecutionContextDefault::popCurrentMode()
384 {
385 m_modeStack.pop_back();
386 }
387
388
389
390
391 const ElemTemplate*
getCurrentTemplate() const392 StylesheetExecutionContextDefault::getCurrentTemplate() const
393 {
394 return m_currentTemplateStack.back();
395 }
396
397
398
399 void
pushCurrentTemplate(const ElemTemplate * theTemplate)400 StylesheetExecutionContextDefault::pushCurrentTemplate(const ElemTemplate* theTemplate)
401 {
402 m_currentTemplateStack.push_back(theTemplate);
403 }
404
405
406
407 void
popCurrentTemplate()408 StylesheetExecutionContextDefault::popCurrentTemplate()
409 {
410 m_currentTemplateStack.pop_back();
411 }
412
413
414
415 bool
isElementPending() const416 StylesheetExecutionContextDefault::isElementPending() const
417 {
418 assert(m_xsltProcessor != 0);
419
420 return m_xsltProcessor->isElementPending();
421 }
422
423
424
425 void
replacePendingAttribute(const XalanDOMChar * theName,const XalanDOMChar * theNewType,const XalanDOMChar * theNewValue)426 StylesheetExecutionContextDefault::replacePendingAttribute(
427 const XalanDOMChar* theName,
428 const XalanDOMChar* theNewType,
429 const XalanDOMChar* theNewValue)
430 {
431 assert(m_xsltProcessor != 0);
432
433 // Remove the old attribute, then add the new one. AttributeListImpl::addAttribute()
434 // does this for us.
435 m_xsltProcessor->replacePendingAttribute(theName, theNewType, theNewValue);
436 }
437
438
439
440 void
pushOutputContext(FormatterListener * flistener)441 StylesheetExecutionContextDefault::pushOutputContext(FormatterListener* flistener)
442 {
443 assert(m_xsltProcessor != 0);
444
445 m_xsltProcessor->pushOutputContext(flistener);
446 }
447
448
449
450 void
popOutputContext()451 StylesheetExecutionContextDefault::popOutputContext()
452 {
453 assert(m_xsltProcessor != 0);
454
455 m_xsltProcessor->popOutputContext();
456 }
457
458
459
460 void
addResultAttribute(const XalanDOMString & aname,const XalanDOMString & value)461 StylesheetExecutionContextDefault::addResultAttribute(
462 const XalanDOMString& aname,
463 const XalanDOMString& value)
464 {
465 assert(m_xsltProcessor != 0);
466
467 m_xsltProcessor->addResultAttribute(aname, value);
468 }
469
470
471
472 void
addResultAttribute(const XalanDOMString & aname,const XalanDOMChar * value)473 StylesheetExecutionContextDefault::addResultAttribute(
474 const XalanDOMString& aname,
475 const XalanDOMChar* value)
476 {
477 assert(m_xsltProcessor != 0);
478
479 m_xsltProcessor->addResultAttribute(aname, value);
480 }
481
482
483
484 void
copyNamespaceAttributes(const XalanNode & src)485 StylesheetExecutionContextDefault::copyNamespaceAttributes(const XalanNode& src)
486 {
487 assert(m_xsltProcessor != 0);
488
489 m_xsltProcessor->copyNamespaceAttributes(src);
490 }
491
492
493
494 const XalanDOMString*
getResultPrefixForNamespace(const XalanDOMString & theNamespace) const495 StylesheetExecutionContextDefault::getResultPrefixForNamespace(const XalanDOMString& theNamespace) const
496 {
497 assert(m_xsltProcessor != 0);
498
499 return m_xsltProcessor->getResultPrefixForNamespace(theNamespace);
500 }
501
502
503
504 const XalanDOMString*
getResultNamespaceForPrefix(const XalanDOMString & thePrefix) const505 StylesheetExecutionContextDefault::getResultNamespaceForPrefix(const XalanDOMString& thePrefix) const
506 {
507 assert(m_xsltProcessor != 0);
508
509 return m_xsltProcessor->getResultNamespaceForPrefix(thePrefix);
510 }
511
512
513
514 bool
isPendingResultPrefix(const XalanDOMString & thePrefix)515 StylesheetExecutionContextDefault::isPendingResultPrefix(const XalanDOMString& thePrefix)
516 {
517 assert(m_xsltProcessor != 0);
518
519 return m_xsltProcessor->isPendingResultPrefix(thePrefix);
520 }
521
522
523 void
getUniqueNamespaceValue(XalanDOMString & theValue) const524 StylesheetExecutionContextDefault::getUniqueNamespaceValue(XalanDOMString& theValue) const
525 {
526 assert(m_xsltProcessor != 0);
527
528 m_xsltProcessor->getUniqueNamespaceValue(theValue);
529 }
530
531
532
533 FormatterListener*
getFormatterListener() const534 StylesheetExecutionContextDefault::getFormatterListener() const
535 {
536 assert(m_xsltProcessor != 0);
537
538 return m_xsltProcessor->getFormatterListener();
539 }
540
541
542
543 void
setFormatterListener(FormatterListener * flistener)544 StylesheetExecutionContextDefault::setFormatterListener(FormatterListener* flistener)
545 {
546 assert(m_xsltProcessor != 0);
547
548 m_xsltProcessor->setFormatterListener(flistener);
549 }
550
551
552
553 int
getIndent() const554 StylesheetExecutionContextDefault::getIndent() const
555 {
556 if (m_indentAmount != -1)
557 {
558 return m_indentAmount;
559 }
560 else
561 {
562 assert(m_xsltProcessor != 0);
563
564 return m_xsltProcessor->getXMLParserLiaison().getIndent();
565 }
566 }
567
568
569
570 void
setIndent(int indentAmount)571 StylesheetExecutionContextDefault::setIndent(int indentAmount)
572 {
573 m_indentAmount = indentAmount;
574 }
575
576
577
578 const XPath*
createMatchPattern(const XalanDOMString & str,const PrefixResolver & resolver)579 StylesheetExecutionContextDefault::createMatchPattern(
580 const XalanDOMString& str,
581 const PrefixResolver& resolver)
582 {
583 assert(m_xsltProcessor != 0);
584
585 const XPath* theResult = 0;
586
587 // We won't cache any xpath that has a namespace, since
588 // we have no idea how that might be resolved. We could
589 // enhance XPath so that we can tell if str would match
590 // the XPath, once the namespace is resolved, but it may
591 // not be worth it...
592 const XalanDOMString::size_type index = indexOf(str, XalanUnicode::charColon);
593 const XalanDOMString::size_type len = str.length();
594
595 // If we found a ':' before the end of the string, and
596 // it's by itself (:: would indicate an axis), don't
597 // try to cache the XPath...
598 if (index < len - 1 && str[index + 1] != XalanUnicode::charColon)
599 {
600 theResult = m_xsltProcessor->createMatchPattern(str, resolver);
601 }
602 else
603 {
604 const XPathCacheMapType::iterator i =
605 m_matchPatternCache.find(str);
606
607 if (i != m_matchPatternCache.end())
608 {
609 // Update hit time...
610 (*i).second.second = std::clock();
611
612 theResult = (*i).second.first;
613 }
614 else
615 {
616 theResult = m_xsltProcessor->createMatchPattern(str, resolver);
617
618 addToXPathCache(str, theResult);
619 }
620 }
621
622 return theResult;
623 }
624
625
626
627 void
returnXPath(const XPath * xpath)628 StylesheetExecutionContextDefault::returnXPath(const XPath* xpath)
629 {
630 assert(m_xsltProcessor != 0);
631
632 if (isCached(xpath) == false)
633 {
634 m_xsltProcessor->returnXPath(xpath);
635 }
636 }
637
638
639
640 void
pushTopLevelVariables(const ParamVectorType & topLevelParams)641 StylesheetExecutionContextDefault::pushTopLevelVariables(const ParamVectorType& topLevelParams)
642 {
643 assert(m_stylesheetRoot != 0);
644
645 m_stylesheetRoot->pushTopLevelVariables(*this, topLevelParams);
646 }
647
648
649
650 const XObjectPtr
createVariable(const XPath & xpath,XalanNode * contextNode,const PrefixResolver & resolver)651 StylesheetExecutionContextDefault::createVariable(
652 const XPath& xpath,
653 XalanNode* contextNode,
654 const PrefixResolver& resolver)
655 {
656 XalanNode* const theCurrentNode = getCurrentNode();
657
658 if (theCurrentNode == contextNode)
659 {
660 return xpath.execute(resolver, *this);
661 }
662 else
663 {
664 return xpath.execute(contextNode, resolver, *this);
665 }
666 }
667
668
669 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
670 const XObjectPtr
createVariable(const ElemTemplateElement & templateChild,XalanNode * sourceNode)671 StylesheetExecutionContextDefault::createVariable(
672 const ElemTemplateElement& templateChild,
673 XalanNode* sourceNode)
674 {
675 return createXResultTreeFrag(templateChild, sourceNode);
676 }
677 #endif
678
679
680
681 void
pushVariable(const XalanQName & name,const ElemTemplateElement * element,const XalanDOMString & str,XalanNode * contextNode,const PrefixResolver & resolver)682 StylesheetExecutionContextDefault::pushVariable(
683 const XalanQName& name,
684 const ElemTemplateElement* element,
685 const XalanDOMString& str,
686 XalanNode* contextNode,
687 const PrefixResolver& resolver)
688 {
689 assert(m_xsltProcessor != 0);
690
691 if (str.empty() == false)
692 {
693 m_variablesStack.pushVariable(
694 name,
695 m_xsltProcessor->evalXPathStr(
696 str,
697 contextNode,
698 resolver,
699 *this),
700 element);
701 }
702 }
703
704
705
706 void
pushVariable(const XalanQName & name,const XObjectPtr val,const ElemTemplateElement * element)707 StylesheetExecutionContextDefault::pushVariable(
708 const XalanQName& name,
709 const XObjectPtr val,
710 const ElemTemplateElement* element)
711 {
712 m_variablesStack.pushVariable(name, val, element);
713 }
714
715
716
717 void
pushVariable(const XalanQName & name,const ElemVariable * var,const ElemTemplateElement * element)718 StylesheetExecutionContextDefault::pushVariable(
719 const XalanQName& name,
720 const ElemVariable* var,
721 const ElemTemplateElement* element)
722 {
723 m_variablesStack.pushVariable(name, var, element);
724 }
725
726
727
728 void
pushVariable(const XalanQName & name,const ElemTemplateElement * element,const XPath & xpath,XalanNode * contextNode,const PrefixResolver & resolver)729 StylesheetExecutionContextDefault::pushVariable(
730 const XalanQName& name,
731 const ElemTemplateElement* element,
732 const XPath& xpath,
733 XalanNode* contextNode,
734 const PrefixResolver& resolver)
735 {
736 m_variablesStack.pushVariable(name, xpath.execute(contextNode, resolver, *this), element);
737 }
738
739
740
741 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
742 void
pushVariable(const XalanQName & name,const ElemTemplateElement * element,const ElemTemplateElement & templateChild,XalanNode * sourceNode)743 StylesheetExecutionContextDefault::pushVariable(
744 const XalanQName& name,
745 const ElemTemplateElement* element,
746 const ElemTemplateElement& templateChild,
747 XalanNode* sourceNode)
748 {
749
750 m_variablesStack.pushVariable(name, createXResultTreeFrag(templateChild, sourceNode), element);
751 }
752 #endif
753
754
755
756 void
pushContextMarker()757 StylesheetExecutionContextDefault::pushContextMarker()
758 {
759 m_variablesStack.pushContextMarker();
760 }
761
762
763
764 void
popContextMarker()765 StylesheetExecutionContextDefault::popContextMarker()
766 {
767 m_variablesStack.popContextMarker();
768 }
769
770
771
772 void
resolveTopLevelParams()773 StylesheetExecutionContextDefault::resolveTopLevelParams()
774 {
775 assert(m_xsltProcessor != 0);
776
777 m_xsltProcessor->resolveTopLevelParams(*this);
778
779 m_variablesStack.markGlobalStackFrame();
780 }
781
782
783
784 void
clearTopLevelParams()785 StylesheetExecutionContextDefault::clearTopLevelParams()
786 {
787 assert(m_xsltProcessor != 0);
788
789 m_xsltProcessor->clearTopLevelParams();
790
791 m_variablesStack.unmarkGlobalStackFrame();
792 }
793
794
795
796 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
797 void
beginParams()798 StylesheetExecutionContextDefault::beginParams()
799 {
800 m_paramsVectorStack.resize(m_paramsVectorStack.size() + 1);
801 }
802
803
804
805 void
endParams()806 StylesheetExecutionContextDefault::endParams()
807 {
808 assert(m_paramsVectorStack.size() > 0);
809
810 m_variablesStack.pushParams(m_paramsVectorStack.back());
811
812 m_paramsVectorStack.pop_back();
813 }
814
815
816
817 void
pushParam(const XalanQName & qName,const XObjectPtr & theValue)818 StylesheetExecutionContextDefault::pushParam(
819 const XalanQName& qName,
820 const XObjectPtr& theValue)
821 {
822 assert(m_paramsVectorStack.empty() == false);
823
824 ParamsVectorType& currentParamVector = m_paramsVectorStack.back();
825
826 currentParamVector.push_back(ParamsVectorType::value_type(&qName, theValue));
827 }
828 #endif
829
830
831 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
832 void
pushParams(const ElemTemplateElement & xslCallTemplateElement)833 StylesheetExecutionContextDefault::pushParams(const ElemTemplateElement& xslCallTemplateElement)
834 {
835
836 // We have a params vector that we reuse, but occasionally, a
837 // param will result in recursive execution, so we'll use a
838 // temporary when we detect such a situation.
839 if(m_paramsVector.empty() == true)
840 {
841 // This will ensure that the contents of m_paramsVector are
842 // cleared.
843 CollectionClearGuard<ParamsVectorType> theGuard(m_paramsVector);
844
845 // Make sure we have the default capacity for the params
846 // vector...
847 if (m_paramsVector.capacity() == 0)
848 {
849 m_paramsVector.reserve(eDefaultParamsVectorSize);
850 }
851
852 getParams(xslCallTemplateElement, m_paramsVector);
853
854 m_variablesStack.pushParams(m_paramsVector);
855 }
856 else
857 {
858 ParamsVectorType tempParams(getMemoryManager());
859
860 getParams(xslCallTemplateElement, tempParams);
861
862 m_variablesStack.pushParams(tempParams);
863 }
864 }
865 #endif
866
867
868
869 const XObjectPtr
getParamVariable(const XalanQName & theName)870 StylesheetExecutionContextDefault::getParamVariable(const XalanQName& theName)
871 {
872 bool fFound;
873
874 return m_variablesStack.getParamVariable(theName, *this, fFound);
875 }
876
877
878
879 void
pushElementFrame(const ElemTemplateElement * elem)880 StylesheetExecutionContextDefault::pushElementFrame(const ElemTemplateElement* elem)
881 {
882 m_variablesStack.pushElementFrame(elem);
883 }
884
885
886
887 void
popElementFrame()888 StylesheetExecutionContextDefault::popElementFrame()
889 {
890 m_variablesStack.popElementFrame();
891 }
892
893
894
895 int
getGlobalStackFrameIndex() const896 StylesheetExecutionContextDefault::getGlobalStackFrameIndex() const
897 {
898 return m_variablesStack.getGlobalStackFrameIndex();
899 }
900
901
902
903 int
getCurrentStackFrameIndex() const904 StylesheetExecutionContextDefault::getCurrentStackFrameIndex() const
905 {
906 return m_variablesStack.getCurrentStackFrameIndex();
907 }
908
909
910
911
912 void
pushCurrentStackFrameIndex(int currentStackFrameIndex)913 StylesheetExecutionContextDefault::pushCurrentStackFrameIndex(int currentStackFrameIndex)
914 {
915 m_currentIndexStack.push_back(getCurrentStackFrameIndex());
916 m_variablesStack.setCurrentStackFrameIndex(currentStackFrameIndex);
917
918 }
919
920
921
922 void
popCurrentStackFrameIndex()923 StylesheetExecutionContextDefault::popCurrentStackFrameIndex()
924 {
925 assert (m_currentIndexStack.size() > 0);
926
927 int previousStackFrameIndex = m_currentIndexStack.back();
928
929 m_currentIndexStack.pop_back();
930
931 m_variablesStack.setCurrentStackFrameIndex(previousStackFrameIndex);
932 }
933
934 void
startDocument()935 StylesheetExecutionContextDefault::startDocument()
936 {
937 assert(m_xsltProcessor != 0);
938
939 m_xsltProcessor->startDocument();
940 }
941
942
943
944 void
endDocument()945 StylesheetExecutionContextDefault::endDocument()
946 {
947 assert(m_xsltProcessor != 0);
948
949 m_xsltProcessor->endDocument();
950
951 cleanUpTransients();
952
953 setFormatterListener(0);
954 }
955
956
957
958 void
characters(const XalanDOMChar * ch,fl_size_type start,fl_size_type length)959 StylesheetExecutionContextDefault::characters(
960 const XalanDOMChar* ch,
961 fl_size_type start,
962 fl_size_type length)
963 {
964 assert(m_xsltProcessor != 0);
965
966 m_xsltProcessor->characters(ch, start, length);
967 }
968
969
970
971 void
charactersRaw(const XalanDOMChar * ch,fl_size_type start,fl_size_type length)972 StylesheetExecutionContextDefault::charactersRaw(
973 const XalanDOMChar* ch,
974 fl_size_type start,
975 fl_size_type length)
976 {
977 assert(m_xsltProcessor != 0);
978
979 m_xsltProcessor->charactersRaw(ch, start, length);
980 }
981
982
983
984 void
comment(const XalanDOMChar * data)985 StylesheetExecutionContextDefault::comment(const XalanDOMChar* data)
986 {
987 assert(m_xsltProcessor != 0);
988
989 m_xsltProcessor->comment(data);
990 }
991
992
993
994 void
processingInstruction(const XalanDOMChar * target,const XalanDOMChar * data)995 StylesheetExecutionContextDefault::processingInstruction(
996 const XalanDOMChar* target,
997 const XalanDOMChar* data)
998 {
999 assert(m_xsltProcessor != 0);
1000
1001 m_xsltProcessor->processingInstruction(target, data);
1002 }
1003
1004
1005
1006 void
startElement(const XalanDOMChar * name)1007 StylesheetExecutionContextDefault::startElement(const XalanDOMChar* name)
1008 {
1009 assert(m_xsltProcessor != 0);
1010
1011 m_xsltProcessor->startElement(name);
1012 }
1013
1014
1015
1016 void
endElement(const XalanDOMChar * name)1017 StylesheetExecutionContextDefault::endElement(const XalanDOMChar* name)
1018 {
1019 assert(m_xsltProcessor != 0);
1020
1021 m_xsltProcessor->endElement(name);
1022 }
1023
1024
1025
1026 void
flushPending()1027 StylesheetExecutionContextDefault::flushPending()
1028 {
1029 assert(m_xsltProcessor != 0);
1030
1031 m_xsltProcessor->flushPending();
1032 }
1033
1034
1035
1036 void
cloneToResultTree(const XalanNode & node,const Locator * locator)1037 StylesheetExecutionContextDefault::cloneToResultTree(
1038 const XalanNode& node,
1039 const Locator* locator)
1040 {
1041 m_xsltProcessor->cloneToResultTree(node, getCopyTextNodesOnly(), locator);
1042 }
1043
1044
1045
1046 void
cloneToResultTree(const XalanNode & node,XalanNode::NodeType nodeType,bool overrideStrip,bool shouldCloneAttributes,const Locator * locator)1047 StylesheetExecutionContextDefault::cloneToResultTree(
1048 const XalanNode& node,
1049 XalanNode::NodeType nodeType,
1050 bool overrideStrip,
1051 bool shouldCloneAttributes,
1052 const Locator* locator)
1053 {
1054 assert(m_xsltProcessor != 0);
1055
1056 m_xsltProcessor->cloneToResultTree(
1057 node,
1058 nodeType,
1059 overrideStrip,
1060 shouldCloneAttributes,
1061 getCopyTextNodesOnly(),
1062 locator);
1063 }
1064
1065
1066 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
1067 void
beginCreateXResultTreeFrag(XalanNode * sourceNode)1068 StylesheetExecutionContextDefault::beginCreateXResultTreeFrag(XalanNode* sourceNode)
1069 {
1070 assert(m_xsltProcessor != 0);
1071
1072 XalanSourceTreeDocument* const theDocument = m_usePerInstanceDocumentFactory == true ?
1073 m_documentAllocator.create(
1074 eDefaultAttributeAllocatorBlockSize,
1075 eDefaultAttributeNSAllocatorBlockSize,
1076 eDefaultCommentAllocatorBlockSize,
1077 eDefaultElementAllocatorBlockSize,
1078 eDefaultElementNSAllocatorBlockSize,
1079 eDefaultPIAllocatorBlockSize,
1080 eDefaultTextAllocatorBlockSize,
1081 eDefaultTextIWSAllocatorBlockSize) :
1082 getSourceTreeFactory(getMemoryManager());
1083 assert(theDocument != 0);
1084
1085 XalanSourceTreeDocumentFragment* const theDocumentFragment =
1086 m_documentFragmentAllocator.create(*theDocument);
1087 assert(theDocumentFragment != 0);
1088
1089 FormatterToSourceTree* const theFormatter = m_formatterToSourceTreeStack.get();
1090 assert(theFormatter != 0);
1091
1092 theFormatter->setDocument(theDocument);
1093
1094 theFormatter->setDocumentFragment(theDocumentFragment);
1095
1096 theFormatter->setPrefixResolver(m_xsltProcessor);
1097
1098 pushOutputContext(theFormatter);
1099
1100 theFormatter->startDocument();
1101
1102 pushCurrentNode(sourceNode);
1103 }
1104
1105
1106
1107 const XObjectPtr
endCreateXResultTreeFrag()1108 StylesheetExecutionContextDefault::endCreateXResultTreeFrag()
1109 {
1110 FormatterToSourceTree* const theFormatter =
1111 m_formatterToSourceTreeStack.top();
1112
1113 assert (theFormatter != 0);
1114
1115 theFormatter->endDocument();
1116
1117 XalanSourceTreeDocumentFragment* const theDocumentFragment =
1118 theFormatter->getDocumentFragment();
1119
1120 assert(theDocumentFragment != 0);
1121
1122 XResultTreeFrag* const theXResultTreeFrag =
1123 m_xresultTreeFragAllocator.create(*theDocumentFragment);
1124
1125 theXResultTreeFrag->setExecutionContext(this);
1126
1127 popCurrentNode();
1128 popOutputContext();
1129
1130 m_formatterToSourceTreeStack.release();
1131
1132 return XObjectPtr(theXResultTreeFrag);
1133 }
1134 #endif
1135
1136
1137
1138 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
1139 const XObjectPtr
createXResultTreeFrag(const ElemTemplateElement & templateChild,XalanNode * sourceNode)1140 StylesheetExecutionContextDefault::createXResultTreeFrag(
1141 const ElemTemplateElement& templateChild,
1142 XalanNode* sourceNode)
1143 {
1144 assert(m_xsltProcessor != 0);
1145
1146 XalanSourceTreeDocument* const theDocument = m_usePerInstanceDocumentFactory == true ?
1147 m_documentAllocator.create(
1148 eDefaultAttributeAllocatorBlockSize,
1149 eDefaultAttributeNSAllocatorBlockSize,
1150 eDefaultCommentAllocatorBlockSize,
1151 eDefaultElementAllocatorBlockSize,
1152 eDefaultElementNSAllocatorBlockSize,
1153 eDefaultPIAllocatorBlockSize,
1154 eDefaultTextAllocatorBlockSize,
1155 eDefaultTextIWSAllocatorBlockSize) :
1156 getSourceTreeFactory(getMemoryManager());
1157 assert(theDocument != 0);
1158
1159 XalanSourceTreeDocumentFragment* const theDocumentFragment =
1160 m_documentFragmentAllocator.create(*theDocument);
1161 assert(theDocumentFragment != 0);
1162
1163 GuardCachedObject<FormatterToSourceTreeCacheType> theGuard(m_formatterToSourceTreeCache);
1164
1165 FormatterToSourceTree* const theFormatter = theGuard.get();
1166 assert(theFormatter != 0);
1167
1168 theFormatter->setDocument(theDocument);
1169
1170 theFormatter->setDocumentFragment(theDocumentFragment);
1171
1172 theFormatter->setPrefixResolver(m_xsltProcessor);
1173
1174 StylesheetExecutionContext::OutputContextPushPop theOutputContextPushPop(
1175 *this,
1176 theFormatter);
1177
1178 theFormatter->startDocument();
1179
1180 templateChild.executeChildren(*this, sourceNode);
1181
1182 theFormatter->endDocument();
1183
1184 XResultTreeFrag* const theXResultTreeFrag =
1185 m_xresultTreeFragAllocator.create(*theDocumentFragment);
1186
1187 theXResultTreeFrag->setExecutionContext(this);
1188
1189 return XObjectPtr(theXResultTreeFrag);
1190 }
1191 #endif
1192
1193
1194
1195 void
outputToResultTree(const XObject & xobj,const Locator * locator)1196 StylesheetExecutionContextDefault::outputToResultTree(
1197 const XObject& xobj,
1198 const Locator* locator)
1199 {
1200 assert(m_xsltProcessor != 0);
1201
1202 m_xsltProcessor->outputToResultTree(xobj, getCopyTextNodesOnly(), locator);
1203 }
1204
1205
1206
1207 void
outputResultTreeFragment(const XObject & theTree,const Locator * locator)1208 StylesheetExecutionContextDefault::outputResultTreeFragment(
1209 const XObject& theTree,
1210 const Locator* locator)
1211 {
1212 assert(m_xsltProcessor != 0);
1213
1214 m_xsltProcessor->outputResultTreeFragment(theTree, getCopyTextNodesOnly(), locator);
1215 }
1216
1217
1218
1219 const XalanDOMString&
getXSLNameSpaceURL() const1220 StylesheetExecutionContextDefault::getXSLNameSpaceURL() const
1221 {
1222 assert(m_xsltProcessor != 0);
1223
1224 return m_xsltProcessor->getXSLNameSpaceURL();
1225 }
1226
1227
1228
1229 const XalanDOMString&
getXalanXSLNameSpaceURL() const1230 StylesheetExecutionContextDefault::getXalanXSLNameSpaceURL() const
1231 {
1232 assert(m_xsltProcessor != 0);
1233
1234 return m_xsltProcessor->getXalanXSLNameSpaceURL();
1235 }
1236
1237
1238
1239 bool
getTraceSelects() const1240 StylesheetExecutionContextDefault::getTraceSelects() const
1241 {
1242 assert(m_xsltProcessor != 0);
1243
1244 return m_xsltProcessor->getTraceSelects();
1245 }
1246
1247
1248
1249 void
traceSelect(const ElemTemplateElement & theTemplate,const NodeRefListBase & nl,const XPath * xpath)1250 StylesheetExecutionContextDefault::traceSelect(
1251 const ElemTemplateElement& theTemplate,
1252 const NodeRefListBase& nl,
1253 const XPath* xpath)
1254 {
1255 assert(m_xsltProcessor != 0);
1256
1257 m_xsltProcessor->traceSelect(*this, theTemplate, nl, xpath);
1258 }
1259
1260
1261
1262 bool
findOnElementRecursionStack(const ElemTemplateElement * theElement) const1263 StylesheetExecutionContextDefault::findOnElementRecursionStack(const ElemTemplateElement* theElement) const
1264 {
1265 assert(theElement != 0);
1266
1267 using std::find;
1268
1269 const ElementTemplateElementStackType::const_iterator i =
1270 find(m_elementRecursionStack.begin(),
1271 m_elementRecursionStack.end(),
1272 theElement);
1273
1274 return i == m_elementRecursionStack.end() ? false : true;
1275 }
1276
1277
1278
1279 void
pushOnElementRecursionStack(const ElemTemplateElement * theElement)1280 StylesheetExecutionContextDefault::pushOnElementRecursionStack(const ElemTemplateElement* theElement)
1281 {
1282 assert(theElement != 0);
1283
1284 if (findOnElementRecursionStack(theElement) == true)
1285 {
1286 const Locator* const theLocator = theElement->getLocator();
1287
1288 const GetCachedString theGuard(*this);
1289
1290 throw XSLTProcessorException(
1291 getMemoryManager(),
1292 XalanMessageLoader::getMessage(
1293 theGuard.get(),
1294 XalanMessages::InfiniteRecursion_1Param,
1295 theElement->getElementName()),
1296 theLocator);
1297 }
1298
1299 m_elementRecursionStack.push_back(theElement);
1300 }
1301
1302
1303
1304 const ElemTemplateElement*
popElementRecursionStack()1305 StylesheetExecutionContextDefault::popElementRecursionStack()
1306 {
1307 assert(m_elementRecursionStack.empty() == false);
1308
1309 const ElemTemplateElement* const theTemp =
1310 m_elementRecursionStack.back();
1311
1312 m_elementRecursionStack.pop_back();
1313
1314 return theTemp;
1315 }
1316
1317
1318
1319 bool
returnXResultTreeFrag(XResultTreeFrag * theXResultTreeFrag)1320 StylesheetExecutionContextDefault::returnXResultTreeFrag(XResultTreeFrag* theXResultTreeFrag)
1321 {
1322 assert(theXResultTreeFrag != 0);
1323
1324 if (m_xresultTreeFragAllocator.ownsObject(theXResultTreeFrag) == false)
1325 {
1326 return false;
1327 }
1328 else
1329 {
1330 XalanDocumentFragment* const theDocumentFragment =
1331 theXResultTreeFrag->release();
1332
1333 const KeyTablesTableType::iterator i =
1334 m_keyTables.find(theDocumentFragment);
1335
1336 if (i != m_keyTables.end())
1337 {
1338 KeyTable* const theTable = (*i).second;
1339
1340 m_keyTables.erase(i);
1341
1342 theTable->~KeyTable();
1343
1344 m_keyTables.getMemoryManager().deallocate((void*)theTable);
1345 }
1346
1347 m_xresultTreeFragAllocator.destroy(theXResultTreeFrag);
1348
1349 if (m_usePerInstanceDocumentFactory == true)
1350 {
1351 m_documentAllocator.destroy(static_cast<XalanSourceTreeDocument*>(theDocumentFragment->getOwnerDocument()));
1352 }
1353
1354 m_documentFragmentAllocator.destroy(static_cast<XalanSourceTreeDocumentFragment*>(theDocumentFragment));
1355
1356 return true;
1357 }
1358 }
1359
1360
1361
1362 StylesheetExecutionContextDefault::eEscapeURLs
getEscapeURLs() const1363 StylesheetExecutionContextDefault::getEscapeURLs() const
1364 {
1365 return m_escapeURLs;
1366 }
1367
1368
1369
1370 void
setEscapeURLs(eEscapeURLs value)1371 StylesheetExecutionContextDefault::setEscapeURLs(eEscapeURLs value)
1372 {
1373 m_escapeURLs = value;
1374 }
1375
1376
1377
1378 StylesheetExecutionContextDefault::eOmitMETATag
getOmitMETATag() const1379 StylesheetExecutionContextDefault::getOmitMETATag() const
1380 {
1381 return m_omitMETATag;
1382 }
1383
1384
1385
1386 void
setOmitMETATag(eOmitMETATag value)1387 StylesheetExecutionContextDefault::setOmitMETATag(eOmitMETATag value)
1388 {
1389 m_omitMETATag = value;
1390 }
1391
1392
1393
1394 FormatterListener*
createFormatterToXML(Writer & writer,const XalanDOMString & version,bool doIndent,int indent,const XalanDOMString & encoding,const XalanDOMString & mediaType,const XalanDOMString & doctypeSystem,const XalanDOMString & doctypePublic,bool xmlDecl,const XalanDOMString & standalone)1395 StylesheetExecutionContextDefault::createFormatterToXML(
1396 Writer& writer,
1397 const XalanDOMString& version,
1398 bool doIndent,
1399 int indent,
1400 const XalanDOMString& encoding,
1401 const XalanDOMString& mediaType,
1402 const XalanDOMString& doctypeSystem,
1403 const XalanDOMString& doctypePublic,
1404 bool xmlDecl,
1405 const XalanDOMString& standalone)
1406 {
1407 m_formatterListeners.push_back(0);
1408
1409 FormatterListener* const theFormatterListener =
1410 XalanXMLSerializerFactory::create(
1411 getMemoryManager(),
1412 writer,
1413 version,
1414 doIndent,
1415 indent,
1416 encoding,
1417 mediaType,
1418 doctypeSystem,
1419 doctypePublic,
1420 xmlDecl,
1421 standalone);
1422 assert(theFormatterListener != 0);
1423
1424 m_formatterListeners.back() = theFormatterListener;
1425
1426 return theFormatterListener;
1427 }
1428
1429
1430
1431 FormatterListener*
createFormatterToHTML(Writer & writer,const XalanDOMString & encoding,const XalanDOMString & mediaType,const XalanDOMString & doctypeSystem,const XalanDOMString & doctypePublic,bool doIndent,int indent,bool escapeURLs,bool omitMetaTag)1432 StylesheetExecutionContextDefault::createFormatterToHTML(
1433 Writer& writer,
1434 const XalanDOMString& encoding,
1435 const XalanDOMString& mediaType,
1436 const XalanDOMString& doctypeSystem,
1437 const XalanDOMString& doctypePublic,
1438 bool doIndent,
1439 int indent,
1440 bool escapeURLs,
1441 bool omitMetaTag)
1442 {
1443 m_formatterListeners.push_back(0);
1444
1445 FormatterToHTML* const theFormatter =
1446 FormatterToHTML::create(
1447 getMemoryManager(),
1448 writer,
1449 encoding,
1450 mediaType,
1451 doctypeSystem,
1452 doctypePublic,
1453 doIndent,
1454 indent,
1455 escapeURLs,
1456 omitMetaTag);
1457
1458 m_formatterListeners.back() = theFormatter;
1459
1460 theFormatter->setPrefixResolver(m_xsltProcessor);
1461
1462 return theFormatter;
1463 }
1464
1465
1466
1467 FormatterListener*
createFormatterToText(Writer & writer,const XalanDOMString & encoding)1468 StylesheetExecutionContextDefault::createFormatterToText(
1469 Writer& writer,
1470 const XalanDOMString& encoding)
1471 {
1472 m_formatterListeners.push_back(0);
1473
1474 FormatterToText* const theFormatter =
1475 FormatterToText::create(getMemoryManager(), writer, encoding);
1476
1477 m_formatterListeners.back() = theFormatter;
1478
1479 return theFormatter;
1480 }
1481
1482
1483 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
1484 FormatterToText*
borrowFormatterToText()1485 StylesheetExecutionContextDefault::borrowFormatterToText()
1486 {
1487 return m_formatterToTextCache.get();
1488 }
1489
1490
1491
1492 bool
returnFormatterToText(FormatterToText * theFormatter)1493 StylesheetExecutionContextDefault::returnFormatterToText(FormatterToText* theFormatter)
1494 {
1495 return m_formatterToTextCache.release(theFormatter);
1496 }
1497 #endif
1498
1499
1500
1501 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
1502 NodeSorter*
getNodeSorter()1503 StylesheetExecutionContextDefault::getNodeSorter()
1504 {
1505 return &m_nodeSorter;
1506 }
1507 #endif
1508
1509
1510 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
1511 NodeSorter*
borrowNodeSorter()1512 StylesheetExecutionContextDefault::borrowNodeSorter()
1513 {
1514 return m_nodeSorterCache.get();
1515 }
1516
1517
1518
1519 bool
returnNodeSorter(NodeSorter * theSorter)1520 StylesheetExecutionContextDefault::returnNodeSorter(NodeSorter* theSorter)
1521 {
1522 return m_nodeSorterCache.release(theSorter);
1523 }
1524 #endif
1525
1526
1527
1528 StylesheetExecutionContextDefault::XalanNumberFormatAutoPtr
createXalanNumberFormat()1529 StylesheetExecutionContextDefault::createXalanNumberFormat()
1530 {
1531 return XalanNumberFormatAutoPtr(getMemoryManager(), s_xalanNumberFormatFactory->create(getMemoryManager()));
1532 }
1533
1534
1535
XalanNumberFormatFactory()1536 StylesheetExecutionContextDefault::XalanNumberFormatFactory::XalanNumberFormatFactory()
1537 {
1538 }
1539
1540
1541
~XalanNumberFormatFactory()1542 StylesheetExecutionContextDefault::XalanNumberFormatFactory::~XalanNumberFormatFactory()
1543 {
1544 }
1545
1546
1547
1548 XalanNumberFormat*
create(MemoryManager & theManager)1549 StylesheetExecutionContextDefault::XalanNumberFormatFactory::create(MemoryManager& theManager)
1550 {
1551 return XalanNumberFormat::create(theManager);
1552 }
1553
1554
1555
1556 StylesheetExecutionContextDefault::XalanNumberFormatFactory*
installXalanNumberFormatFactory(XalanNumberFormatFactory * theFactory)1557 StylesheetExecutionContextDefault::installXalanNumberFormatFactory(XalanNumberFormatFactory* theFactory)
1558 {
1559 XalanNumberFormatFactory* const theOldFactory =
1560 s_xalanNumberFormatFactory;
1561
1562 if (theFactory == 0)
1563 {
1564 s_xalanNumberFormatFactory = &s_defaultXalanNumberFormatFactory;
1565 }
1566 else
1567 {
1568 s_xalanNumberFormatFactory = theFactory;
1569 }
1570
1571 return theOldFactory;
1572 }
1573
1574
1575
1576 int
collationCompare(const XalanDOMString & theLHS,const XalanDOMString & theRHS,XalanCollationServices::eCaseOrder theCaseOrder)1577 StylesheetExecutionContextDefault::collationCompare(
1578 const XalanDOMString& theLHS,
1579 const XalanDOMString& theRHS,
1580 XalanCollationServices::eCaseOrder theCaseOrder)
1581 {
1582 if (m_collationCompareFunctor == 0)
1583 {
1584 return s_defaultCollationFunctor(theLHS.c_str(), theRHS.c_str(), theCaseOrder);
1585 }
1586 else
1587 {
1588 return (*m_collationCompareFunctor)(theLHS.c_str(), theRHS.c_str(), theCaseOrder);
1589 }
1590 }
1591
1592
1593
1594 int
collationCompare(const XalanDOMString & theLHS,const XalanDOMString & theRHS,const XalanDOMString & theLocale,XalanCollationServices::eCaseOrder theCaseOrder)1595 StylesheetExecutionContextDefault::collationCompare(
1596 const XalanDOMString& theLHS,
1597 const XalanDOMString& theRHS,
1598 const XalanDOMString& theLocale,
1599 XalanCollationServices::eCaseOrder theCaseOrder)
1600 {
1601 if (m_collationCompareFunctor == 0)
1602 {
1603 return s_defaultCollationFunctor(theLHS.c_str(), theRHS.c_str(), theLocale.c_str(), theCaseOrder);
1604 }
1605 else
1606 {
1607 return (*m_collationCompareFunctor)(theLHS.c_str(), theRHS.c_str(), theLocale.c_str(), theCaseOrder);
1608 }
1609 }
1610
1611
1612
1613 int
collationCompare(const XalanDOMChar * theLHS,const XalanDOMChar * theRHS,XalanCollationServices::eCaseOrder theCaseOrder)1614 StylesheetExecutionContextDefault::collationCompare(
1615 const XalanDOMChar* theLHS,
1616 const XalanDOMChar* theRHS,
1617 XalanCollationServices::eCaseOrder theCaseOrder)
1618 {
1619 assert(theLHS != 0 && theRHS != 0);
1620
1621 if (m_collationCompareFunctor == 0)
1622 {
1623 return s_defaultCollationFunctor(theLHS, theRHS, theCaseOrder);
1624 }
1625 else
1626 {
1627 return (*m_collationCompareFunctor)(theLHS, theRHS, theCaseOrder);
1628 }
1629 }
1630
1631
1632
1633 int
collationCompare(const XalanDOMChar * theLHS,const XalanDOMChar * theRHS,const XalanDOMChar * theLocale,XalanCollationServices::eCaseOrder theCaseOrder)1634 StylesheetExecutionContextDefault::collationCompare(
1635 const XalanDOMChar* theLHS,
1636 const XalanDOMChar* theRHS,
1637 const XalanDOMChar* theLocale,
1638 XalanCollationServices::eCaseOrder theCaseOrder)
1639 {
1640 assert(theLHS != 0 && theRHS != 0);
1641
1642 if (m_collationCompareFunctor == 0)
1643 {
1644 return s_defaultCollationFunctor(theLHS, theRHS, theLocale, theCaseOrder);
1645 }
1646 else
1647 {
1648 return (*m_collationCompareFunctor)(theLHS, theRHS, theLocale, theCaseOrder);
1649 }
1650 }
1651
1652
1653
DefaultCollationCompareFunctor()1654 StylesheetExecutionContextDefault::DefaultCollationCompareFunctor::DefaultCollationCompareFunctor()
1655 {
1656 }
1657
1658
1659
~DefaultCollationCompareFunctor()1660 StylesheetExecutionContextDefault::DefaultCollationCompareFunctor::~DefaultCollationCompareFunctor()
1661 {
1662 }
1663
1664
1665
1666 int
operator ()(const XalanDOMChar * theLHS,const XalanDOMChar * theRHS,XalanCollationServices::eCaseOrder) const1667 StylesheetExecutionContextDefault::DefaultCollationCompareFunctor::operator()(
1668 const XalanDOMChar* theLHS,
1669 const XalanDOMChar* theRHS,
1670 XalanCollationServices::eCaseOrder /* theCaseOrder */) const
1671 {
1672 return xalanc::collationCompare(theLHS, theRHS);
1673 }
1674
1675
1676
1677 int
operator ()(const XalanDOMChar * theLHS,const XalanDOMChar * theRHS,const XalanDOMChar *,XalanCollationServices::eCaseOrder theCaseOrder) const1678 StylesheetExecutionContextDefault::DefaultCollationCompareFunctor::operator()(
1679 const XalanDOMChar* theLHS,
1680 const XalanDOMChar* theRHS,
1681 const XalanDOMChar* /* theLocale */,
1682 XalanCollationServices::eCaseOrder theCaseOrder) const
1683 {
1684 return (*this)(theLHS, theRHS, theCaseOrder);
1685 }
1686
1687
1688
1689 const StylesheetExecutionContextDefault::CollationCompareFunctor*
installCollationCompareFunctor(CollationCompareFunctor * theFunctor)1690 StylesheetExecutionContextDefault::installCollationCompareFunctor(CollationCompareFunctor* theFunctor)
1691 {
1692 assert(theFunctor != 0);
1693
1694 const CollationCompareFunctor* const temp = m_collationCompareFunctor;
1695
1696 m_collationCompareFunctor = theFunctor;
1697
1698 return temp;
1699 }
1700
1701
1702
1703 StylesheetExecutionContextDefault::CollationCompareFunctor*
uninstallCollationCompareFunctor()1704 StylesheetExecutionContextDefault::uninstallCollationCompareFunctor()
1705 {
1706 if (m_collationCompareFunctor == 0)
1707 {
1708 return 0;
1709 }
1710 else
1711 {
1712 CollationCompareFunctor* const temp = m_collationCompareFunctor;
1713
1714 m_collationCompareFunctor = 0;
1715
1716 return temp;
1717 }
1718 }
1719
1720
1721
1722 static const XalanQNameByValue theEmptyQName(XalanMemMgrs::getDummyMemMgr());
1723
1724
1725
1726 void
formatNumber(double number,const XalanDOMString & pattern,XalanDOMString & theResult,const XalanNode * context,const Locator * locator)1727 StylesheetExecutionContextDefault::formatNumber(
1728 double number,
1729 const XalanDOMString& pattern,
1730 XalanDOMString& theResult,
1731 const XalanNode* context,
1732 const Locator* locator)
1733 {
1734 const XalanDecimalFormatSymbols * theDFS = getDecimalFormatSymbols(theEmptyQName);
1735
1736 if (m_formatNumberFunctor == 0)
1737 {
1738 m_xpathExecutionContextDefault.doFormatNumber(
1739 number,
1740 pattern,
1741 theDFS,
1742 theResult,
1743 context,
1744 locator);
1745 }
1746 else
1747 {
1748 (*m_formatNumberFunctor)(
1749 *this,
1750 number,
1751 pattern,
1752 theDFS,
1753 theResult,
1754 context,
1755 locator);
1756 }
1757 }
1758
1759
1760
1761 void
formatNumber(double number,const XalanDOMString & pattern,const XalanDOMString & dfsName,XalanDOMString & theResult,const XalanNode * context,const Locator * locator)1762 StylesheetExecutionContextDefault::formatNumber(
1763 double number,
1764 const XalanDOMString& pattern,
1765 const XalanDOMString& dfsName,
1766 XalanDOMString& theResult,
1767 const XalanNode* context,
1768 const Locator* locator)
1769 {
1770 XalanQNameByValue& theDFSQName = m_xpathExecutionContextDefault.getScratchQName();
1771
1772 theDFSQName.set(dfsName, getPrefixResolver(), locator);
1773
1774 const XalanDecimalFormatSymbols* theDFS = getDecimalFormatSymbols(theDFSQName);
1775
1776 if (theDFS == 0)
1777 {
1778 const GetCachedString theGuard(*this);
1779
1780 problem(
1781 eXSLTProcessor,
1782 eWarning,
1783 XalanMessageLoader::getMessage(
1784 theGuard.get(),
1785 XalanMessages::Decimal_formatElementNotFound_1Param,
1786 "format-number()"),
1787 locator,
1788 context);
1789
1790 theDFS = getDecimalFormatSymbols(theEmptyQName);
1791
1792 }
1793
1794 if (m_formatNumberFunctor == 0)
1795 {
1796 m_xpathExecutionContextDefault.doFormatNumber(number,pattern,theDFS,theResult,context,locator);
1797 }
1798 else
1799 {
1800 (*m_formatNumberFunctor)(*this, number, pattern, theDFS, theResult, context, locator);
1801 }
1802 }
1803
1804
1805
1806 const StylesheetExecutionContextDefault::FormatNumberFunctor*
installFormatNumberFunctor(FormatNumberFunctor * theFunctor)1807 StylesheetExecutionContextDefault::installFormatNumberFunctor(FormatNumberFunctor* theFunctor)
1808 {
1809 assert(theFunctor != 0);
1810
1811 const FormatNumberFunctor * const temp = m_formatNumberFunctor;
1812
1813 m_formatNumberFunctor = theFunctor;
1814
1815 return temp;
1816 }
1817
1818
1819
1820 StylesheetExecutionContextDefault::FormatNumberFunctor*
uninstallFormatNumberFunctor()1821 StylesheetExecutionContextDefault::uninstallFormatNumberFunctor()
1822 {
1823 if (m_formatNumberFunctor == 0)
1824 {
1825 return 0;
1826 }
1827 else
1828 {
1829 FormatNumberFunctor * const temp = m_formatNumberFunctor;
1830
1831 m_formatNumberFunctor = 0;
1832
1833 return temp;
1834 }
1835 }
1836
1837
1838
1839 void
reset()1840 StylesheetExecutionContextDefault::reset()
1841 {
1842 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
1843 assert(m_elementRecursionStack.empty() == true);
1844 #endif
1845
1846 m_variablesStack.reset();
1847
1848 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
1849 m_xobjectPtrStack.clear();
1850 m_paramsVectorStack.clear();
1851 m_elementRecursionStack.clear();
1852 #endif
1853
1854 if (m_xsltProcessor != 0)
1855 {
1856 m_xsltProcessor->reset();
1857 }
1858
1859 m_rootDocument = 0;
1860 m_stylesheetRoot = 0;
1861 m_mode = 0;
1862
1863 m_currentTemplateStack.clear();
1864 m_currentTemplateStack.push_back(0);
1865
1866 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
1867 m_formatterToTextCache.reset();
1868 m_formatterToSourceTreeCache.reset();
1869 m_nodeSorterCache.reset();
1870 #endif
1871
1872 m_xresultTreeFragAllocator.reset();
1873 m_documentFragmentAllocator.reset();
1874 m_documentAllocator.reset();
1875
1876 // Just in case endDocument() was not called,
1877 // clean things up...
1878 cleanUpTransients();
1879
1880 // Destroy the source tree factory, which
1881 // will destroy all result tree fragment nodes
1882 // that were generated...
1883 m_sourceTreeResultTreeFactory.reset();
1884
1885 // Reset the default execution context...
1886 m_xpathExecutionContextDefault.reset();
1887
1888 m_copyTextNodesOnlyStack.clear();
1889
1890 m_modeStack.clear();
1891
1892 m_currentIndexStack.clear();
1893
1894 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
1895 m_nodesToTransformStack.clear();
1896 m_processCurrentAttributeStack.clear();
1897 m_skipElementAttributesStack.clear();
1898 m_executeIfStack.clear();
1899 m_elementInvokerStack.clear();
1900 m_useAttributeSetIndexesStack.clear();
1901 m_formatterToSourceTreeStack.reset();
1902 m_stringStack.reset();
1903 m_mutableNodeRefListStack.reset();
1904 m_formatterToTextStack.reset();
1905 #endif
1906 }
1907
1908
1909
1910 XalanNode*
getCurrentNode() const1911 StylesheetExecutionContextDefault::getCurrentNode() const
1912 {
1913 return m_xpathExecutionContextDefault.getCurrentNode();
1914 }
1915
1916
1917
1918 void
pushCurrentNode(XalanNode * theCurrentNode)1919 StylesheetExecutionContextDefault::pushCurrentNode(XalanNode* theCurrentNode)
1920 {
1921 m_xpathExecutionContextDefault.pushCurrentNode(theCurrentNode);
1922 }
1923
1924
1925
1926 void
popCurrentNode()1927 StylesheetExecutionContextDefault::popCurrentNode()
1928 {
1929 m_xpathExecutionContextDefault.popCurrentNode();
1930 }
1931
1932
1933
1934 bool
isNodeAfter(const XalanNode & node1,const XalanNode & node2) const1935 StylesheetExecutionContextDefault::isNodeAfter(
1936 const XalanNode& node1,
1937 const XalanNode& node2) const
1938 {
1939 return m_xpathExecutionContextDefault.isNodeAfter(node1, node2);
1940 }
1941
1942
1943
1944 void
pushContextNodeList(const NodeRefListBase & theContextNodeList)1945 StylesheetExecutionContextDefault::pushContextNodeList(const NodeRefListBase& theContextNodeList)
1946 {
1947 m_xpathExecutionContextDefault.pushContextNodeList(theContextNodeList);
1948 }
1949
1950
1951
1952 void
popContextNodeList()1953 StylesheetExecutionContextDefault::popContextNodeList()
1954 {
1955 m_xpathExecutionContextDefault.popContextNodeList();
1956 }
1957
1958
1959
1960 const NodeRefListBase&
getContextNodeList() const1961 StylesheetExecutionContextDefault::getContextNodeList() const
1962 {
1963 return m_xpathExecutionContextDefault.getContextNodeList();
1964 }
1965
1966
1967
1968 StylesheetExecutionContextDefault::size_type
getContextNodeListLength() const1969 StylesheetExecutionContextDefault::getContextNodeListLength() const
1970 {
1971 return m_xpathExecutionContextDefault.getContextNodeListLength();
1972 }
1973
1974
1975
1976 StylesheetExecutionContextDefault::size_type
getContextNodeListPosition(const XalanNode & contextNode) const1977 StylesheetExecutionContextDefault::getContextNodeListPosition(const XalanNode& contextNode) const
1978 {
1979 return m_xpathExecutionContextDefault.getContextNodeListPosition(contextNode);
1980 }
1981
1982
1983
1984 bool
elementAvailable(const XalanQName & theQName) const1985 StylesheetExecutionContextDefault::elementAvailable(const XalanQName& theQName) const
1986 {
1987 if (theQName.getNamespace() == XSLTEngineImpl::getXSLNameSpaceURL())
1988 {
1989 const int xslToken = StylesheetConstructionContextDefault::getElementNameToken(theQName.getLocalPart());
1990
1991 return xslToken < 0 ? false : true;
1992 }
1993 else
1994 {
1995 return m_xpathExecutionContextDefault.elementAvailable(theQName);
1996 }
1997 }
1998
1999
2000
2001 bool
elementAvailable(const XalanDOMString & theName,const Locator * theLocator) const2002 StylesheetExecutionContextDefault::elementAvailable(
2003 const XalanDOMString& theName,
2004 const Locator* theLocator) const
2005 {
2006 XalanQNameByValue& theQName = m_xpathExecutionContextDefault.getScratchQName();
2007
2008 theQName.set(theName, getPrefixResolver(), theLocator);
2009
2010 return elementAvailable(theQName);
2011 }
2012
2013
2014
2015 bool
functionAvailable(const XalanQName & theQName) const2016 StylesheetExecutionContextDefault::functionAvailable(const XalanQName& theQName) const
2017 {
2018 return m_xpathExecutionContextDefault.functionAvailable(theQName);
2019 }
2020
2021
2022
2023 bool
functionAvailable(const XalanDOMString & theName,const Locator * theLocator) const2024 StylesheetExecutionContextDefault::functionAvailable(
2025 const XalanDOMString& theName,
2026 const Locator* theLocator) const
2027 {
2028 return m_xpathExecutionContextDefault.functionAvailable(theName, theLocator);
2029 }
2030
2031
2032
2033 const XObjectPtr
extFunction(const XalanDOMString & theNamespace,const XalanDOMString & functionName,XalanNode * context,const XObjectArgVectorType & argVec,const Locator * locator)2034 StylesheetExecutionContextDefault::extFunction(
2035 const XalanDOMString& theNamespace,
2036 const XalanDOMString& functionName,
2037 XalanNode* context,
2038 const XObjectArgVectorType& argVec,
2039 const Locator* locator)
2040 {
2041 assert(m_xpathExecutionContextDefault.getXPathEnvSupport() != 0);
2042
2043 return m_xpathExecutionContextDefault.getXPathEnvSupport()->extFunction(*this, theNamespace, functionName, context, argVec, locator);
2044 }
2045
2046
2047
2048 XalanDocument*
parseXML(MemoryManager & theManager,const XalanDOMString & urlString,const XalanDOMString & base,ErrorHandler * theErrorHandler) const2049 StylesheetExecutionContextDefault::parseXML(
2050 MemoryManager& theManager,
2051 const XalanDOMString& urlString,
2052 const XalanDOMString& base,
2053 ErrorHandler* theErrorHandler) const
2054 {
2055 return m_xpathExecutionContextDefault.parseXML(
2056 theManager,
2057 urlString,
2058 base,
2059 theErrorHandler);
2060 }
2061
2062
2063
2064 MutableNodeRefList*
borrowMutableNodeRefList()2065 StylesheetExecutionContextDefault::borrowMutableNodeRefList()
2066 {
2067 return m_xpathExecutionContextDefault.borrowMutableNodeRefList();
2068 }
2069
2070
2071
2072 bool
returnMutableNodeRefList(MutableNodeRefList * theList)2073 StylesheetExecutionContextDefault::returnMutableNodeRefList(MutableNodeRefList* theList)
2074 {
2075 return m_xpathExecutionContextDefault.returnMutableNodeRefList(theList);
2076 }
2077
2078
2079
2080 void
pushCopyTextNodesOnly(bool copyTextNodesOnly)2081 StylesheetExecutionContextDefault::pushCopyTextNodesOnly(bool copyTextNodesOnly)
2082 {
2083 m_copyTextNodesOnlyStack.push_back(copyTextNodesOnly);
2084 }
2085
2086
2087
2088 bool
popCopyTextNodesOnly()2089 StylesheetExecutionContextDefault::popCopyTextNodesOnly()
2090 {
2091 assert (m_copyTextNodesOnlyStack.size() > 0);
2092
2093 bool copyTextNodesOnly = m_copyTextNodesOnlyStack.back();
2094
2095 m_copyTextNodesOnlyStack.pop_back();
2096
2097 return copyTextNodesOnly;
2098 }
2099
2100
2101
2102 MutableNodeRefList*
createMutableNodeRefList(MemoryManager & theManager) const2103 StylesheetExecutionContextDefault::createMutableNodeRefList(MemoryManager& theManager) const
2104 {
2105 return m_xpathExecutionContextDefault.createMutableNodeRefList(theManager);
2106 }
2107
2108
2109
2110 XalanDOMString&
getCachedString()2111 StylesheetExecutionContextDefault::getCachedString()
2112 {
2113 return m_xpathExecutionContextDefault.getCachedString();
2114 }
2115
2116
2117
2118 bool
releaseCachedString(XalanDOMString & theString)2119 StylesheetExecutionContextDefault::releaseCachedString(XalanDOMString& theString)
2120 {
2121 return m_xpathExecutionContextDefault.releaseCachedString(theString);
2122 }
2123
2124
2125
2126 void
getNodeSetByKey(XalanNode * context,const XalanQName & qname,const XalanDOMString & ref,const Locator * locator,MutableNodeRefList & nodelist)2127 StylesheetExecutionContextDefault::getNodeSetByKey(
2128 XalanNode* context,
2129 const XalanQName& qname,
2130 const XalanDOMString& ref,
2131 const Locator* locator,
2132 MutableNodeRefList& nodelist)
2133 {
2134 assert(m_stylesheetRoot != 0);
2135
2136 m_stylesheetRoot->getNodeSetByKey(
2137 context,
2138 qname,
2139 ref,
2140 *getPrefixResolver(),
2141 nodelist,
2142 *this,
2143 locator,
2144 m_keyTables);
2145 }
2146
2147
2148
2149 void
getNodeSetByKey(XalanNode * context,const XalanDOMString & name,const XalanDOMString & ref,const Locator * locator,MutableNodeRefList & nodelist)2150 StylesheetExecutionContextDefault::getNodeSetByKey(
2151 XalanNode* context,
2152 const XalanDOMString& name,
2153 const XalanDOMString& ref,
2154 const Locator* locator,
2155 MutableNodeRefList& nodelist)
2156 {
2157 assert(m_stylesheetRoot != 0);
2158
2159 const PrefixResolver* const resolver =
2160 getPrefixResolver();
2161 assert(resolver != 0);
2162
2163 XalanQNameByValue& theQName =
2164 m_xpathExecutionContextDefault.getScratchQName();
2165
2166 theQName.set(name, resolver, locator);
2167
2168 m_stylesheetRoot->getNodeSetByKey(
2169 context,
2170 theQName,
2171 ref,
2172 *resolver,
2173 nodelist,
2174 *this,
2175 locator,
2176 m_keyTables);
2177 }
2178
2179
2180
2181 const XObjectPtr
getVariable(const XalanQName & name,const Locator * locator)2182 StylesheetExecutionContextDefault::getVariable(
2183 const XalanQName& name,
2184 const Locator* locator)
2185 {
2186 bool fFound;
2187
2188 const XObjectPtr theValue(m_variablesStack.getVariable(name, *this, fFound));
2189
2190 if(fFound == true)
2191 {
2192 assert(theValue.null() == false);
2193
2194 return theValue;
2195 }
2196 else
2197 {
2198 const GetCachedString theGuard(*this);
2199
2200 problem(
2201 eXSLTProcessor,
2202 eWarning,
2203 XalanMessageLoader::getMessage(
2204 theGuard.get(),
2205 XalanMessages::VariableIsNotDefined_1Param,
2206 name.getLocalPart()),
2207 locator,
2208 getCurrentNode());
2209
2210 return getXObjectFactory().createUnknown(name.getLocalPart());
2211 }
2212 }
2213
2214
2215
2216 const PrefixResolver*
getPrefixResolver() const2217 StylesheetExecutionContextDefault::getPrefixResolver() const
2218 {
2219 return m_xpathExecutionContextDefault.getPrefixResolver();
2220 }
2221
2222
2223
2224 void
setPrefixResolver(const PrefixResolver * thePrefixResolver)2225 StylesheetExecutionContextDefault::setPrefixResolver(const PrefixResolver* thePrefixResolver)
2226 {
2227 m_xpathExecutionContextDefault.setPrefixResolver(thePrefixResolver);
2228 }
2229
2230
2231
2232 const XalanDOMString*
getNamespaceForPrefix(const XalanDOMString & prefix) const2233 StylesheetExecutionContextDefault::getNamespaceForPrefix(const XalanDOMString& prefix) const
2234 {
2235 return m_xpathExecutionContextDefault.getNamespaceForPrefix(prefix);
2236 }
2237
2238
2239
2240 const XalanDOMString&
findURIFromDoc(const XalanDocument * owner) const2241 StylesheetExecutionContextDefault::findURIFromDoc(const XalanDocument* owner) const
2242 {
2243 return m_xpathExecutionContextDefault.findURIFromDoc(owner);
2244 }
2245
2246
2247
2248 const XalanDOMString&
getUnparsedEntityURI(const XalanDOMString & theName,const XalanDocument & theDocument) const2249 StylesheetExecutionContextDefault::getUnparsedEntityURI(
2250 const XalanDOMString& theName,
2251 const XalanDocument& theDocument) const
2252 {
2253 return m_xpathExecutionContextDefault.getUnparsedEntityURI(theName, theDocument);
2254 }
2255
2256
2257
2258 bool
shouldStripSourceNode(const XalanText & node)2259 StylesheetExecutionContextDefault::shouldStripSourceNode(const XalanText& node)
2260 {
2261 assert(m_stylesheetRoot != 0);
2262 // assert(node.getData().length() != 0);
2263
2264 return m_stylesheetRoot->shouldStripSourceNode(node);
2265 }
2266
2267
2268
2269 XalanDocument*
getSourceDocument(const XalanDOMString & theURI) const2270 StylesheetExecutionContextDefault::getSourceDocument(const XalanDOMString& theURI) const
2271 {
2272 return m_xpathExecutionContextDefault.getSourceDocument(theURI);
2273 }
2274
2275
2276
2277 void
setSourceDocument(const XalanDOMString & theURI,XalanDocument * theDocument)2278 StylesheetExecutionContextDefault::setSourceDocument(
2279 const XalanDOMString& theURI,
2280 XalanDocument* theDocument)
2281 {
2282 m_xpathExecutionContextDefault.setSourceDocument(theURI, theDocument);
2283 }
2284
2285
2286
2287 const XalanDecimalFormatSymbols*
getDecimalFormatSymbols(const XalanQName & qname)2288 StylesheetExecutionContextDefault::getDecimalFormatSymbols(const XalanQName& qname)
2289 {
2290 if (m_stylesheetRoot == 0)
2291 {
2292 return 0;
2293 }
2294 else
2295 {
2296 return m_stylesheetRoot->getDecimalFormatSymbols(qname);
2297 }
2298 }
2299
2300
2301
2302 PrintWriter*
createPrintWriter(XalanOutputStream * theTextOutputStream)2303 StylesheetExecutionContextDefault::createPrintWriter(XalanOutputStream* theTextOutputStream)
2304 {
2305 assert(theTextOutputStream != 0);
2306
2307 PrintWriter* const thePrintWriter =
2308 XalanOutputStreamPrintWriter::create(*theTextOutputStream);
2309
2310 m_printWriters.push_back(thePrintWriter);
2311
2312 return thePrintWriter;
2313 }
2314
2315
2316
2317 PrintWriter*
createPrintWriter(const XalanDOMString & theFileName,const XalanDOMString &)2318 StylesheetExecutionContextDefault::createPrintWriter(
2319 const XalanDOMString& theFileName,
2320 const XalanDOMString& /* theEncoding */)
2321 {
2322 XalanOutputStream* const theOutputStream =
2323 XalanFileOutputStream::create( theFileName, getMemoryManager());
2324
2325 m_outputStreams.push_back(theOutputStream);
2326
2327 return createPrintWriter(theOutputStream);
2328 }
2329
2330
2331
2332 PrintWriter*
createPrintWriter(StreamType & theStream)2333 StylesheetExecutionContextDefault::createPrintWriter(StreamType& theStream)
2334 {
2335 XalanOutputStream* const theOutputStream =
2336 XalanStdOutputStream::create(theStream, getMemoryManager());
2337
2338 m_outputStreams.push_back(theOutputStream);
2339
2340 return createPrintWriter(theOutputStream);
2341 }
2342
2343
2344
2345 PrintWriter*
createPrintWriter(FILE * theStream)2346 StylesheetExecutionContextDefault::createPrintWriter(FILE* theStream)
2347 {
2348 XalanOutputStream* const theOutputStream =
2349 XalanFStreamOutputStream::create(theStream, getMemoryManager());
2350
2351 m_outputStreams.push_back(theOutputStream);
2352
2353 return createPrintWriter(theOutputStream);
2354 }
2355
2356
2357
2358 CountersTable&
getCountersTable()2359 StylesheetExecutionContextDefault::getCountersTable()
2360 {
2361 return m_countersTable;
2362 }
2363
2364
2365
2366 void
characters(const XalanNode & node)2367 StylesheetExecutionContextDefault::characters(const XalanNode& node)
2368 {
2369 m_xsltProcessor->characters(node);
2370 }
2371
2372
2373 void
characters(const XObjectPtr & xobject)2374 StylesheetExecutionContextDefault::characters(const XObjectPtr& xobject)
2375 {
2376 m_xsltProcessor->characters(xobject);
2377 }
2378
2379
2380
2381 void
charactersRaw(const XalanNode & node)2382 StylesheetExecutionContextDefault::charactersRaw(const XalanNode& node)
2383 {
2384 m_xsltProcessor->charactersRaw(node);
2385 }
2386
2387
2388
2389 void
charactersRaw(const XObjectPtr & xobject)2390 StylesheetExecutionContextDefault::charactersRaw(const XObjectPtr& xobject)
2391 {
2392 m_xsltProcessor->charactersRaw(xobject);
2393 }
2394
2395
2396
2397 StylesheetExecutionContextDefault::tl_size_type
getTraceListeners() const2398 StylesheetExecutionContextDefault::getTraceListeners() const
2399 {
2400 assert(m_xsltProcessor != 0);
2401
2402 return m_xsltProcessor->getTraceListeners();
2403 }
2404
2405
2406
2407 void
fireGenerateEvent(const GenerateEvent & ge)2408 StylesheetExecutionContextDefault::fireGenerateEvent(const GenerateEvent& ge)
2409 {
2410 assert(m_xsltProcessor != 0);
2411
2412 m_xsltProcessor->fireGenerateEvent(ge);
2413 }
2414
2415
2416
2417 void
fireTraceEvent(const TracerEvent & te)2418 StylesheetExecutionContextDefault::fireTraceEvent(const TracerEvent& te)
2419 {
2420 assert(m_xsltProcessor != 0);
2421
2422 m_xsltProcessor->fireTraceEvent(te);
2423 }
2424
2425
2426
2427 void
fireSelectEvent(const SelectionEvent & se)2428 StylesheetExecutionContextDefault::fireSelectEvent(const SelectionEvent& se)
2429 {
2430 assert(m_xsltProcessor != 0);
2431
2432 m_xsltProcessor->fireSelectEvent(se);
2433 }
2434
2435
2436
2437 class PopAndPushContextMarker
2438 {
2439 public:
2440
PopAndPushContextMarker(StylesheetExecutionContext & theExecutionContext)2441 PopAndPushContextMarker(StylesheetExecutionContext& theExecutionContext) :
2442 m_executionContext(theExecutionContext)
2443 {
2444 m_executionContext.popContextMarker();
2445 }
2446
~PopAndPushContextMarker()2447 ~PopAndPushContextMarker()
2448 {
2449 m_executionContext.pushContextMarker();
2450 }
2451
2452 private:
2453
2454 StylesheetExecutionContext& m_executionContext;
2455 };
2456
2457
2458
2459 #if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
2460 void
getParams(const ElemTemplateElement & xslCallTemplateElement,ParamsVectorType & params)2461 StylesheetExecutionContextDefault::getParams(
2462 const ElemTemplateElement& xslCallTemplateElement,
2463 ParamsVectorType& params)
2464 {
2465 assert(getCurrentNode() != 0);
2466 assert(params.empty() == true);
2467
2468 const ElemTemplateElement* child =
2469 xslCallTemplateElement.getFirstChildElem();
2470
2471 if (0 != child)
2472 {
2473 // This object will take care of popping, then
2474 // pushing the context marker at the top of the
2475 // stack, even if an exception is thrown.
2476 PopAndPushContextMarker thePopPush(*this);
2477
2478 while(0 != child)
2479 {
2480 if(StylesheetConstructionContext::ELEMNAME_WITH_PARAM == child->getXSLToken())
2481 {
2482 const XPath* const pxpath = child->getXPath();
2483
2484 XObjectPtr theXObject;
2485
2486 if(0 != pxpath)
2487 {
2488 theXObject =
2489 createVariable(
2490 *pxpath,
2491 getCurrentNode(),
2492 *child);
2493 }
2494 else
2495 {
2496 theXObject =
2497 createVariable(
2498 *child,
2499 getCurrentNode());
2500 }
2501
2502 const ElemWithParam* const xslParamElement =
2503 static_cast<const ElemWithParam*>(child);
2504
2505 params.push_back(ParamsVectorType::value_type(&xslParamElement->getQName(), theXObject));
2506 }
2507
2508 child = child->getNextSiblingElem();
2509 }
2510 }
2511 }
2512 #endif
2513
2514
2515 XalanSourceTreeDocument*
getSourceTreeFactory(MemoryManager & theManager) const2516 StylesheetExecutionContextDefault::getSourceTreeFactory(MemoryManager& theManager) const
2517 {
2518 assert(m_xsltProcessor != 0);
2519
2520 if (m_sourceTreeResultTreeFactory.get() == 0)
2521 {
2522 m_sourceTreeResultTreeFactory.reset(
2523 &theManager,
2524 XalanSourceTreeDocument::create(theManager));
2525 }
2526
2527 return m_sourceTreeResultTreeFactory.get();
2528 }
2529
2530
2531
2532 bool
isCached(const XPath * theXPath)2533 StylesheetExecutionContextDefault::isCached(const XPath* theXPath)
2534 {
2535 XPathCacheMapType::const_iterator i =
2536 m_matchPatternCache.begin();
2537
2538 const XPathCacheMapType::const_iterator theEnd =
2539 m_matchPatternCache.end();
2540
2541 while (i != theEnd)
2542 {
2543 if ((*i).second.first == theXPath)
2544 {
2545 return true;
2546 }
2547 else
2548 {
2549 ++i;
2550 }
2551 }
2552
2553 return false;
2554 }
2555
2556
2557
2558 void
operator ()(const XPathCacheMapType::value_type & theCacheEntry)2559 StylesheetExecutionContextDefault::XPathCacheReturnFunctor::operator()(const XPathCacheMapType::value_type& theCacheEntry)
2560 {
2561 m_xsltProcessor.returnXPath(theCacheEntry.second.first);
2562 }
2563
2564
2565
2566
2567 void
clearXPathCache()2568 StylesheetExecutionContextDefault::clearXPathCache()
2569 {
2570 using std::for_each;
2571
2572 assert(m_matchPatternCache.empty() == true || m_xsltProcessor != 0);
2573
2574 if (m_xsltProcessor != 0)
2575 {
2576 for_each(m_matchPatternCache.begin(),
2577 m_matchPatternCache.end(),
2578 XPathCacheReturnFunctor(*m_xsltProcessor));
2579 }
2580
2581 m_matchPatternCache.clear();
2582 }
2583
2584
2585
2586 void
addToXPathCache(const XalanDOMString & pattern,const XPath * theXPath)2587 StylesheetExecutionContextDefault::addToXPathCache(
2588 const XalanDOMString& pattern,
2589 const XPath* theXPath)
2590 {
2591 assert(m_xsltProcessor != 0);
2592
2593 ClockType addClock = std::clock();
2594
2595 if (m_matchPatternCache.size() == eXPathCacheMax)
2596 {
2597 // OK, we need to clear something out of the cache...
2598
2599 // Initialize the lowest clock time found so far
2600 // with the current clock...
2601 ClockType lowest = addClock;
2602
2603 // Get some iterators ready to search the cache...
2604 XPathCacheMapType::iterator i =
2605 m_matchPatternCache.begin();
2606
2607 const XPathCacheMapType::iterator theEnd =
2608 m_matchPatternCache.end();
2609
2610 XPathCacheMapType::iterator earliest(theEnd);
2611
2612 while(i != theEnd)
2613 {
2614 const ClockType current = (*i).second.second;
2615
2616 if (current < lowest)
2617 {
2618 // OK, found a lower clock time, so
2619 // update the everything...
2620 lowest = current;
2621
2622 earliest = i;
2623 }
2624 else
2625 {
2626 ++i;
2627 }
2628 }
2629 assert(earliest != theEnd);
2630
2631 // Return the XPath and erase it from the cache.
2632 m_xsltProcessor->returnXPath((*earliest).second.first);
2633
2634 m_matchPatternCache.erase(earliest);
2635 }
2636
2637 // Add the XPath with the current clock
2638 m_matchPatternCache.insert(pattern, XPathCacheEntry(theXPath, addClock));
2639 }
2640
2641
2642
2643 void
cleanUpTransients()2644 StylesheetExecutionContextDefault::cleanUpTransients()
2645 {
2646 using std::for_each;
2647
2648 for_each(m_formatterListeners.begin(),
2649 m_formatterListeners.end(),
2650 DeleteFunctor<FormatterListener>(getMemoryManager()));
2651
2652 m_formatterListeners.clear();
2653
2654 for_each(m_printWriters.begin(),
2655 m_printWriters.end(),
2656 DeleteFunctor<PrintWriter>(getMemoryManager()));
2657
2658 m_printWriters.clear();
2659
2660 for_each(m_outputStreams.begin(),
2661 m_outputStreams.end(),
2662 DeleteFunctor<XalanOutputStream>(getMemoryManager()));
2663
2664 m_outputStreams.clear();
2665
2666 // Clean up the key table vector
2667 for_each(m_keyTables.begin(),
2668 m_keyTables.end(),
2669 makeMapValueDeleteFunctor(m_keyTables));
2670
2671 m_keyTables.clear();
2672
2673 m_countersTable.reset();
2674
2675 // Clear any cached XPaths...
2676 clearXPathCache();
2677
2678 assert(m_matchPatternCache.empty() == true);
2679 }
2680
2681
2682
2683 #if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
2684 void
createUseAttributeSetIndexesOnStack()2685 StylesheetExecutionContextDefault::createUseAttributeSetIndexesOnStack()
2686 {
2687 UseAttributeSetIndexes useAttributeSetIndexes;
2688 m_useAttributeSetIndexesStack.push_back(useAttributeSetIndexes);
2689 }
2690
2691
2692
2693 StylesheetExecutionContextDefault::UseAttributeSetIndexes&
getUseAttributeSetIndexes()2694 StylesheetExecutionContextDefault::getUseAttributeSetIndexes()
2695 {
2696 assert(m_useAttributeSetIndexesStack.size() > 0);
2697
2698 return m_useAttributeSetIndexesStack.back();
2699 }
2700
2701
2702
2703 void
popUseAttributeSetIndexesFromStack()2704 StylesheetExecutionContextDefault::popUseAttributeSetIndexesFromStack()
2705 {
2706 assert(m_useAttributeSetIndexesStack.size() > 0);
2707
2708 m_useAttributeSetIndexesStack.pop_back();
2709
2710 }
2711
2712
2713
2714 void
pushInvoker(const ElemTemplateElement * invoker)2715 StylesheetExecutionContextDefault::pushInvoker(const ElemTemplateElement * invoker)
2716 {
2717 m_elementInvokerStack.push_back(invoker);
2718 }
2719
2720
2721
2722 void
popInvoker()2723 StylesheetExecutionContextDefault::popInvoker()
2724 {
2725 assert (m_elementInvokerStack.size() > 0);
2726
2727 m_elementInvokerStack.pop_back();
2728 }
2729
2730
2731
2732 const ElemTemplateElement*
getInvoker() const2733 StylesheetExecutionContextDefault::getInvoker() const
2734 {
2735 assert (m_elementInvokerStack.size() > 0);
2736
2737 return m_elementInvokerStack.back();
2738 }
2739
2740
2741
2742
2743 XalanDOMString&
getAndPushCachedString()2744 StylesheetExecutionContextDefault::getAndPushCachedString()
2745 {
2746 XalanDOMString& theString = *(m_stringStack.get());
2747
2748 theString.clear();
2749
2750 return theString;
2751 }
2752
2753
2754
2755 XalanDOMString&
getLastCachedString()2756 StylesheetExecutionContextDefault::getLastCachedString()
2757 {
2758 return *(m_stringStack.top());
2759 }
2760
2761
2762
2763 XalanDOMString&
getAndPopCachedString()2764 StylesheetExecutionContextDefault::getAndPopCachedString()
2765 {
2766 return *(m_stringStack.release());
2767 }
2768
2769
2770
2771 void
pushProcessCurrentAttribute(const bool processAttribute)2772 StylesheetExecutionContextDefault::pushProcessCurrentAttribute(const bool processAttribute)
2773 {
2774 m_processCurrentAttributeStack.push_back(processAttribute);
2775 }
2776
2777
2778
2779 bool
popProcessCurrentAttribute()2780 StylesheetExecutionContextDefault::popProcessCurrentAttribute()
2781 {
2782 assert (m_processCurrentAttributeStack.size() > 0);
2783
2784 bool processAttribute = m_processCurrentAttributeStack.back();
2785 m_processCurrentAttributeStack.pop_back();
2786 return processAttribute;
2787 }
2788
2789
2790
2791 void
pushSkipElementAttributes(bool skipAttributes)2792 StylesheetExecutionContextDefault::pushSkipElementAttributes(bool skipAttributes)
2793 {
2794 m_skipElementAttributesStack.push_back(skipAttributes);
2795 }
2796
2797
2798
2799 bool
getSkipElementAttributes() const2800 StylesheetExecutionContextDefault::getSkipElementAttributes() const
2801 {
2802 if (m_skipElementAttributesStack.size() == 0)
2803 {
2804 return false;
2805 }
2806 else
2807 {
2808 return m_skipElementAttributesStack.back();
2809 }
2810 }
2811
2812
2813
2814 bool
popSkipElementAttributes()2815 StylesheetExecutionContextDefault::popSkipElementAttributes()
2816 {
2817 assert(m_skipElementAttributesStack.size() > 0);
2818
2819 bool skipAttributes = m_skipElementAttributesStack.back();
2820
2821 m_skipElementAttributesStack.pop_back();
2822
2823 return skipAttributes;
2824 }
2825
2826
2827
2828 void
pushExecuteIf(bool executeIf)2829 StylesheetExecutionContextDefault::pushExecuteIf(bool executeIf)
2830 {
2831 m_executeIfStack.push_back(executeIf);
2832 }
2833
2834
2835
2836 bool
popExecuteIf()2837 StylesheetExecutionContextDefault::popExecuteIf()
2838 {
2839 assert(m_executeIfStack.size() > 0);
2840
2841 bool executeIf = m_executeIfStack.back();
2842
2843 m_executeIfStack.pop_back();
2844
2845 return executeIf;
2846 }
2847
2848
2849
2850 void
beginFormatToText(XalanDOMString & theResult)2851 StylesheetExecutionContextDefault::beginFormatToText(XalanDOMString& theResult)
2852 {
2853 FormatterToTextDOMString* const theFormatter =
2854 m_formatterToTextStack.get();
2855 assert(theFormatter != 0);
2856
2857 theFormatter->setDOMString(theResult);
2858
2859 pushOutputContext(theFormatter);
2860
2861 theFormatter->startDocument();
2862 }
2863
2864
2865
2866 void
endFormatToText()2867 StylesheetExecutionContextDefault::endFormatToText()
2868 {
2869 FormatterToText* const theFormatter = m_formatterToTextStack.top();
2870 assert(
2871 theFormatter != 0 &&
2872 theFormatter->getEncoding().empty() == true &&
2873 theFormatter->getNormalizeLinefeed() == false &&
2874 theFormatter->getHandleIgnorableWhitespace() == true);
2875
2876 theFormatter->endDocument();
2877
2878 popOutputContext();
2879
2880 m_formatterToTextStack.release();
2881 }
2882
2883
2884
2885 void
pushXObjectPtr(const XObjectPtr & xobjectPtr)2886 StylesheetExecutionContextDefault::pushXObjectPtr(const XObjectPtr & xobjectPtr)
2887 {
2888 m_xobjectPtrStack.push_back(xobjectPtr);
2889 }
2890
2891
2892
2893 void
popXObjectPtr()2894 StylesheetExecutionContextDefault::popXObjectPtr()
2895 {
2896 assert(m_xobjectPtrStack.size() > 0);
2897
2898 m_xobjectPtrStack.back().release();
2899 m_xobjectPtrStack.pop_back();
2900 }
2901
2902
2903
2904 MutableNodeRefList&
createAndPushMutableNodeRefList()2905 StylesheetExecutionContextDefault::createAndPushMutableNodeRefList()
2906 {
2907 MutableNodeRefList& nodeList = *(m_mutableNodeRefListStack.get());
2908
2909 nodeList.clear();
2910
2911 return nodeList;
2912 }
2913
2914
2915
2916 void
releaseAndPopMutableNodeRefList()2917 StylesheetExecutionContextDefault::releaseAndPopMutableNodeRefList()
2918 {
2919 m_mutableNodeRefListStack.release();
2920 }
2921
2922
2923
2924 void
createAndPushNodesToTransformList(const NodeRefListBase * nodeList)2925 StylesheetExecutionContextDefault::createAndPushNodesToTransformList(const NodeRefListBase* nodeList)
2926 {
2927 assert(nodeList != 0);
2928
2929 NodesToTransform nodesToTransform(nodeList);
2930 m_nodesToTransformStack.push_back(nodesToTransform);
2931 }
2932
2933
2934
2935 XalanNode*
getNextNodeToTransform()2936 StylesheetExecutionContextDefault::getNextNodeToTransform()
2937 {
2938 assert(m_nodesToTransformStack.size() > 0);
2939
2940 return m_nodesToTransformStack.back().next();
2941 }
2942
2943
2944
2945 void
popNodesToTransformList()2946 StylesheetExecutionContextDefault::popNodesToTransformList()
2947 {
2948 assert(m_nodesToTransformStack.size() > 0);
2949
2950 m_nodesToTransformStack.pop_back();
2951 }
2952
2953
2954 XalanDOMString StylesheetExecutionContextDefault::FormatterToTextDOMString::s_dummyString(XalanMemMgrs::getDummyMemMgr());
2955
2956
2957
FormatterToTextDOMString(MemoryManager & theManager)2958 StylesheetExecutionContextDefault::FormatterToTextDOMString::FormatterToTextDOMString(MemoryManager& theManager) :
2959 FormatterToText(theManager),
2960 m_printWriter(s_dummyString)
2961 {
2962 setNormalizeLinefeed(false);
2963
2964 setWriter(&m_printWriter);
2965 }
2966
2967
~FormatterToTextDOMString()2968 StylesheetExecutionContextDefault::FormatterToTextDOMString::~FormatterToTextDOMString()
2969 {
2970 assert(s_dummyString.capacity() == 0);
2971 }
2972 #endif
2973
2974
2975 }
2976