/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_framework.hxx"

#include <xml/xmlnamespaces.hxx>

using namespace ::com::sun::star::xml::sax;
using namespace ::com::sun::star::uno;

const ::rtl::OUString aXMLAttributeNamespace( RTL_CONSTASCII_USTRINGPARAM( "xmlns" ));

namespace framework
{

XMLNamespaces::XMLNamespaces()
{
}

XMLNamespaces::XMLNamespaces( const XMLNamespaces& aXMLNamespaces )
{
	m_aDefaultNamespace = aXMLNamespaces.m_aDefaultNamespace;
	m_aNamespaceMap = aXMLNamespaces.m_aNamespaceMap;
}

XMLNamespaces::~XMLNamespaces()
{
}

void XMLNamespaces::addNamespace( const ::rtl::OUString& aName, const ::rtl::OUString& aValue ) throw( SAXException )
{
	NamespaceMap::iterator p;
	::rtl::OUString aNamespaceName( aName );
	sal_Int32 nXMLNamespaceLength = aXMLAttributeNamespace.getLength();

	// delete preceding "xmlns"
	if ( aNamespaceName.compareTo( aXMLAttributeNamespace, nXMLNamespaceLength ) == 0 )
	{
		if ( aNamespaceName.getLength() == nXMLNamespaceLength )
		{
			aNamespaceName = ::rtl::OUString();
		}
		else if ( aNamespaceName.getLength() >= nXMLNamespaceLength+2 )
		{
			aNamespaceName = aNamespaceName.copy( nXMLNamespaceLength+1 );
		}
		else
		{
			// a xml namespace without name is not allowed (e.g. "xmlns:" )
			::rtl::OUString aErrorMessage( RTL_CONSTASCII_USTRINGPARAM( "A xml namespace without name is not allowed!" ));
			throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
		}
	}

	if ( aValue.getLength() == 0 && aNamespaceName.getLength() > 0 )
	{
		// namespace should be reseted - as xml draft states this is only allowed
		// for the default namespace - check and throw exception if check fails
		::rtl::OUString aErrorMessage( RTL_CONSTASCII_USTRINGPARAM( "Clearing xml namespace only allowed for default namespace!" ));
		throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
	}
	else
	{
		if ( aNamespaceName.getLength() == 0 )
			m_aDefaultNamespace = aValue;
		else
		{
			p = m_aNamespaceMap.find( aNamespaceName );
			if ( p != m_aNamespaceMap.end() )
			{
				// replace current namespace definition
				m_aNamespaceMap.erase( p );
				m_aNamespaceMap.insert( NamespaceMap::value_type( aNamespaceName, aValue ));
			}
			else
			{
				m_aNamespaceMap.insert( NamespaceMap::value_type( aNamespaceName, aValue ));
			}
		}
	}
}

::rtl::OUString XMLNamespaces::applyNSToAttributeName( const ::rtl::OUString& aName ) const throw( SAXException )
{
	// xml draft: there is no default namespace for attributes!

	int	index;
	if (( index = aName.indexOf( ':' )) > 0 )
	{
		if ( aName.getLength() > index+1 )
		{
			::rtl::OUString aAttributeName = getNamespaceValue( aName.copy( 0, index ) );
			aAttributeName += ::rtl::OUString::createFromAscii( "^" );
			aAttributeName += aName.copy( index+1 );
			return aAttributeName;
		}
		else
		{
			// attribute with namespace but without name "namespace:" is not allowed!!
			::rtl::OUString aErrorMessage( RTL_CONSTASCII_USTRINGPARAM( "Attribute has no name only preceding namespace!" ));
			throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
		}
	}

	return aName;
}

::rtl::OUString XMLNamespaces::applyNSToElementName( const ::rtl::OUString& aName ) const	throw( SAXException )
{
	// xml draft: element names can have a default namespace

	int			index = aName.indexOf( ':' );
	::rtl::OUString	aNamespace;
	::rtl::OUString	aElementName = aName;

	if ( index > 0 )
		aNamespace = getNamespaceValue( aName.copy( 0, index ) );
	else
		aNamespace = m_aDefaultNamespace;

	if ( aNamespace.getLength() > 0 )
	{
		aElementName = aNamespace;
		aElementName += ::rtl::OUString::createFromAscii( "^" );
	}
	else
		return aName;

	if ( index > 0 )
	{
		if ( aName.getLength() > index+1 )
			aElementName += aName.copy( index+1 );
		else
		{
			// attribute with namespace but without a name is not allowed (e.g. "cfg:" )
			::rtl::OUString aErrorMessage( RTL_CONSTASCII_USTRINGPARAM( "Attribute has no name only preceding namespace!" ));
			throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
		}
	}
	else
		aElementName += aName;

	return aElementName;
}

::rtl::OUString XMLNamespaces::getNamespaceValue( const ::rtl::OUString& aNamespace ) const throw( SAXException )
{
	if ( aNamespace.getLength() == 0 )
		return m_aDefaultNamespace;
	else
	{
		NamespaceMap::const_iterator p;
		p = m_aNamespaceMap.find( aNamespace );
		if ( p != m_aNamespaceMap.end() )
			return p->second;
		else
		{
			// namespace not defined => throw exception!
			::rtl::OUString aErrorMessage( RTL_CONSTASCII_USTRINGPARAM( "XML namespace used but not defined!" ));
			throw SAXException( aErrorMessage, Reference< XInterface >(), Any() );
		}
	}
}

}

