| /* |
| * Copyright 1999-2004 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #include "StylesheetHandler.hpp" |
| |
| |
| |
| #include <algorithm> |
| |
| |
| |
| #include <xercesc/sax/Locator.hpp> |
| #include <xercesc/sax/SAXParseException.hpp> |
| |
| |
| |
| #include <xalanc/Include/STLHelper.hpp> |
| |
| |
| |
| #include <xalanc/XalanDOM/XalanDOMException.hpp> |
| |
| |
| |
| #include <xalanc/PlatformSupport/AttributeListImpl.hpp> |
| #include <xalanc/PlatformSupport/DOMStringHelper.hpp> |
| #include <xalanc/PlatformSupport/DoubleSupport.hpp> |
| #include <xalanc/PlatformSupport/StringTokenizer.hpp> |
| #include <xalanc/PlatformSupport/XalanLocator.hpp> |
| #include <xalanc/PlatformSupport/XalanMessageLoader.hpp> |
| |
| |
| |
| #include <xalanc/DOMSupport/DOMServices.hpp> |
| |
| |
| |
| #include "Constants.hpp" |
| #include "ElemTemplateElement.hpp" |
| #include "ElemTextLiteral.hpp" |
| #include "Stylesheet.hpp" |
| #include "StylesheetConstructionContext.hpp" |
| #include "StylesheetRoot.hpp" |
| #include "XalanSpaceNodeTester.hpp" |
| |
| |
| |
| #include <xalanc/Include/XalanAutoPtr.hpp> |
| |
| |
| |
| XALAN_CPP_NAMESPACE_BEGIN |
| |
| |
| |
| typedef StylesheetConstructionContext::GetAndReleaseCachedString GetAndReleaseCachedString; |
| |
| |
| |
| StylesheetHandler::StylesheetHandler( |
| Stylesheet& stylesheetTree, |
| StylesheetConstructionContext& constructionContext) : |
| FormatterListener(OUTPUT_METHOD_OTHER), |
| m_stylesheet(stylesheetTree), |
| m_constructionContext(constructionContext), |
| m_elemEmptyAllocator(eElemEmptyAllocatorBlockSize), |
| m_elemTextAllocator(eElemTextBlockSize), |
| m_elemStack(), |
| m_whiteSpaceElems(), |
| m_pTemplate(0), |
| m_lastPopped(*this), |
| m_inTemplate(false), |
| m_foundStylesheet(false), |
| m_foundNotImport(false), |
| m_elementLocalName(), |
| m_accumulateText(), |
| m_includeBase(stylesheetTree.getBaseIdentifier()), |
| m_inExtensionElementStack(), |
| m_locatorsPushed(0), |
| m_globalVariableNames(), |
| m_inScopeVariableNamesStack() |
| { |
| m_inScopeVariableNamesStack.reserve(eVariablesStackDefault); |
| } |
| |
| |
| |
| StylesheetHandler::~StylesheetHandler() |
| { |
| doCleanup(); |
| } |
| |
| |
| |
| void StylesheetHandler::setDocumentLocator(const LocatorType* const locator) |
| { |
| m_constructionContext.pushLocatorOnStack(locator); |
| |
| ++m_locatorsPushed; |
| } |
| |
| |
| |
| void |
| StylesheetHandler::startDocument() |
| { |
| } |
| |
| |
| |
| void |
| StylesheetHandler::endDocument() |
| { |
| m_constructionContext.popLocatorStack(); |
| |
| if (m_locatorsPushed > 0) |
| { |
| --m_locatorsPushed; |
| } |
| |
| m_inExtensionElementStack.clear(); |
| } |
| |
| |
| |
| bool |
| StylesheetHandler::isAttrOK( |
| const XalanDOMChar* attrName, |
| const AttributeListType& atts, |
| int which) |
| { |
| return m_stylesheet.isAttrOK(attrName, atts, which, m_constructionContext); |
| } |
| |
| |
| |
| bool |
| StylesheetHandler::processSpaceAttr( |
| const XalanDOMChar* aname, |
| const AttributeListType& atts, |
| int which, |
| const LocatorType* locator, |
| bool& fPreserve) |
| { |
| if(m_constructionContext.isXMLSpaceAttribute(aname, m_stylesheet, locator) == false) |
| { |
| fPreserve = false; |
| |
| return false; |
| } |
| else |
| { |
| const XalanDOMChar* const spaceVal = atts.getValue(which); |
| |
| if(equals(spaceVal, Constants::ATTRVAL_DEFAULT)) |
| { |
| fPreserve = false; |
| } |
| else if(equals(spaceVal, Constants::ATTRVAL_PRESERVE)) |
| { |
| fPreserve = true; |
| } |
| else |
| { |
| error( |
| XalanMessageLoader::getMessage( |
| XalanMessages::AttributeHasIllegalValue_1Param, |
| Constants::ATTRNAME_XMLSPACE), |
| locator); |
| } |
| |
| return true; |
| } |
| } |
| |
| |
| |
| bool |
| StylesheetHandler::processSpaceAttr( |
| const AttributeListType& atts, |
| const LocatorType* locator, |
| bool& fPreserve) |
| { |
| const unsigned int len = atts.getLength(); |
| |
| for (unsigned int i = 0; i < len; ++i) |
| { |
| if (processSpaceAttr(atts.getName(i), atts, i, locator, fPreserve) == true) |
| { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| |
| |
| void |
| StylesheetHandler::startElement( |
| const XMLCh* const name, |
| AttributeListType& atts) |
| { |
| m_inExtensionElementStack.push_back(false); |
| |
| if (m_preserveSpaceStack.empty() == true) |
| { |
| m_preserveSpaceStack.push_back(false); |
| } |
| else |
| { |
| m_preserveSpaceStack.push_back(m_preserveSpaceStack.back()); |
| } |
| |
| try |
| { |
| // By default, space is not preserved... |
| bool fPreserveSpace = false; |
| bool fSpaceAttrProcessed = false; |
| |
| processAccumulatedText(); |
| |
| m_whiteSpaceElems.clear(); |
| |
| const LocatorType* const locator = m_constructionContext.getLocatorFromStack(); |
| |
| // First push namespaces |
| m_stylesheet.pushNamespaces(atts); |
| |
| const XalanDOMString::size_type nameLength = length(name); |
| const XalanDOMString::size_type index = indexOf(name, XalanUnicode::charColon); |
| |
| const XalanDOMString* ns = getNamespaceFromStack(name); |
| |
| if(ns == 0) |
| { |
| if (index < nameLength) |
| { |
| error(XalanMessageLoader::getMessage(XalanMessages::CannotResolvePrefix_1Param, name), locator); |
| } |
| else |
| { |
| ns = &s_emptyString; |
| } |
| } |
| assert(ns != 0); |
| |
| if (index < nameLength) |
| { |
| m_elementLocalName.assign(name + index + 1, nameLength - index - 1); |
| } |
| else |
| { |
| m_elementLocalName.assign(name, nameLength); |
| } |
| |
| ElemTemplateElement* elem = 0; |
| |
| const ElemTemplateStackType::size_type origStackSize = m_elemStack.size(); |
| |
| if(equals(*ns, m_constructionContext.getXSLTNamespaceURI())) |
| { |
| if(!isEmpty(m_stylesheet.getXSLTNamespaceURI())) |
| m_stylesheet.setXSLTNamespaceURI(*ns); |
| |
| const StylesheetConstructionContext::eElementToken xslToken = |
| m_constructionContext.getElementToken(m_elementLocalName); |
| |
| if(!m_inTemplate) |
| { |
| processTopLevelElement(name, atts, xslToken, locator, fPreserveSpace, fSpaceAttrProcessed); |
| } |
| else |
| { |
| switch(xslToken) |
| { |
| case StylesheetConstructionContext::ELEMNAME_APPLY_TEMPLATES: |
| case StylesheetConstructionContext::ELEMNAME_ATTRIBUTE: |
| case StylesheetConstructionContext::ELEMNAME_CALL_TEMPLATE: |
| case StylesheetConstructionContext::ELEMNAME_CHOOSE: |
| case StylesheetConstructionContext::ELEMNAME_COMMENT: |
| case StylesheetConstructionContext::ELEMNAME_COPY: |
| case StylesheetConstructionContext::ELEMNAME_COPY_OF: |
| case StylesheetConstructionContext::ELEMNAME_ELEMENT: |
| case StylesheetConstructionContext::ELEMNAME_FALLBACK: |
| case StylesheetConstructionContext::ELEMNAME_FOR_EACH: |
| case StylesheetConstructionContext::ELEMNAME_IF: |
| case StylesheetConstructionContext::ELEMNAME_MESSAGE: |
| case StylesheetConstructionContext::ELEMNAME_NUMBER: |
| case StylesheetConstructionContext::ELEMNAME_VALUE_OF: |
| case StylesheetConstructionContext::ELEMNAME_WITH_PARAM: |
| case StylesheetConstructionContext::ELEMNAME_PI: |
| elem = m_constructionContext.createElement( |
| xslToken, |
| m_stylesheet, |
| atts, |
| locator); |
| assert(elem != 0); |
| break; |
| |
| case StylesheetConstructionContext::ELEMNAME_PARAM: |
| elem = m_constructionContext.createElement( |
| xslToken, |
| m_stylesheet, |
| atts, |
| locator); |
| |
| checkForOrAddVariableName(elem->getNameAttribute(), locator); |
| |
| assert(elem != 0); |
| break; |
| |
| case StylesheetConstructionContext::ELEMNAME_SORT: |
| { |
| if (m_elemStack.empty() == true) |
| { |
| error(XalanMessageLoader::getMessage(XalanMessages::IsNotAllowedInThisPosition_1Param,Constants::ELEMNAME_SORT_WITH_PREFIX_STRING), locator); |
| } |
| |
| ElemTemplateElement* const theElement = |
| m_elemStack.back(); |
| assert(theElement != 0); |
| |
| theElement->processSortElement( |
| m_constructionContext, |
| m_stylesheet, |
| atts, |
| locator); |
| |
| m_elemStack.push_back( |
| m_elemEmptyAllocator.create( |
| m_constructionContext, |
| m_stylesheet, |
| &Constants::ELEMNAME_SORT_WITH_PREFIX_STRING)); |
| } |
| break; |
| |
| case StylesheetConstructionContext::ELEMNAME_APPLY_IMPORTS: |
| { |
| if (m_elemStack.empty() == true) |
| { |
| error(XalanMessageLoader::getMessage(XalanMessages::IsNotAllowedInThisPosition_1Param,Constants::ELEMNAME_APPLY_IMPORTS_WITH_PREFIX_STRING), locator); |
| } |
| |
| ElemTemplateElement* const theElement = |
| m_elemStack.back(); |
| assert(theElement != 0); |
| |
| const int parentToken = |
| theElement->getXSLToken(); |
| |
| if (parentToken == StylesheetConstructionContext::ELEMNAME_FOR_EACH) |
| { |
| error(XalanMessageLoader::getMessage(XalanMessages::IsNotAllowedInThisPosition_1Param,Constants::ELEMNAME_APPLY_IMPORTS_WITH_PREFIX_STRING), locator); |
| } |
| |
| elem = m_constructionContext.createElement( |
| xslToken, |
| m_stylesheet, |
| atts, |
| locator); |
| assert(elem != 0); |
| } |
| break; |
| |
| case StylesheetConstructionContext::ELEMNAME_VARIABLE: |
| { |
| elem = |
| m_constructionContext.createElement( |
| xslToken, |
| m_stylesheet, |
| atts, |
| locator); |
| assert(elem != 0); |
| |
| checkForOrAddVariableName(elem->getNameAttribute(), locator); |
| } |
| break; |
| |
| case StylesheetConstructionContext::ELEMNAME_WHEN: |
| { |
| ElemTemplateElement* const parent = m_elemStack.back(); |
| |
| if(StylesheetConstructionContext::ELEMNAME_CHOOSE != parent->getXSLToken()) |
| { |
| error(XalanMessageLoader::getMessage(XalanMessages::NotParentedBy_2Param, |
| Constants::ELEMNAME_WHEN_WITH_PREFIX_STRING,Constants::ELEMNAME_CHOOSE_WITH_PREFIX_STRING), locator); |
| } |
| else |
| { |
| ElemTemplateElement* const lastChild = parent->getLastChildElem(); |
| |
| if(0 == lastChild || |
| StylesheetConstructionContext::ELEMNAME_WHEN == lastChild->getXSLToken() || |
| lastChild->isWhitespace() == true) |
| { |
| elem = m_constructionContext.createElement( |
| xslToken, |
| m_stylesheet, |
| atts, |
| locator); |
| assert(elem != 0); |
| } |
| else |
| { |
| error(XalanMessageLoader::getMessage(XalanMessages::Misplaced_1Param,Constants::ELEMNAME_WHEN_WITH_PREFIX_STRING), locator); |
| } |
| } |
| } |
| break; |
| |
| case StylesheetConstructionContext::ELEMNAME_OTHERWISE: |
| { |
| ElemTemplateElement* parent = m_elemStack.back(); |
| |
| if(StylesheetConstructionContext::ELEMNAME_CHOOSE != parent->getXSLToken()) |
| { |
| error(XalanMessageLoader::getMessage(XalanMessages::NotParentedBy_2Param |
| ,Constants::ELEMNAME_OTHERWISE_WITH_PREFIX_STRING |
| ,Constants::ELEMNAME_CHOOSE_WITH_PREFIX_STRING), locator); |
| } |
| else |
| { |
| ElemTemplateElement* lastChild = parent->getLastChildElem(); |
| |
| if(0 == lastChild || |
| StylesheetConstructionContext::ELEMNAME_WHEN == lastChild->getXSLToken() || |
| lastChild->isWhitespace() == true) |
| { |
| elem = m_constructionContext.createElement( |
| xslToken, |
| m_stylesheet, |
| atts, |
| locator); |
| assert(elem != 0); |
| } |
| else |
| { |
| error(XalanMessageLoader::getMessage(XalanMessages::Misplaced_1Param, Constants::ELEMNAME_OTHERWISE_WITH_PREFIX_STRING), locator); |
| } |
| } |
| } |
| break; |
| |
| case StylesheetConstructionContext::ELEMNAME_TEXT: |
| m_elemStack.push_back( |
| m_elemTextAllocator.create( |
| m_constructionContext, |
| m_stylesheet, |
| atts, |
| XalanLocator::getLineNumber(locator), |
| XalanLocator::getColumnNumber(locator))); |
| |
| // This fixes Bugzilla 26354, but it's really a workaround |
| // for the bizarre way we handle literal text in the |
| // stylesheet. We should examine this strategy, because |
| // an xml:space attribute on an xsl:text element results |
| // in building a stylesheet that tries to parent an |
| // ElenTextLiteral instance to an ElemText instance, which |
| // should not ever happen. |
| fSpaceAttrProcessed = true; |
| break; |
| |
| case StylesheetConstructionContext::ELEMNAME_TEMPLATE: |
| case StylesheetConstructionContext::ELEMNAME_ATTRIBUTE_SET: |
| case StylesheetConstructionContext::ELEMNAME_EXTENSION: |
| case StylesheetConstructionContext::ELEMNAME_EXTENSION_HANDLER: |
| case StylesheetConstructionContext::ELEMNAME_KEY: |
| case StylesheetConstructionContext::ELEMNAME_IMPORT: |
| case StylesheetConstructionContext::ELEMNAME_INCLUDE: |
| case StylesheetConstructionContext::ELEMNAME_PRESERVE_SPACE: |
| case StylesheetConstructionContext::ELEMNAME_STRIP_SPACE: |
| case StylesheetConstructionContext::ELEMNAME_DECIMAL_FORMAT: |
| { |
| error(XalanMessageLoader::getMessage(XalanMessages::IsNotAllowedInsideTemplate_1Param, name), locator); |
| } |
| break; |
| |
| default: |
| { |
| // If this stylesheet is declared to be of a higher version than the one |
| // supported, don't flag an error. |
| if(m_constructionContext.getXSLTVersionSupported() < m_stylesheet.getXSLTVerDeclared()) |
| { |
| warn(XalanMessageLoader::getMessage(XalanMessages::UnknownXSLElement_1Param, name), locator); |
| |
| elem = m_constructionContext.createElement( |
| StylesheetConstructionContext::ELEMNAME_FORWARD_COMPATIBLE, |
| m_stylesheet, |
| name, |
| atts, |
| locator); |
| } |
| else |
| { |
| error(XalanMessageLoader::getMessage(XalanMessages::UnknownXSLElement_1Param, name), locator); |
| } |
| } |
| } |
| |
| m_inScopeVariableNamesStack.resize(m_inScopeVariableNamesStack.size() + 1); |
| } |
| } |
| else if (!m_inTemplate && startsWith(*ns, m_constructionContext.getXalanXSLNameSpaceURL())) |
| { |
| processExtensionElement(name, m_elementLocalName, atts, locator); |
| } |
| else |
| { |
| if(!m_inTemplate) |
| { |
| // If it's a top level |
| if (!m_foundStylesheet) |
| { |
| elem = initWrapperless(name, atts, locator); |
| } |
| else if (length(*ns) == 0 && m_elemStack.size() == 1) |
| { |
| error(XalanMessageLoader::getMessage(XalanMessages::IllegalTopLevelElement), locator); |
| } |
| else |
| { |
| m_inExtensionElementStack.back() = true; |
| } |
| } |
| else |
| { |
| m_inScopeVariableNamesStack.resize(m_inScopeVariableNamesStack.size() + 1); |
| |
| // BEGIN SANJIVA CODE |
| // is this an extension element call? |
| ExtensionNSHandler* nsh = 0; |
| |
| if (!isEmpty(*ns) && |
| ((nsh = m_stylesheet.lookupExtensionNSHandler(*ns)) != 0)) |
| { |
| elem = m_constructionContext.createElement( |
| m_stylesheet, |
| name, |
| atts, |
| *nsh, |
| locator); |
| assert(m_inExtensionElementStack.empty() == false); |
| |
| m_inExtensionElementStack.back() = true; |
| } |
| else |
| { |
| elem = m_constructionContext.createElement( |
| StylesheetConstructionContext::ELEMNAME_LITERAL_RESULT, |
| m_stylesheet, |
| name, |
| atts, |
| locator); |
| } |
| |
| assert(elem != 0); |
| } |
| } |
| |
| if(m_inTemplate && 0 != elem) |
| { |
| if(!m_elemStack.empty()) |
| { |
| appendChildElementToParent(elem, locator); |
| } |
| |
| m_elemStack.push_back(elem); |
| } |
| |
| // If we haven't processed an xml:space attribute already, look for one... |
| if (fSpaceAttrProcessed == false) |
| { |
| fSpaceAttrProcessed = processSpaceAttr(atts, locator, fPreserveSpace); |
| } |
| |
| // Only update the stack if we actually processed an xml:space attribute... |
| if (fSpaceAttrProcessed == true) |
| { |
| // Set the preserve value... |
| m_preserveSpaceStack.back() = fPreserveSpace; |
| } |
| |
| // If for some reason something didn't get pushed, push an empty |
| // object. |
| if(origStackSize == m_elemStack.size()) |
| { |
| m_elemStack.push_back(m_elemEmptyAllocator.create(m_constructionContext, m_stylesheet)); |
| } |
| } // end try |
| catch(...) |
| { |
| doCleanup(); |
| |
| throw; |
| } |
| } |
| |
| |
| |
| ElemTemplateElement* |
| StylesheetHandler::initWrapperless( |
| const XalanDOMChar* name, |
| const AttributeListType& atts, |
| const LocatorType* locator) |
| { |
| assert(m_pTemplate == 0); |
| |
| m_pTemplate = m_stylesheet.initWrapperless(m_constructionContext, locator); |
| assert(m_pTemplate != 0); |
| |
| ElemTemplateElement* const pElem = |
| m_constructionContext.createElement( |
| StylesheetConstructionContext::ELEMNAME_LITERAL_RESULT, |
| m_stylesheet, |
| name, |
| atts, |
| locator); |
| |
| m_pTemplate->appendChildElem(pElem); |
| m_inTemplate = true; |
| |
| m_inScopeVariableNamesStack.resize(m_inScopeVariableNamesStack.size() + 1); |
| |
| m_foundStylesheet = true; |
| |
| // This attempts to optimize for a literal result element with |
| // the name HTML, so we don't have to switch on-the-fly. |
| if(equalsIgnoreCaseASCII(name, Constants::ELEMNAME_HTML_STRING) == true) |
| { |
| // If there's a default namespace, then we must output XML. |
| // Otherwise, we'll set the output method to HTML. |
| if (atts.getValue(c_wstr(DOMServices::s_XMLNamespace)) == 0) |
| { |
| m_stylesheet.getStylesheetRoot().setIndentResult(true); |
| m_stylesheet.getStylesheetRoot().setOutputMethod(OUTPUT_METHOD_HTML); |
| } |
| } |
| |
| return pElem; |
| } |
| |
| |
| |
| const XalanDOMString* |
| StylesheetHandler::getNamespaceFromStack(const XalanDOMChar* theName) const |
| { |
| return m_stylesheet.getNamespaceFromStack(theName); |
| } |
| |
| |
| |
| const XalanDOMString* |
| StylesheetHandler::getNamespaceForPrefixFromStack(const XalanDOMString& thePrefix) const |
| { |
| return m_stylesheet.getNamespaceForPrefixFromStack(thePrefix); |
| } |
| |
| |
| |
| void |
| StylesheetHandler::processTopLevelElement( |
| const XalanDOMChar* name, |
| const AttributeListType& atts, |
| int xslToken, |
| const LocatorType* locator, |
| bool& fPreserveSpace, |
| bool& fSpaceAttrProcessed) |
| { |
| if(m_foundStylesheet && StylesheetConstructionContext::ELEMNAME_IMPORT != xslToken) |
| { |
| m_foundNotImport = true; |
| } |
| |
| switch(xslToken) |
| { |
| case StylesheetConstructionContext::ELEMNAME_TEMPLATE: |
| assert(m_pTemplate == 0); |
| |
| m_pTemplate = |
| m_constructionContext.createElement( |
| StylesheetConstructionContext::ELEMNAME_TEMPLATE, |
| m_stylesheet, |
| atts, |
| locator); |
| |
| m_elemStack.push_back(m_pTemplate); |
| m_inTemplate = true; |
| m_inScopeVariableNamesStack.resize(m_inScopeVariableNamesStack.size() + 1); |
| break; |
| |
| case StylesheetConstructionContext::ELEMNAME_VARIABLE: |
| case StylesheetConstructionContext::ELEMNAME_PARAM: |
| { |
| ElemTemplateElement* const elem = m_constructionContext.createElement( |
| xslToken, |
| m_stylesheet, |
| atts, |
| locator); |
| assert(elem != 0); |
| |
| checkForOrAddVariableName(elem->getNameAttribute(), locator); |
| |
| m_elemStack.push_back(elem); |
| m_inTemplate = true; // fake it out |
| m_inScopeVariableNamesStack.resize(m_inScopeVariableNamesStack.size() + 1); |
| elem->addToStylesheet(m_constructionContext, m_stylesheet); |
| } |
| break; |
| |
| case StylesheetConstructionContext::ELEMNAME_PRESERVE_SPACE: |
| case StylesheetConstructionContext::ELEMNAME_STRIP_SPACE: |
| processPreserveStripSpace(name, atts, locator, xslToken); |
| break; |
| |
| case StylesheetConstructionContext::ELEMNAME_KEY: |
| { |
| m_stylesheet.processKeyElement( |
| XalanQName::PrefixResolverProxy(m_stylesheet.getNamespaces(), m_stylesheet.getURI()), |
| atts, |
| locator, |
| m_constructionContext); |
| } |
| break; |
| |
| case StylesheetConstructionContext::ELEMNAME_ATTRIBUTE_SET: |
| { |
| m_inTemplate = true; // fake it out |
| m_inScopeVariableNamesStack.resize(m_inScopeVariableNamesStack.size() + 1); |
| |
| ElemTemplateElement* const theAttributeSet = |
| m_constructionContext.createElement( |
| xslToken, |
| m_stylesheet, |
| atts, |
| locator); |
| |
| theAttributeSet->addToStylesheet(m_constructionContext, m_stylesheet); |
| |
| m_elemStack.push_back(theAttributeSet); |
| } |
| break; |
| |
| case StylesheetConstructionContext::ELEMNAME_INCLUDE: |
| processInclude(name, atts, locator); |
| break; |
| |
| case StylesheetConstructionContext::ELEMNAME_IMPORT: |
| processImport(name, atts, locator); |
| break; |
| |
| case StylesheetConstructionContext::ELEMNAME_OUTPUT: |
| m_stylesheet.getStylesheetRoot().processOutputSpec(name, atts, m_constructionContext); |
| break; |
| |
| case StylesheetConstructionContext::ELEMNAME_DECIMAL_FORMAT: |
| m_stylesheet.processDecimalFormatElement( |
| m_constructionContext, |
| atts, |
| locator); |
| break; |
| |
| case StylesheetConstructionContext::ELEMNAME_NAMESPACE_ALIAS: |
| m_stylesheet.processNSAliasElement(name, atts, m_constructionContext); |
| break; |
| |
| case StylesheetConstructionContext::ELEMNAME_WITH_PARAM: |
| case StylesheetConstructionContext::ELEMNAME_ATTRIBUTE: |
| case StylesheetConstructionContext::ELEMNAME_APPLY_TEMPLATES: |
| case StylesheetConstructionContext::ELEMNAME_CHOOSE: |
| case StylesheetConstructionContext::ELEMNAME_COMMENT: |
| case StylesheetConstructionContext::ELEMNAME_COPY: |
| case StylesheetConstructionContext::ELEMNAME_COPY_OF: |
| case StylesheetConstructionContext::ELEMNAME_FOR_EACH: |
| case StylesheetConstructionContext::ELEMNAME_IF: |
| case StylesheetConstructionContext::ELEMNAME_CALL_TEMPLATE: |
| case StylesheetConstructionContext::ELEMNAME_MESSAGE: |
| case StylesheetConstructionContext::ELEMNAME_NUMBER: |
| case StylesheetConstructionContext::ELEMNAME_OTHERWISE: |
| case StylesheetConstructionContext::ELEMNAME_PI: |
| case StylesheetConstructionContext::ELEMNAME_SORT: |
| case StylesheetConstructionContext::ELEMNAME_TEXT: |
| case StylesheetConstructionContext::ELEMNAME_VALUE_OF: |
| case StylesheetConstructionContext::ELEMNAME_WHEN: |
| case StylesheetConstructionContext::ELEMNAME_ELEMENT: |
| case StylesheetConstructionContext::ELEMNAME_APPLY_IMPORTS: |
| if (inExtensionElement() == false) |
| { |
| error(XalanMessageLoader::getMessage(XalanMessages::IsNotAllowedInsideStylesheet_1Param, name), locator); |
| } |
| break; |
| |
| case StylesheetConstructionContext::ELEMNAME_STYLESHEET: |
| processStylesheet(name, atts, locator, fPreserveSpace, fSpaceAttrProcessed); |
| break; |
| |
| default: |
| if (inExtensionElement() == false) |
| { |
| if (m_constructionContext.getXSLTVersionSupported() < m_stylesheet.getXSLTVerDeclared()) |
| { |
| // Forward-compatible mode... |
| m_inExtensionElementStack.back() = true; |
| } |
| else |
| { |
| error(XalanMessageLoader::getMessage(XalanMessages::UnknownXSLElement_1Param, name), locator); |
| } |
| } |
| break; |
| } |
| } |
| |
| |
| void |
| StylesheetHandler::processStylesheet( |
| const XalanDOMChar* name, |
| const AttributeListType& atts, |
| const LocatorType* locator, |
| bool& fPreserveSpace, |
| bool& fSpaceAttrProcessed) |
| { |
| m_foundStylesheet = true; |
| |
| const unsigned int nAttrs = atts.getLength(); |
| |
| bool fVersionFound = false; |
| |
| for(unsigned int i = 0; i < nAttrs; ++i) |
| { |
| const XalanDOMChar* const aname = atts.getName(i); |
| |
| if(equals(aname, Constants::ATTRNAME_EXCLUDE_RESULT_PREFIXES)) |
| { |
| m_stylesheet.processExcludeResultPrefixes(m_constructionContext, atts.getValue(i)); |
| } |
| else if(equals(aname, Constants::ATTRNAME_EXTENSIONELEMENTPREFIXES)) |
| { |
| const GetAndReleaseCachedString theGuard(m_constructionContext); |
| |
| XalanDOMString& prefix = theGuard.get(); |
| |
| StringTokenizer tokenizer(atts.getValue(i), |
| Constants::DEFAULT_WHITESPACE_SEPARATOR_STRING); |
| |
| while(tokenizer.hasMoreTokens() == true) |
| { |
| tokenizer.nextToken(prefix); |
| |
| const XalanDOMString* const extns = getNamespaceForPrefixFromStack(prefix); |
| |
| if (extns == 0) |
| { |
| error( |
| XalanMessageLoader::getMessage( |
| XalanMessages::PrefixMustResolveToNamespace_1Param, |
| prefix), |
| locator); |
| } |
| |
| m_stylesheet.processExtensionNamespace(m_constructionContext, *extns); |
| } |
| } |
| else if(equals(aname, Constants::ATTRNAME_ID)) |
| { |
| // |
| } |
| else if(equals(aname, Constants::ATTRNAME_VERSION)) |
| { |
| const XalanDOMChar* const versionStr = atts.getValue(i); |
| assert(versionStr != 0); |
| |
| m_stylesheet.setXSLTVerDeclared(DoubleSupport::toDouble(versionStr)); |
| |
| fVersionFound = true; |
| } |
| else if(processSpaceAttr(aname, atts, i, locator, fPreserveSpace) == true) |
| { |
| fSpaceAttrProcessed = true; |
| } |
| else if(isAttrOK(aname, atts, i) == false) |
| { |
| if(false == m_stylesheet.isWrapperless()) |
| { |
| illegalAttributeError(name, aname, locator); |
| } |
| } |
| |
| if(!m_stylesheet.getNamespaces().empty()) |
| { |
| m_stylesheet.setNamespaceDecls(m_stylesheet.getNamespaces().back()); |
| } |
| } |
| |
| if (fVersionFound == false) |
| { |
| error(XalanMessageLoader::getMessage(XalanMessages::StylesheetAttribDidNotSpecifyVersionAttrib), locator); |
| } |
| } |
| |
| |
| |
| void |
| StylesheetHandler::processExtensionElement( |
| const XalanDOMChar* /* name */, |
| const XalanDOMString& /* localName */, |
| const AttributeListType& /* atts */, |
| const LocatorType* /* locator */) |
| { |
| } |
| |
| |
| |
| void |
| StylesheetHandler::checkForOrAddVariableName( |
| const XalanQName& theVariableName, |
| const LocatorType* theLocator) |
| { |
| if (m_inTemplate == false) |
| { |
| assert(m_inScopeVariableNamesStack.empty() == true); |
| |
| if (m_globalVariableNames.count(theVariableName) != 0) |
| { |
| error(XalanMessageLoader::getMessage(XalanMessages::VariableHasBeenDeclared), theLocator); |
| } |
| else |
| { |
| m_globalVariableNames.insert(theVariableName); |
| } |
| } |
| else |
| { |
| assert(m_inScopeVariableNamesStack.empty() == false); |
| |
| QNameSetVectorType::iterator theCurrent = m_inScopeVariableNamesStack.begin(); |
| const QNameSetVectorType::iterator theEnd = m_inScopeVariableNamesStack.end(); |
| |
| while(theCurrent != theEnd) |
| { |
| QNameSetVectorType::value_type theLocalScope = *theCurrent; |
| |
| if (theLocalScope.count(theVariableName) != 0) |
| { |
| error(XalanMessageLoader::getMessage(XalanMessages::VariableHasBeenDeclaredInThisTemplate), theLocator); |
| } |
| |
| ++theCurrent; |
| } |
| |
| assert(theCurrent == theEnd); |
| |
| m_inScopeVariableNamesStack.back().insert(theVariableName); |
| } |
| } |
| |
| |
| |
| void |
| StylesheetHandler::processPreserveStripSpace( |
| const XalanDOMChar* name, |
| const AttributeListType& atts, |
| const LocatorType* locator, |
| int xslToken) |
| { |
| const unsigned int nAttrs = atts.getLength(); |
| |
| bool foundIt = false; |
| |
| const bool isPreserveSpace = StylesheetConstructionContext::ELEMNAME_PRESERVE_SPACE == xslToken? true : false; |
| |
| for(unsigned int i = 0; i < nAttrs; i++) |
| { |
| const XalanDOMChar* const aname = atts.getName(i); |
| |
| if(equals(aname, Constants::ATTRNAME_ELEMENTS)) |
| { |
| foundIt = true; |
| |
| StringTokenizer tokenizer(atts.getValue(i), |
| Constants::DEFAULT_WHITESPACE_SEPARATOR_STRING); |
| |
| const GetAndReleaseCachedString theGuard(m_constructionContext); |
| |
| XalanDOMString& theNameTest = theGuard.get(); |
| |
| const XalanQName::PrefixResolverProxy theProxy(m_stylesheet.getNamespaces(), m_stylesheet.getURI()); |
| |
| while(tokenizer.hasMoreTokens()) |
| { |
| tokenizer.nextToken(theNameTest); |
| |
| m_stylesheet.addWhitespaceElement( |
| XalanSpaceNodeTester( |
| isPreserveSpace == true ? |
| XalanSpaceNodeTester::ePreserve : |
| XalanSpaceNodeTester::eStrip, |
| m_constructionContext, |
| theNameTest, |
| theProxy, |
| locator)); |
| } |
| } |
| else if(!isAttrOK(aname, atts, i)) |
| { |
| illegalAttributeError(name, aname, locator); |
| } |
| } |
| |
| if(!foundIt && inExtensionElement() == false) |
| { |
| error( |
| XalanMessageLoader::getMessage( |
| XalanMessages::ElementRequiresAttribute_2Param, |
| isPreserveSpace == true ? |
| Constants::ELEMNAME_PRESERVESPACE_WITH_PREFIX_STRING : |
| Constants::ELEMNAME_STRIPSPACE_WITH_PREFIX_STRING, |
| Constants::ATTRNAME_ELEMENTS), |
| locator); |
| } |
| } |
| |
| |
| |
| void |
| StylesheetHandler::appendChildElementToParent( |
| ElemTemplateElement* parent, |
| ElemTemplateElement* elem) |
| { |
| assert(elem != 0); |
| |
| appendChildElementToParent(parent, elem, elem->getLocator()); |
| } |
| |
| |
| |
| void |
| StylesheetHandler::appendChildElementToParent( |
| ElemTemplateElement* elem, |
| const LocatorType* locator) |
| { |
| appendChildElementToParent(m_elemStack.back(), elem, locator); |
| } |
| |
| |
| |
| void |
| StylesheetHandler::appendChildElementToParent( |
| ElemTemplateElement* parent, |
| ElemTemplateElement* elem, |
| const LocatorType* locator) |
| { |
| assert(parent != 0 && elem != 0); |
| |
| try |
| { |
| parent->appendChildElem(elem); |
| } |
| catch(const XalanDOMException& e) |
| { |
| if (e.getExceptionCode() == XalanDOMException::HIERARCHY_REQUEST_ERR) |
| { |
| if (elem->getXSLToken() == StylesheetConstructionContext::ELEMNAME_TEXT_LITERAL_RESULT) |
| { |
| error( |
| XalanMessageLoader::getMessage(XalanMessages::ElemOrLTIsNotAllowed_1Param, elem->getElementName()), |
| locator); |
| } |
| else |
| { |
| error( |
| XalanMessageLoader::getMessage(XalanMessages::ElemIsNotAllowed_1Param, elem->getElementName()), |
| locator); |
| } |
| } |
| } |
| } |
| |
| |
| |
| void |
| StylesheetHandler::doCleanup() |
| { |
| if (m_locatorsPushed > 0) |
| { |
| m_constructionContext.popLocatorStack(); |
| |
| --m_locatorsPushed; |
| } |
| |
| m_lastPopped = 0; |
| } |
| |
| |
| |
| static bool |
| stackContains( |
| const Stylesheet::URLStackType& stack, |
| const XalanDOMString& urlString) |
| { |
| const Stylesheet::URLStackType::size_type n = stack.size(); |
| |
| bool contains = false; |
| |
| for(Stylesheet::URLStackType::size_type i = 0; i < n && contains == false; ++i) |
| { |
| if(equals(stack[i], urlString)) |
| { |
| contains = true; |
| } |
| } |
| |
| return contains; |
| } |
| |
| |
| |
| void |
| StylesheetHandler::processImport( |
| const XalanDOMChar* name, |
| const AttributeListType& atts, |
| const LocatorType* locator) |
| { |
| const unsigned int nAttrs = atts.getLength(); |
| |
| bool foundIt = false; |
| |
| for(unsigned int i = 0; i < nAttrs; i++) |
| { |
| const XalanDOMChar* const aname = atts.getName(i); |
| |
| if(equals(aname, Constants::ATTRNAME_HREF)) |
| { |
| foundIt = true; |
| |
| if(m_foundNotImport) |
| { |
| error(XalanMessageLoader::getMessage(XalanMessages::ImportCanOnlyOccur), locator); |
| } |
| |
| const GetAndReleaseCachedString theGuard1(m_constructionContext); |
| |
| XalanDOMString& saved_XSLNameSpaceURL = theGuard1.get(); |
| |
| saved_XSLNameSpaceURL = m_stylesheet.getXSLTNamespaceURI(); |
| |
| const GetAndReleaseCachedString theGuard2(m_constructionContext); |
| |
| XalanDOMString& href = theGuard2.get(); |
| |
| href = atts.getValue(i); |
| |
| Stylesheet::URLStackType& includeStack = m_stylesheet.getIncludeStack(); |
| assert(includeStack.empty() == false); |
| |
| const XalanDOMString hrefUrl = m_constructionContext.getURLStringFromString(href, includeStack.back()); |
| assert(length(hrefUrl) != 0); |
| |
| Stylesheet::URLStackType& importStack = m_stylesheet.getStylesheetRoot().getImportStack(); |
| |
| if(stackContains(importStack, hrefUrl)) |
| { |
| error(XalanMessageLoader::getMessage(XalanMessages::ImportingItself_1Param, hrefUrl), locator); |
| } |
| |
| importStack.push_back(hrefUrl); |
| |
| // This will take care of cleaning up the stylesheet if an exception |
| // is thrown. |
| XalanAutoPtr<Stylesheet> importedStylesheet( |
| m_constructionContext.create( |
| m_stylesheet.getStylesheetRoot(), |
| hrefUrl)); |
| |
| StylesheetHandler tp(*importedStylesheet.get(), m_constructionContext); |
| |
| m_constructionContext.parseXML(hrefUrl, &tp, 0); |
| |
| // Add it to the imports, releasing the XalanAutoPtr... |
| m_stylesheet.addImport(importedStylesheet.get()); |
| |
| importedStylesheet.release(); |
| |
| assert(equals(importStack.back(), hrefUrl)); |
| importStack.pop_back(); |
| |
| m_stylesheet.setXSLTNamespaceURI(saved_XSLNameSpaceURL); |
| } |
| else if(!isAttrOK(aname, atts, i)) |
| { |
| illegalAttributeError(name, aname, locator); |
| } |
| } |
| |
| if(!foundIt) |
| { |
| error( |
| XalanMessageLoader::getMessage( |
| XalanMessages::ElementRequiresAttribute_2Param, |
| Constants::ELEMNAME_IMPORT_WITH_PREFIX_STRING, |
| Constants::ATTRNAME_HREF), |
| locator); |
| } |
| } |
| |
| |
| |
| void |
| StylesheetHandler::processInclude( |
| const XalanDOMChar* name, |
| const AttributeListType& atts, |
| const LocatorType* locator) |
| { |
| const unsigned int nAttrs = atts.getLength(); |
| |
| bool foundIt = false; |
| |
| for(unsigned int i = 0; i < nAttrs; i++) |
| { |
| const XalanDOMChar* const aname = atts.getName(i); |
| |
| if(equals(aname, Constants::ATTRNAME_HREF)) |
| { |
| foundIt = true; |
| |
| PushPopIncludeState theStateHandler(*this); |
| |
| const XalanDOMString href(atts.getValue(i)); |
| |
| assert(c_wstr(m_stylesheet.getIncludeStack().back()) != 0); |
| const XalanDOMString hrefUrl = m_constructionContext.getURLStringFromString(href, m_stylesheet.getIncludeStack().back()); |
| |
| if(stackContains(m_stylesheet.getIncludeStack(), hrefUrl)) |
| { |
| |
| error(XalanMessageLoader::getMessage(XalanMessages::IncludingItself_1Param,hrefUrl) , locator); |
| } |
| |
| m_stylesheet.getIncludeStack().push_back(hrefUrl); |
| |
| m_constructionContext.parseXML(hrefUrl, this, 0); |
| |
| assert(equals(m_stylesheet.getIncludeStack().back(), hrefUrl)); |
| m_stylesheet.getIncludeStack().pop_back(); |
| } |
| else if(!isAttrOK(aname, atts, i)) |
| { |
| illegalAttributeError(name, aname, locator); |
| } |
| } |
| |
| if(!foundIt) |
| { |
| error( |
| XalanMessageLoader::getMessage( |
| XalanMessages::ElementRequiresAttribute_2Param, |
| Constants::ELEMNAME_INCLUDE_WITH_PREFIX_STRING, |
| Constants::ATTRNAME_HREF), |
| locator); |
| } |
| } |
| |
| |
| |
| void |
| StylesheetHandler::endElement(const XMLCh* const /* name */) |
| { |
| processAccumulatedText(); |
| |
| m_whiteSpaceElems.clear(); |
| |
| m_stylesheet.popNamespaces(); |
| |
| assert(m_elemStack.empty() == false); |
| |
| m_lastPopped = m_elemStack.back(); |
| |
| assert(m_lastPopped != 0); |
| |
| m_elemStack.pop_back(); |
| m_lastPopped->setFinishedConstruction(true); |
| |
| const int tok = m_lastPopped->getXSLToken(); |
| |
| if (m_inTemplate == true) |
| { |
| assert(m_inScopeVariableNamesStack.empty() == false); |
| |
| m_inScopeVariableNamesStack.pop_back(); |
| } |
| |
| if(StylesheetConstructionContext::ELEMNAME_TEMPLATE == tok) |
| { |
| m_inTemplate = false; |
| m_pTemplate->addToStylesheet(m_constructionContext, m_stylesheet); |
| m_pTemplate = 0; |
| } |
| else if((StylesheetConstructionContext::ELEMNAME_PARAM == tok) || |
| StylesheetConstructionContext::ELEMNAME_VARIABLE == tok) |
| { |
| if(m_lastPopped->getParentNodeElem() == 0) |
| { |
| // Top-level param or variable |
| m_inTemplate = false; |
| } |
| } |
| else if(StylesheetConstructionContext::ELEMNAME_ATTRIBUTE_SET == tok) |
| { |
| m_inTemplate = false; |
| } |
| |
| assert(m_inExtensionElementStack.empty() == false); |
| |
| m_inExtensionElementStack.pop_back(); |
| |
| assert(m_preserveSpaceStack.empty() == false); |
| |
| m_preserveSpaceStack.pop_back(); |
| } |
| |
| |
| |
| void |
| StylesheetHandler::characters( |
| const XMLCh* const chars, |
| const unsigned int length) |
| { |
| if (m_inTemplate == false && |
| inExtensionElement() == false && |
| isXMLWhitespace(chars, 0, length) == false) |
| { |
| error( |
| XalanMessageLoader::getMessage(XalanMessages::CharIsNotAllowedInStylesheet), |
| m_constructionContext.getLocatorFromStack()); |
| |
| } |
| else |
| { |
| accumulateText(chars, length); |
| } |
| } |
| |
| |
| |
| void |
| StylesheetHandler::cdata( |
| const XMLCh* const chars, |
| const unsigned int length) |
| { |
| accumulateText(chars, length); |
| |
| processText(chars, length); |
| |
| m_lastPopped = 0; |
| } |
| |
| |
| |
| void |
| StylesheetHandler::ignorableWhitespace( |
| const XMLCh* const /*chars*/, |
| const unsigned int /*length*/) |
| { |
| // Ignore! |
| m_lastPopped = 0; |
| } |
| |
| |
| |
| void |
| StylesheetHandler::processingInstruction( |
| const XMLCh* const /*target*/, |
| const XMLCh* const /*data*/) |
| { |
| if (isXMLWhitespace(m_accumulateText) == false) |
| { |
| processAccumulatedText(); |
| } |
| else |
| { |
| clear(m_accumulateText); |
| } |
| } |
| |
| |
| |
| void |
| StylesheetHandler::comment(const XMLCh* const /*data*/) |
| { |
| processAccumulatedText(); |
| } |
| |
| |
| |
| void |
| StylesheetHandler::entityReference(const XMLCh* const /*name*/) |
| { |
| processAccumulatedText(); |
| } |
| |
| |
| |
| void |
| StylesheetHandler::resetDocument() |
| { |
| clear(m_accumulateText); |
| } |
| |
| |
| |
| void |
| StylesheetHandler::charactersRaw( |
| const XMLCh* const /* chars */, |
| const unsigned int /* length */) |
| { |
| } |
| |
| |
| |
| void |
| StylesheetHandler::processText( |
| const XMLCh* chars, |
| XalanDOMString::size_type length) |
| { |
| if(m_inTemplate) |
| { |
| ElemTemplateElement* parent = m_elemStack.back(); |
| assert(parent != 0); |
| |
| assert(m_preserveSpaceStack.empty() == false); |
| |
| bool preserveSpace = m_preserveSpaceStack.back(); |
| bool disableOutputEscaping = false; |
| |
| if (preserveSpace == false && parent->getXSLToken() == StylesheetConstructionContext::ELEMNAME_TEXT) |
| { |
| #if defined(XALAN_OLD_STYLE_CASTS) |
| disableOutputEscaping = ((ElemText*)parent)->getDisableOutputEscaping(); |
| #else |
| disableOutputEscaping = static_cast<ElemText*>(parent)->getDisableOutputEscaping(); |
| #endif |
| preserveSpace = true; |
| |
| parent = m_elemStack[m_elemStack.size() - 2]; |
| } |
| |
| const LocatorType* const locator = m_constructionContext.getLocatorFromStack(); |
| |
| ElemTemplateElement* const elem = |
| m_constructionContext.createElement( |
| m_stylesheet, |
| chars, |
| length, |
| preserveSpace, |
| disableOutputEscaping, |
| locator); |
| assert(elem != 0); |
| |
| const bool isWhite = elem->isWhitespace(); |
| |
| if(preserveSpace || (!preserveSpace && !isWhite)) |
| { |
| while(!m_whiteSpaceElems.empty()) |
| { |
| assert(m_whiteSpaceElems.back() != 0); |
| |
| appendChildElementToParent( |
| parent, |
| m_whiteSpaceElems.back()); |
| |
| m_whiteSpaceElems.pop_back(); |
| } |
| |
| appendChildElementToParent( |
| parent, |
| elem); |
| } |
| else if(isWhite) |
| { |
| bool shouldPush = true; |
| |
| ElemTemplateElement* const last = parent->getLastChildElem(); |
| |
| if(0 != last) |
| { |
| // If it was surrounded by xsl:text, it will count as an element. |
| const bool isPrevCharData = |
| StylesheetConstructionContext::ELEMNAME_TEXT_LITERAL_RESULT == last->getXSLToken(); |
| |
| const bool isLastPoppedXSLText = (m_lastPopped != 0) && |
| (StylesheetConstructionContext::ELEMNAME_TEXT == m_lastPopped->getXSLToken()); |
| |
| if(isPrevCharData == true && isLastPoppedXSLText == false) |
| { |
| appendChildElementToParent( |
| parent, |
| elem); |
| |
| shouldPush = false; |
| } |
| } |
| |
| if(shouldPush) |
| { |
| m_whiteSpaceElems.push_back(elem); |
| } |
| } |
| } |
| // TODO: Flag error if text inside of stylesheet |
| } |
| |
| |
| |
| void |
| StylesheetHandler::accumulateText( |
| const XMLCh* chars, |
| XalanDOMString::size_type length) |
| { |
| if(m_inTemplate) |
| { |
| append(m_accumulateText, chars, length); |
| } |
| } |
| |
| |
| |
| void |
| StylesheetHandler::processAccumulatedText() |
| { |
| if (isEmpty(m_accumulateText) == false) |
| { |
| processText(m_accumulateText.c_str(), length(m_accumulateText)); |
| |
| clear(m_accumulateText); |
| } |
| } |
| |
| |
| |
| bool |
| StylesheetHandler::inExtensionElement() const |
| { |
| XALAN_USING_STD(find) |
| |
| if (!(find( |
| m_inExtensionElementStack.begin(), |
| m_inExtensionElementStack.end(), |
| true) == m_inExtensionElementStack.end())) |
| { |
| return true; |
| } |
| else |
| { |
| return false; |
| } |
| } |
| |
| |
| |
| void |
| StylesheetHandler::error( |
| const XalanDOMString& theMessage, |
| const LocatorType* theLocator) const |
| { |
| m_constructionContext.error(theMessage, 0, theLocator); |
| } |
| |
| |
| |
| void |
| StylesheetHandler::error( |
| const XalanDOMChar* theMessage1, |
| const XalanDOMChar* theMessage2, |
| const LocatorType* theLocator) const |
| { |
| const GetAndReleaseCachedString theGuard(m_constructionContext); |
| |
| XalanDOMString& msg = theGuard.get(); |
| |
| msg = theMessage1; |
| msg += theMessage2; |
| |
| error(msg, theLocator); |
| } |
| |
| |
| |
| |
| void |
| StylesheetHandler::error( |
| const XalanDOMChar* theMessage1, |
| const XalanDOMString& theMessage2, |
| const LocatorType* theLocator) const |
| { |
| error(theMessage1, theMessage2.c_str(), theLocator); |
| } |
| |
| |
| |
| void |
| StylesheetHandler::error( |
| const XalanDOMString& theMessage1, |
| const XalanDOMChar* theMessage2, |
| const LocatorType* theLocator) const |
| { |
| error(theMessage1.c_str(), theMessage2, theLocator); |
| } |
| |
| |
| |
| |
| void |
| StylesheetHandler::error( |
| const XalanDOMString& theMessage1, |
| const XalanDOMString& theMessage2, |
| const LocatorType* theLocator) const |
| { |
| error(theMessage1.c_str(), theMessage2.c_str(), theLocator); |
| } |
| |
| |
| |
| void |
| StylesheetHandler::warn( |
| const XalanDOMChar* theMessage1, |
| const XalanDOMString& theMessage2, |
| const LocatorType* theLocator) const |
| { |
| warn(theMessage1, theMessage2.c_str(), theLocator); |
| } |
| |
| void |
| StylesheetHandler::warn( |
| const XalanDOMString& theMessage, |
| const LocatorType* theLocator) const |
| { |
| m_constructionContext.warn(theMessage, 0, theLocator); |
| } |
| |
| |
| |
| void |
| StylesheetHandler::warn( |
| const XalanDOMChar* theMessage1, |
| const XalanDOMChar* theMessage2, |
| const LocatorType* theLocator) const |
| { |
| const GetAndReleaseCachedString theGuard(m_constructionContext); |
| |
| XalanDOMString& msg = theGuard.get(); |
| |
| msg = theMessage1; |
| msg += theMessage2; |
| |
| m_constructionContext.warn(msg, 0, theLocator); |
| } |
| |
| |
| |
| void |
| StylesheetHandler::illegalAttributeError( |
| const XalanDOMChar* theElementName, |
| const XalanDOMChar* theAttributeName, |
| const LocatorType* theLocator) const |
| |
| { |
| const GetAndReleaseCachedString theGuard(m_constructionContext); |
| |
| XalanDOMString& msg = theGuard.get(); |
| |
| msg = XalanMessageLoader::getMessage(XalanMessages::HasIllegalAttribute_2Param,XalanDOMString(theElementName),XalanDOMString(theAttributeName)); |
| |
| |
| error(msg, theLocator); |
| } |
| |
| |
| |
| StylesheetHandler::PushPopIncludeState::PushPopIncludeState(StylesheetHandler& theHandler) : |
| m_handler(theHandler), |
| m_elemStack(theHandler.m_elemStack), |
| m_pTemplate(theHandler.m_pTemplate), |
| m_lastPopped(theHandler), |
| m_inTemplate(theHandler.m_inTemplate), |
| m_foundStylesheet(theHandler.m_foundStylesheet), |
| m_XSLNameSpaceURL(theHandler.m_stylesheet.getXSLTNamespaceURI()), |
| m_foundNotImport(theHandler.m_foundNotImport), |
| m_namespaceDecls(), |
| m_namespaces(), |
| m_namespacesHandler(), |
| m_inExtensionElementStack() |
| { |
| clear(m_handler.m_accumulateText); |
| |
| m_handler.m_elemStack.clear(); |
| m_handler.m_pTemplate = 0; |
| |
| m_lastPopped.swap(theHandler.m_lastPopped); |
| |
| m_handler.m_inTemplate = false; |
| m_handler.m_foundStylesheet = false; |
| m_handler.m_foundNotImport = false; |
| |
| // This is much more efficient, since we're just swapping |
| // underlying data. This clears out the stack as well... |
| m_namespaceDecls.swap(theHandler.m_stylesheet.getNamespaceDecls()); |
| m_namespaces.swap(theHandler.m_stylesheet.getNamespaces()); |
| m_namespacesHandler.swap(theHandler.m_stylesheet.getNamespacesHandler()); |
| m_inExtensionElementStack.swap(theHandler.m_inExtensionElementStack); |
| m_preserveSpaceStack.swap(theHandler.m_preserveSpaceStack); |
| } |
| |
| |
| |
| StylesheetHandler::PushPopIncludeState::~PushPopIncludeState() |
| { |
| clear(m_handler.m_accumulateText); |
| m_handler.m_elemStack = m_elemStack; |
| m_handler.m_pTemplate = m_pTemplate; |
| |
| m_lastPopped.swap(m_handler.m_lastPopped); |
| |
| m_handler.m_inTemplate = m_inTemplate; |
| m_handler.m_foundStylesheet = m_foundStylesheet; |
| m_handler.m_stylesheet.setXSLTNamespaceURI(m_XSLNameSpaceURL); |
| m_handler.m_foundNotImport = m_foundNotImport; |
| |
| // This is much more efficient, since we're just swapping |
| // underlying data. |
| m_handler.m_stylesheet.getNamespaceDecls().swap(m_namespaceDecls); |
| m_handler.m_stylesheet.getNamespaces().swap(m_namespaces); |
| m_handler.m_stylesheet.getNamespacesHandler().swap(m_namespacesHandler); |
| m_handler.m_inExtensionElementStack.swap(m_inExtensionElementStack); |
| m_handler.m_preserveSpaceStack.swap(m_preserveSpaceStack); |
| } |
| |
| |
| |
| void |
| StylesheetHandler::LastPoppedHolder::cleanup() |
| { |
| if (m_lastPopped != 0) |
| { |
| const int tok = m_lastPopped->getXSLToken(); |
| |
| if (tok == StylesheetConstructionContext::ELEMNAME_UNDEFINED) |
| { |
| #if defined(XALAN_OLD_STYLE_CASTS) |
| m_stylesheetHandler.m_elemEmptyAllocator.destroy((ElemEmpty*)m_lastPopped); |
| #else |
| m_stylesheetHandler.m_elemEmptyAllocator.destroy(static_cast<ElemEmpty*>(m_lastPopped)); |
| #endif |
| } |
| else if (tok == StylesheetConstructionContext::ELEMNAME_TEXT) |
| { |
| #if defined(XALAN_OLD_STYLE_CASTS) |
| m_stylesheetHandler.m_elemTextAllocator.destroy((ElemText*)m_lastPopped); |
| #else |
| m_stylesheetHandler.m_elemTextAllocator.destroy(static_cast<ElemText*>(m_lastPopped)); |
| #endif |
| } |
| } |
| } |
| |
| |
| |
| const XalanDOMString StylesheetHandler::s_emptyString; |
| |
| |
| |
| void |
| StylesheetHandler::initialize() |
| { |
| } |
| |
| |
| |
| void |
| StylesheetHandler::terminate() |
| { |
| } |
| |
| |
| |
| XALAN_CPP_NAMESPACE_END |