Xalan-C++ API Reference  1.12.0
StylesheetHandler.hpp
Go to the documentation of this file.
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 #if !defined(XALAN_STYLESHEETHANDLER_HEADER_GUARD)
20 #define XALAN_STYLESHEETHANDLER_HEADER_GUARD
21 
22 // Base include file. Must be first.
23 #include "XSLTDefinitions.hpp"
24 
25 
26 
29 
30 
31 
33 
34 
35 
37 
38 
39 
41 
42 
43 
48 
49 
50 
51 namespace XALAN_CPP_NAMESPACE {
52 
53 
54 
55 class ElemTemplate;
56 class ElemTemplateElement;
57 class ElemTextLiteral;
58 class ExtensionNSHandler;
59 class StylesheetConstructionContext;
60 
61 
62 
63 /**
64  * This class processes a stylesheet via SAX events, and inits
65  * the given stylesheet. If you need to alter the code in here,
66  * it is not for the faint-of-heart, due to the state tracking
67  * that has to be done due to the SAX event model.
68  */
70 {
71 
72 public:
73 
76 
81 
82  /**
83  * Perform static initialization. See class XMLSupportInit.
84  */
85  static void
86  initialize(MemoryManager& theManager);
87 
88  /**
89  * Perform static shut down. See class XMLSupportInit.
90  */
91  static void
92  terminate();
93 
94  /**
95  * Construct a StylesheetHandler ... it will add the DOM nodes
96  * to the document fragment.
97  */
99  Stylesheet& stylesheetTree,
100  StylesheetConstructionContext& constructionContext);
101 
102  MemoryManager&
104  {
105  return m_constructionContext.getMemoryManager();
106  }
107 
108  virtual
110 
111  /**
112  * Receive notification of character data.
113  *
114  * <p>The Parser will call this method to report each chunk of
115  * character data. SAX parsers may return all contiguous character
116  * data in a single chunk, or they may split it into several
117  * chunks; however, all of the characters in any single event
118  * must come from the same external entity, so that the Locator
119  * provides useful information.</p>
120  *
121  * <p>The application must not attempt to read from the array
122  * outside of the specified range.</p>
123  *
124  * <p>Note that some parsers will report whitespace using the
125  * ignorableWhitespace() method rather than this one (validating
126  * parsers must do so).</p>
127  *
128  * @param chars pointer to characters from the XML document
129  * @param length number of characters to read from the array
130  * @exception SAXException
131  * @see #ignorableWhitespace
132  * @see org.xml.sax.Locator
133  */
134  virtual void
135  characters(
136  const XMLCh* const chars,
137  const size_type length);
138 
139  /**
140  * Receive notification of character data. If available, when the
141  * disable-output-escaping attribute is used, output raw text without
142  * escaping.
143  *
144  * @param ch pointer to characters from the XML document
145  * @param start start position in the array
146  * @param length number of characters to read from the array
147  * @exception SAXException
148  */
149  virtual void
150  charactersRaw(
151  const XMLCh* const chars,
152  const size_type length);
153 
154  /**
155  * Receive notification of cdata.
156  *
157  * <p>The Parser will call this method to report each chunk of
158  * character data. SAX parsers may return all contiguous character
159  * data in a single chunk, or they may split it into several
160  * chunks; however, all of the characters in any single event
161  * must come from the same external entity, so that the Locator
162  * provides useful information.</p>
163  *
164  * <p>The application must not attempt to read from the array
165  * outside of the specified range.</p>
166  *
167  * <p>Note that some parsers will report whitespace using the
168  * ignorableWhitespace() method rather than this one (validating
169  * parsers must do so).</p>
170  *
171  * @param ch pointer to characters from the XML document
172  * @param start start position in the array
173  * @param length number of characters to read from the array
174  * @exception SAXException
175  * @see #ignorableWhitespace
176  */
177  virtual void
178  cdata(
179  const XMLCh* const ch,
180  const size_type length);
181 
182  /**
183  * Receive notification of ignorable whitespace in element content.
184  *
185  * <p>Validating Parsers must use this method to report each chunk
186  * of ignorable whitespace (see the W3C XML 1.0 recommendation,
187  * section 2.10): non-validating parsers may also use this method
188  * if they are capable of parsing and using content models.</p>
189  *
190  * <p>SAX parsers may return all contiguous whitespace in a single
191  * chunk, or they may split it into several chunks; however, all of
192  * the characters in any single event must come from the same
193  * external entity, so that the Locator provides useful
194  * information.</p>
195  *
196  * <p>The application must not attempt to read from the array
197  * outside of the specified range.</p>
198  *
199  * @param chars characters from the XML document
200  * @param start start position in the array
201  * @param length number of characters to read from the array
202  * @exception SAXException
203  * @see #characters
204  */
205  virtual void
206  ignorableWhitespace(
207  const XMLCh* const chars,
208  const size_type length);
209 
210  /**
211  * Receive notification of a processing instruction.
212  *
213  * <p>The Parser will invoke this method once for each processing
214  * instruction found: note that processing instructions may occur
215  * before or after the main document element.</p>
216  *
217  * <p>A SAX parser should never report an XML declaration (XML 1.0,
218  * section 2.8) or a text declaration (XML 1.0, section 4.3.1)
219  * using this method.</p>
220  *
221  * @param target pointer to processing instruction target
222  * @param data pointer to processing instruction data, or null if none
223  * was supplied
224  * @exception SAXException
225  */
226  virtual void processingInstruction (const XMLCh* const target, const XMLCh* const data);
227 
228  /**
229  * Called when a Comment is to be constructed.
230  *
231  * @param data comment data
232  * @exception SAXException
233  */
234  virtual void comment(const XMLCh* const data);
235 
236  /**
237  * Receive notification of a entityReference.
238  *
239  * @param data pointer to characters from the XML document
240  * @exception SAXException
241  */
242  virtual void entityReference(const XMLCh* const data);
243 
244  // These methods are inherited DocumentHandler ...
245 
246  // $$$ Theoretically, shouldn't need javadoc for these, since they are
247  // inherited from DocumentHandler, but let's leave them in for now -- JMD
248 
249  /**
250  * Receive an object for locating the origin of SAX document events.
251  *
252  * <p>SAX parsers are strongly encouraged (though not absolutely
253  * required) to supply a locator: if it does so, it must supply
254  * the locator to the application by invoking this method before
255  * invoking any of the other methods in the DocumentHandler
256  * interface.</p>
257  *
258  * <p>The locator allows the application to determine the end
259  * position of any document-related event, even if the parser is
260  * not reporting an error. Typically, the application will
261  * use this information for reporting its own errors (such as
262  * character content that does not match an application's
263  * business rules). The information returned by the locator
264  * is probably not sufficient for use with a search engine.</p>
265  *
266  * <p>Note that the locator will return correct information only
267  * during the invocation of the events in this interface. The
268  * application should not attempt to use it at any other time.</p>
269  *
270  * @param locator object that can return the location of
271  * any SAX document event.
272  * @see org.xml.sax.Locator
273  */
274  virtual void setDocumentLocator(const Locator* const locator);
275 
276  /**
277  * Receive notification of the beginning of a document.
278  *
279  * <p>The SAX parser will invoke this method only once, before any
280  * other methods in this interface or in DTDHandler (except for
281  * setDocumentLocator).</p>
282  *
283  * @exception SAXException
284  */
285  virtual void startDocument();
286 
287  /**
288  * Receive notification of the end of a document.
289  *
290  * <p>The SAX parser will invoke this method only once, and it will
291  * be the last method invoked during the parse. The parser shall
292  * not invoke this method until it has either abandoned parsing
293  * (because of an unrecoverable error) or reached the end of
294  * input.</p>
295  *
296  * @exception SAXException
297  */
298  virtual void endDocument();
299 
300  /**
301  * Receive notification of the beginning of an element.
302  *
303  * <p>The Parser will invoke this method at the beginning of every
304  * element in the XML document; there will be a corresponding
305  * endElement() event for every startElement() event (even when the
306  * element is empty). All of the element's content will be
307  * reported, in order, before the corresponding endElement()
308  * event.</p>
309  *
310  * <p>If the element name has a namespace prefix, the prefix will
311  * still be attached. Note that the attribute list provided will
312  * contain only attributes with explicit values (specified or
313  * defaulted): #IMPLIED attributes will be omitted.</p>
314  *
315  * @param name element type name
316  * @param atts attributes attached to the element, if any
317  * @exception SAXException
318  * @see #endElement
319  * @see org.xml.sax.AttributeList
320  */
321  virtual void startElement(const XMLCh* const name, AttributeListType& attrs);
322 
323  /**
324  * Receive notification of the end of an element.
325  *
326  * <p>The SAX parser will invoke this method at the end of every
327  * element in the XML document; there will be a corresponding
328  * startElement() event for every endElement() event (even when the
329  * element is empty).</p>
330  *
331  * <p>If the element name has a namespace prefix, the prefix will
332  * still be attached to the name.</p>
333  *
334  * @param name element type name
335  * @exception SAXException
336  */
337  virtual void endElement(const XMLCh* const name);
338 
339  /**
340  * This method allows the user installed Document Handler to 'reset'
341  * itself, freeing all the memory resources. The scanner calls this
342  * method before starting a new parse event.
343  */
344  virtual void resetDocument();
345 
346 protected:
347 
348  /**
349  * See if this is a xmlns attribute, and, if so, process it.
350  *
351  * @param attrName Qualified name of attribute.
352  * @param atts The attribute list where the element comes from (not used at
353  * this time).
354  * @param which The index into the attribute list (not used at this time).
355  * @return True if this is a namespace name.
356  */
357  bool
358  isAttrOK(
359  const XalanDOMChar* attrName,
360  const AttributeListType& atts,
361  XalanSize_t which);
362 
363  /**
364  * Tell whether or not this is a xml:space attribute and, if so, process it.
365  *
366  * @param elementName The name of the element that owns the attribute
367  * @param aname The name of the attribute in question.
368  * @param atts The attribute list that owns the attribute.
369  * @param which The index of the attribute into the attribute list.
370  * @param locator A Locator instance for error reporting.
371  * @param fPreserve set to true if the attribute value is "preserve"
372  * @return True if this is a xml:space attribute.
373  */
374  bool
375  processSpaceAttr(
376  const XalanDOMChar* elementName,
377  const XalanDOMChar* aname,
378  const AttributeListType& atts,
379  XalanSize_t which,
380  const Locator* locator,
381  bool& fPreserve);
382 
383  /**
384  * Tell whether or not this is a xml:space attribute and, if so, process it.
385  *
386  * @param elementName The name of the element that owns the attributes
387  * @param atts The attribute list that owns the attribute.
388  * @param locator A Locator instance for error reporting.
389  * @param fPreserve set to true if an xml:space attribute value is "preserve"
390  * @return True if this is a xml:space attribute.
391  */
392  bool
393  processSpaceAttr(
394  const XalanDOMChar* elementName,
395  const AttributeListType& atts,
396  const Locator* locator,
397  bool& fPreserve);
398 
399  /**
400  * Process xsl:import.
401  */
402  void
403  processImport(
404  const XalanDOMChar* name,
405  const AttributeListType& atts,
406  const Locator* locator);
407 
408  /**
409  * Process xsl:include.
410  */
411  void
412  processInclude(
413  const XalanDOMChar* name,
414  const AttributeListType& atts,
415  const Locator* locator);
416 
417  void
418  doCleanup();
419 
420 private:
421 
422  enum { eElemEmptyAllocatorBlockSize = 10, eElemTextBlockSize = 10 };
423 
424  // not implemented
425  StylesheetHandler(const StylesheetHandler&);
426 
427  StylesheetHandler&
428  operator=(const StylesheetHandler&);
429 
430  // Utility functions...
431  void
432  illegalAttributeError(
433  const XalanDOMChar* theElementName,
434  const XalanDOMChar* theAttributeName,
435  const Locator* theLocator) const;
436 
437  void
438  error(
439  const XalanDOMChar* theMessage1,
440  const XalanDOMChar* theMessage2,
441  const Locator* theLocator) const;
442 
443  void
444  error(
445  const XalanDOMChar* theMessage1,
446  const XalanDOMString& theMessage2,
447  const Locator* theLocator) const;
448 
449  void
450  error(
451  const XalanDOMString& theMessage1,
452  const XalanDOMChar* theMessage2,
453  const Locator* theLocator) const;
454 
455  void
456  error(
457  const XalanDOMString& theMessage1,
458  const XalanDOMString& theMessage2,
459  const Locator* theLocator) const;
460 
461  void
462  warn(
463  const XalanDOMChar* theMessage1,
464  const XalanDOMChar* theMessage2,
465  const Locator* theLocator) const;
466 
467  void
468  warn(
469  const XalanDOMChar* theMessage1,
470  const XalanDOMString& theMessage2,
471  const Locator* theLocator) const;
472  void
473  warn(
474  const XalanDOMString& theMessage,
475  const Locator* theLocator) const;
476 
477  void
478  error(
479  const XalanDOMString& theMessage,
480  const Locator* theLocator) const;
481 
482  void
483  processText(
484  const XMLCh* chars,
485  size_type length);
486 
487  void
488  accumulateText(
489  const XMLCh* chars,
490  size_type length);
491 
492  void
493  processAccumulatedText();
494 
495  void
496  processTopLevelElement(
497  const XalanDOMChar* name,
498  const AttributeListType& atts,
499  int xslToken,
500  const Locator* locator,
501  bool& fPreserveSpace,
502  bool& fSpaceAttrProcessed);
503 
504  void
505  processStylesheet(
506  const XalanDOMChar* name,
507  const AttributeListType& atts,
508  const Locator* locator,
509  bool& fPreserveSpace,
510  bool& fSpaceAttrProcessed);
511 
512  void
513  processPreserveStripSpace(
514  const XalanDOMChar* name,
515  const AttributeListType& atts,
516  const Locator* locator,
517  int xslToken);
518 
519  void
520  appendChildElementToParent(
521  ElemTemplateElement* elem,
522  const Locator* locator);
523 
524  void
525  appendChildElementToParent(
526  ElemTemplateElement* parent,
527  ElemTemplateElement* elem);
528 
529  void
530  appendChildElementToParent(
531  ElemTemplateElement* parent,
532  ElemTemplateElement* elem,
533  const Locator* locator);
534 
535  bool
536  inExtensionElement() const;
537 
538  void
539  processExtensionElement(
540  const XalanDOMChar* name,
541  const XalanDOMString& localName,
542  const AttributeListType& atts,
543  const Locator* locator);
544 
545  void
546  checkForOrAddVariableName(
547  const XalanQName& theVariableName,
548  const Locator* theLocator);
549 
550  // Data members...
551 
552  /**
553  * The owning stylesheet.
554  */
555  Stylesheet& m_stylesheet;
556 
557  /**
558  * The construction context.
559  */
560  StylesheetConstructionContext& m_constructionContext;
561 
562  /**
563  * An allocator for ElemEmpty instances.
564  */
565  XalanElemEmptyAllocator m_elemEmptyAllocator;
566 
567  /**
568  * An allocator for ElemText instances.
569  */
570  XalanElemTextAllocator m_elemTextAllocator;
571 
572  /**
573  * The stack of elements, pushed and popped as events occur.
574  */
575  ElemTemplateStackType m_elemStack;
576 
577  /**
578  * Need to keep a stack of found whitespace elements so that
579  * whitespace elements next to non-whitespace elements can
580  * be merged. For instance: &lt;out> &lt;![CDATA[test]]> &lt;/out>
581  */
582  ElemTextLiteralStackType m_whiteSpaceElems;
583 
584  /**
585  * The current template.
586  */
587  ElemTemplateElement* m_pTemplate;
588 
589  class LastPoppedHolder
590  {
591  public:
592 
593  LastPoppedHolder(StylesheetHandler& theStylesheetHandler) :
594  m_stylesheetHandler(theStylesheetHandler),
595  m_lastPopped(0)
596  {
597  }
598 
599  ~LastPoppedHolder()
600  {
601  cleanup();
602  }
603 
604  ElemTemplateElement*
605  operator->() const
606  {
607  return m_lastPopped;
608  }
609 
610  bool
611  operator==(ElemTemplateElement* theRHS)
612  {
613  return m_lastPopped == theRHS;
614  }
615 
616  bool
617  operator!=(ElemTemplateElement* theRHS)
618  {
619  return m_lastPopped != theRHS;
620  }
621 
622  void
623  operator=(ElemTemplateElement* theRHS)
624  {
625  if (theRHS != m_lastPopped)
626  {
627  cleanup();
628 
629  m_lastPopped = theRHS;
630  }
631  }
632 
633  void
634  swap(LastPoppedHolder& theOther)
635  {
636  ElemTemplateElement* const theTemp = m_lastPopped;
637 
638  m_lastPopped = theOther.m_lastPopped;
639 
640  theOther.m_lastPopped = theTemp;
641  }
642 
643  ElemTemplateElement*
644  get() const
645  {
646  return m_lastPopped;
647  }
648 
649  private:
650 
651  void
652  set(ElemTemplateElement* theNewElement)
653  {
654  if (theNewElement != m_lastPopped)
655  {
656  cleanup();
657 
658  m_lastPopped = theNewElement;
659  }
660  }
661 
662  // Not implemented...
663  LastPoppedHolder&
664  operator=(const LastPoppedHolder&);
665 
666  LastPoppedHolder(const LastPoppedHolder&);
667 
668  // Helper functions...
669  void
670  cleanup();
671 
672  // Data members...
673  StylesheetHandler& m_stylesheetHandler;
674 
675  ElemTemplateElement* m_lastPopped;
676  };
677 
678  friend class LastPoppedHolder;
679 
680  /**
681  * Manages the last element popped from the stack.
682  */
683  LastPoppedHolder m_lastPopped;
684 
685  /**
686  * True if the process is in a template context.
687  */
688  bool m_inTemplate;
689 
690  /**
691  * True if the stylesheet element was found, or if it was determined that
692  * the stylesheet is wrapperless.
693  */
694  bool m_foundStylesheet;
695 
696  /**
697  * Flag to let us know when we've found an element inside the
698  * stylesheet that is not an xsl:import, so we can restrict imports
699  * to being the first elements.
700  */
701  bool m_foundNotImport;
702 
703  XalanDOMString m_elementLocalName;
704 
705  /**
706  * Accumulate character buffer to create contiguous character data
707  * where possible.
708  */
709  XalanDOMString m_accumulateText;
710 
711  XalanDOMString m_includeBase;
712 
713  BoolStackType m_inExtensionElementStack;
714 
715  BoolStackType m_preserveSpaceStack;
716 
717  // Note that these variables must not be saved by
718  // PushPopIncludeState...
719  unsigned long m_locatorsPushed;
720 
721  QNameSetType m_globalVariableNames;
722 
723  enum { eVariablesStackDefault = 20 };
724 
725  QNameSetVectorType m_inScopeVariableNamesStack;
726 
727  /**
728  * Init the wrapperless template
729  */
731  initWrapperless(
732  const XalanDOMChar* name,
733  const AttributeListType& atts,
734  const Locator* locator);
735 
736  const XalanDOMString*
737  getNamespaceFromStack(const XalanDOMChar* theName,
738  XalanDOMString& theBuffer) const;
739 
740  const XalanDOMString*
741  getNamespaceForPrefixFromStack(const XalanDOMString& thePrefix) const;
742 
743  class PushPopIncludeState;
744 
745  friend class StylesheetHandler::PushPopIncludeState;
746 
747  class PushPopIncludeState
748  {
749  public:
750 
751  PushPopIncludeState(StylesheetHandler& theHandler);
752 
753  ~PushPopIncludeState();
754 
755  private:
756 
757  StylesheetHandler& m_handler;
758 
759  ElemTemplateStackType m_elemStack;
760 
761  ElemTemplateElement* const m_pTemplate;
762 
763  LastPoppedHolder m_lastPopped;
764 
765  const bool m_inTemplate;
766 
767  const bool m_foundStylesheet;
768 
769  const XalanDOMString m_XSLNameSpaceURL;
770 
771  const bool m_foundNotImport;
772 
773  Stylesheet::NamespaceVectorType m_namespaceDecls;
774 
775  Stylesheet::NamespacesStackType m_namespaces;
776 
777  NamespacesHandler m_namespacesHandler;
778 
779  BoolStackType m_inExtensionElementStack;
780 
781  BoolStackType m_preserveSpaceStack;
782  };
783 
784  static const XalanDOMString s_emptyString;
785 };
786 
787 
788 
789 }
790 
791 
792 
793 #endif // XALAN_STYLESHEETHANDLER_HEADER_GUARD
xalanc::operator!=
bool operator!=(const XalanVector< Type > &theLHS, const XalanVector< Type > &theRHS)
Definition: XalanVector.hpp:1140
xalanc::XalanSet< XalanQNameByReference >
XALAN_CPP_NAMESPACE
#define XALAN_CPP_NAMESPACE
Xalan-C++ namespace, including major and minor version.
Definition: XalanVersion.hpp:76
xalanc::AttributeListType
xercesc::AttributeList AttributeListType
Definition: AttributeListImpl.hpp:41
XalanDOMString.hpp
xalanc::XalanVector< ElemTemplateElement * >
XALAN_XSLT_EXPORT
#define XALAN_XSLT_EXPORT
Definition: XSLTDefinitions.hpp:27
xalanc::StylesheetHandler::getMemoryManager
MemoryManager & getMemoryManager()
Definition: StylesheetHandler.hpp:103
FormatterListener.hpp
xalanc::swap
void swap(XalanVector< Type > &theLHS, XalanVector< Type > &theRHS)
Definition: XalanVector.hpp:1107
xalanc::StylesheetHandler::BoolStackType
XalanVector< bool > BoolStackType
Definition: StylesheetHandler.hpp:77
xalanc::size_type
size_t size_type
Definition: XalanMap.hpp:46
xalanc::ElemTemplateElement
Definition: ElemTemplateElement.hpp:79
xalanc::StylesheetHandler::QNameSetVectorType
XalanVector< QNameSetType, ConstructWithMemoryManagerTraits< QNameSetType > > QNameSetVectorType
Definition: StylesheetHandler.hpp:80
XalanVector.hpp
xalanc::operator==
bool operator==(const XalanVector< Type > &theLHS, const XalanVector< Type > &theRHS)
Definition: XalanVector.hpp:1118
xalanc::StylesheetHandler::ElemTextLiteralStackType
XalanVector< ElemTemplateElement * > ElemTextLiteralStackType
Definition: StylesheetHandler.hpp:75
XalanQNameByValue.hpp
xalanc::NamespacesHandler
Definition: NamespacesHandler.hpp:52
xalanc::XalanDeque
Xalan implementation of deque.
Definition: XalanDeque.hpp:200
xalanc::StylesheetHandler::ElemTemplateStackType
XalanVector< ElemTemplateElement * > ElemTemplateStackType
Definition: StylesheetHandler.hpp:74
xalanc::StylesheetHandler::QNameSetType
XalanSet< XalanQNameByReference > QNameSetType
Definition: StylesheetHandler.hpp:78
XalanElemEmptyAllocator.hpp
xalanc::length
XalanDOMString::size_type length(const XalanDOMString &theString)
Get the length of a XalanDOMString.
Definition: DOMStringHelper.hpp:235
xalanc::StylesheetConstructionContext
Definition: StylesheetConstructionContext.hpp:83
xalanc::StylesheetHandler
This class processes a stylesheet via SAX events, and inits the given stylesheet.
Definition: StylesheetHandler.hpp:69
XalanElemTextAllocator.hpp
NamespacesHandler.hpp
XSLTDefinitions.hpp
xalanc::Stylesheet
This class represents the base stylesheet or an "import" stylesheet.
Definition: Stylesheet.hpp:86
xalanc::FormatterListener
A SAX-based formatter interface for the XSL processor.
Definition: FormatterListener.hpp:56
xalanc::XalanDOMString
Definition: XalanDOMString.hpp:45
Stylesheet.hpp
XalanSet.hpp