blob: 8923f187170d6d460ae2d53ce36183fae7d86b13 [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.
*/
#if !defined(XALAN_XALANNAMESPACESSTACK_HEADER_GUARD)
#define XALAN_XALANNAMESPACESSTACK_HEADER_GUARD
// Base include file. Must be first.
#include <xalanc/DOMSupport/DOMSupportDefinitions.hpp>
#include <xalanc/Include/XalanVector.hpp>
#include <xalanc/Include/XalanDeque.hpp>
#include <xalanc/PlatformSupport/PrefixResolver.hpp>
#include <xalanc/PlatformSupport/XalanNamespace.hpp>
XALAN_CPP_NAMESPACE_BEGIN
class XalanDOMString;
class XALAN_DOMSUPPORT_EXPORT XalanNamespacesStack
{
public:
class XALAN_DOMSUPPORT_EXPORT PrefixResolverProxy : public PrefixResolver
{
public:
/**
* Construct a PrefixResolver from a XalanNamespaceStack
* instance.
*
* @param theStack The stack to use for prefix resolution
* @param theURI The namespace URI of the resolver, if any. Only a reference is kept, so this cannot be a temporary
* @return pointer to the string value if found, otherwise 0.
*/
PrefixResolverProxy(
const XalanNamespacesStack& theStack,
const XalanDOMString& theURI);
virtual
~PrefixResolverProxy();
virtual const XalanDOMString*
getNamespaceForPrefix(const XalanDOMString& prefix) const;
virtual const XalanDOMString&
getURI() const;
private:
const XalanNamespacesStack& m_stack;
const XalanDOMString& m_uri;
};
class XALAN_DOMSUPPORT_EXPORT XalanNamespacesStackEntry
{
public:
typedef XalanNamespace value_type;
typedef XalanDeque<value_type> NamespaceCollectionType;
typedef const XalanDOMString& (value_type::*MemberFunctionType)() const;
typedef NamespaceCollectionType::iterator iterator;
typedef NamespaceCollectionType::reverse_iterator reverse_iterator;
typedef NamespaceCollectionType::const_iterator const_iterator;
typedef NamespaceCollectionType::const_reverse_iterator const_reverse_iterator;
XalanNamespacesStackEntry();
XalanNamespacesStackEntry(const XalanNamespacesStackEntry& theSource);
~XalanNamespacesStackEntry();
XalanNamespacesStackEntry&
operator=(const XalanNamespacesStackEntry& theRHS);
void
addDeclaration(
const XalanDOMString& thePrefix,
const XalanDOMChar* theNamespaceURI,
XalanDOMString::size_type theLength);
/**
* Get the namespace for a prefix.
*
* @param thePrefix The prefix to find
* @return pointer to the string value if found, otherwise 0.
*/
const XalanDOMString*
getNamespaceForPrefix(const XalanDOMString& thePrefix) const
{
return findEntry(thePrefix, &XalanNamespace::getPrefix, &XalanNamespace::getURI);
}
/**
* Get the prefix for a namespace.
*
* @param theURI The namespace URI to find
* @return pointer to the string value if found, otherwise 0.
*/
const XalanDOMString*
getPrefixForNamespace(const XalanDOMString& theURI) const
{
return findEntry(theURI, &XalanNamespace::getURI, &XalanNamespace::getPrefix);
}
bool
isPrefixPresent(const XalanDOMString& thePrefix) const
{
return getNamespaceForPrefix(thePrefix) == 0 ? false : true;
}
iterator
begin()
{
return m_namespaces.begin();
}
const_iterator
begin() const
{
return m_namespaces.begin();
}
iterator
end()
{
return m_position;
}
const_iterator
end() const
{
return const_iterator(m_position);
}
reverse_iterator
rbegin()
{
return reverse_iterator(end());
}
const_reverse_iterator
rbegin() const
{
return const_reverse_iterator(end());
}
reverse_iterator
rend()
{
return reverse_iterator(begin());
}
const_reverse_iterator
rend() const
{
return const_reverse_iterator(begin());
}
void
clear();
void
reset()
{
m_position = m_namespaces.begin();
}
void
swap(XalanNamespacesStackEntry& theOther);
private:
const XalanDOMString*
findEntry(
const XalanDOMString& theKey,
MemberFunctionType theKeyFunction,
MemberFunctionType theValueFunction) const;
NamespaceCollectionType m_namespaces;
iterator m_position;
};
typedef XalanNamespacesStackEntry value_type;
typedef XalanDeque<value_type> NamespacesStackType;
typedef XalanVector<bool> BoolVectorType;
typedef NamespacesStackType::iterator iterator;
typedef NamespacesStackType::reverse_iterator reverse_iterator;
typedef NamespacesStackType::const_iterator const_iterator;
typedef NamespacesStackType::const_reverse_iterator const_reverse_iterator;
typedef NamespacesStackType::size_type size_type;
typedef const XalanDOMString* (value_type::*MemberFunctionType)(const XalanDOMString&) const;
explicit
XalanNamespacesStack();
~XalanNamespacesStack();
void
addDeclaration(
const XalanDOMString& thePrefix,
const XalanDOMString& theURI)
{
addDeclaration(
thePrefix,
theURI.c_str(),
theURI.length());
}
void
addDeclaration(
const XalanDOMString& thePrefix,
const XalanDOMChar* theURI)
{
addDeclaration(
thePrefix,
theURI,
length(theURI));
}
void
addDeclaration(
const XalanDOMString& thePrefix,
const XalanDOMChar* theURI,
XalanDOMString::size_type theLength);
void
pushContext();
void
popContext();
const XalanDOMString*
getNamespaceForPrefix(const XalanDOMString& thePrefix) const;
const XalanDOMString*
getPrefixForNamespace(const XalanDOMString& theURI) const
{
return findEntry(theURI, &value_type::getPrefixForNamespace);
}
/**
* See if the prefix has been mapped to a namespace in the current
* context, without looking down the stack of namespaces.
*/
bool
prefixIsPresentLocal(const XalanDOMString& thePrefix);
void
clear();
iterator
begin()
{
return m_stackBegin + 1;
}
const_iterator
begin() const
{
return const_iterator(m_stackBegin + 1);
}
iterator
end()
{
return m_stackPosition + 1;
}
const_iterator
end() const
{
return const_iterator(m_stackPosition + 1);
}
reverse_iterator
rbegin()
{
return reverse_iterator(end());
}
const_reverse_iterator
rbegin() const
{
return const_reverse_iterator(end());
}
reverse_iterator
rend()
{
return reverse_iterator(begin());
}
const_reverse_iterator
rend() const
{
return const_reverse_iterator(begin());
}
size_type
size() const
{
return m_resultNamespaces.size() - 1;
}
bool
empty() const
{
return NamespacesStackType::const_iterator(m_stackPosition) == m_resultNamespaces.begin() ? true : false;
}
private:
// not implemented
XalanNamespacesStack(const XalanNamespacesStack&);
bool
operator==(const XalanNamespacesStack&) const;
XalanNamespacesStack&
operator=(const XalanNamespacesStack&);
enum { eDefaultCreateNewContextStackSize = 25 };
const XalanDOMString*
findEntry(
const XalanDOMString& theKey,
MemberFunctionType theFunction) const;
/**
* A stack to keep track of the result tree namespaces.
*/
NamespacesStackType m_resultNamespaces;
NamespacesStackType::iterator m_stackBegin;
NamespacesStackType::iterator m_stackPosition;
BoolVectorType m_createNewContextStack;
};
XALAN_CPP_NAMESPACE_END
#endif // XALAN_XALANNAMESPACESSTACK_HEADER_GUARD