blob: 63f322780c38c86267a3e0608ec83f4d5f2f8d46 [file] [log] [blame]
/*
* 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 "ElemUse.hpp"
#include <cassert>
#include <xercesc/sax/AttributeList.hpp>
#include <xalanc/PlatformSupport/StringTokenizer.hpp>
#include "Constants.hpp"
#include "ElemAttributeSet.hpp"
#include "StylesheetRoot.hpp"
#include "StylesheetConstructionContext.hpp"
XALAN_CPP_NAMESPACE_BEGIN
/**
* This acts as a superclass for ElemCopy, ElemAttributeSet,
* ElemElement, and ElemLiteralResult, on order to implement
* shared behavior the use-attribute-sets attribute.
*/
ElemUse::ElemUse(
StylesheetConstructionContext& constructionContext,
Stylesheet& stylesheetTree,
int lineNumber,
int columnNumber,
int xslToken) :
ElemTemplateElement(constructionContext,
stylesheetTree,
lineNumber,
columnNumber,
xslToken),
m_attributeSetsNames(0),
m_attributeSetsNamesCount(0)
{
}
ElemUse::~ElemUse()
{
}
const XalanDOMString&
ElemUse::getElementName() const
{
return s_emptyString;
}
void
ElemUse::postConstruction(
StylesheetConstructionContext& constructionContext,
const NamespacesHandler& theParentHandler)
{
if (m_attributeSetsNamesCount > 0)
{
canGenerateAttributes(true);
}
// OK, now we can chain-up...
ElemTemplateElement::postConstruction(constructionContext, theParentHandler);
}
#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
const ElemTemplateElement*
ElemUse::startElement(StylesheetExecutionContext& executionContext) const
{
if (m_attributeSetsNamesCount > 0)
{
assert(canGenerateAttributes() == true);
executionContext.pushInvoker(this);
executionContext.createUseAttributeSetIndexesOnStack();
return getNextAttributeSet(executionContext);
}
return 0;
}
void
ElemUse::endElement(StylesheetExecutionContext& executionContext) const
{
if (m_attributeSetsNamesCount > 0)
{
executionContext.popInvoker();
executionContext.popUseAttributeSetIndexesFromStack();
}
}
const ElemTemplateElement*
ElemUse::getNextChildElemToExecute(
StylesheetExecutionContext& executionContext,
const ElemTemplateElement* currentElem) const
{
const ElemTemplateElement* nextElement = 0;
if (m_attributeSetsNamesCount > 0)
{
nextElement = getNextAttributeSet(executionContext);
}
// no more attribute sets, check for next child element
if (0 == nextElement)
{
nextElement = ElemTemplateElement::getNextChildElemToExecute(executionContext, currentElem);
}
// if next element to execute is the first child after executing attribute set(s),
// evalute the element's AVTs first
if (0 == nextElement && currentElem->getXSLToken() == StylesheetConstructionContext::ELEMNAME_ATTRIBUTE_SET)
{
evaluateAVTs(executionContext);
nextElement = ElemTemplateElement::getFirstChildElemToExecute(executionContext);
}
return nextElement;
}
const ElemTemplateElement*
ElemUse::getFirstChildElemToExecute(
StylesheetExecutionContext& executionContext) const
{
const ElemTemplateElement* nextElement = 0;
if (m_attributeSetsNamesCount > 0)
{
// reset
executionContext.getUseAttributeSetIndexes().attributeSetNameIndex = 0;
executionContext.getUseAttributeSetIndexes().matchingAttributeSetIndex = 0;
nextElement = getNextAttributeSet(executionContext);
}
else
{
evaluateAVTs(executionContext);
}
if (0 == nextElement)
{
nextElement = ElemTemplateElement::getFirstChildElemToExecute(executionContext);
}
return nextElement;
}
const ElemTemplateElement*
ElemUse::getNextAttributeSet(
StylesheetExecutionContext& executionContext) const
{
const StylesheetRoot& theStylesheetRoot = getStylesheet().getStylesheetRoot();
StylesheetExecutionContext::UseAttributeSetIndexes& useAttributeSetIndexes = executionContext.getUseAttributeSetIndexes();
const ElemTemplateElement* attributeSet = 0;
while (0 == attributeSet &&
useAttributeSetIndexes.attributeSetNameIndex < m_attributeSetsNamesCount)
{
attributeSet = theStylesheetRoot.getAttributeSet(
executionContext,
*m_attributeSetsNames[useAttributeSetIndexes.attributeSetNameIndex],
useAttributeSetIndexes.matchingAttributeSetIndex++,
getLocator());
if (0 == attributeSet)
{
useAttributeSetIndexes.attributeSetNameIndex++;
useAttributeSetIndexes.matchingAttributeSetIndex = 0;
}
}
return attributeSet;
}
void
ElemUse::evaluateAVTs(
StylesheetExecutionContext& /*executionContext*/) const
{
}
#endif
#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
void
ElemUse::execute(StylesheetExecutionContext& executionContext) const
{
doExecute(executionContext, true);
}
void
ElemUse::doExecute(
StylesheetExecutionContext& executionContext,
bool applyAttributeSets) const
{
assert(m_attributeSetsNamesCount == 0 || m_attributeSetsNames != 0);
ElemTemplateElement::execute(executionContext);
if(applyAttributeSets == true && m_attributeSetsNamesCount > 0)
{
assert(canGenerateAttributes() == true);
const StylesheetRoot& theStylesheetRoot = getStylesheet().getStylesheetRoot();
const LocatorType* const theLocator = getLocator();
for(size_type i = 0; i < m_attributeSetsNamesCount; ++i)
{
theStylesheetRoot.executeAttributeSet(executionContext, *m_attributeSetsNames[i], theLocator);
}
}
}
#endif
bool
ElemUse::processUseAttributeSets(
StylesheetConstructionContext& constructionContext,
const XalanDOMChar* attrName,
const AttributeListType& atts,
int which)
{
bool isUAS = false;
if(StylesheetConstructionContext::ELEMNAME_LITERAL_RESULT == getXSLToken())
{
isUAS = constructionContext.isXSLUseAttributeSetsAttribute(
attrName,
getStylesheet(),
getLocator());
}
else
{
isUAS = equals(attrName, Constants::ATTRNAME_USEATTRIBUTESETS);
}
if(isUAS == true)
{
m_attributeSetsNames =
constructionContext.tokenizeQNames(
m_attributeSetsNamesCount,
atts.getValue(which),
getStylesheet().getNamespaces(),
getLocator());
assert(m_attributeSetsNamesCount == 0 || m_attributeSetsNames != 0);
}
return isUAS;
}
XALAN_CPP_NAMESPACE_END