/**************************************************************
 *
 * 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_xmloff.hxx"
#include <rtl/ref.hxx>
#include <rtl/ustrbuf.hxx>
#include <com/sun/star/i18n/XCharacterClassification.hpp>
#include <com/sun/star/i18n/UnicodeType.hpp>
#include <comphelper/processfactory.hxx>
#include <xmloff/nmspmap.hxx>
#include "xmloff/xmlnmspe.hxx"
#include "IgnoreTContext.hxx"
#include "RenameElemTContext.hxx"
#include "ProcAttrTContext.hxx"
#include "ProcAddAttrTContext.hxx"
#include "MergeElemTContext.hxx"
#include "CreateElemTContext.hxx"
#include "MutableAttrList.hxx"
#include "TransformerActions.hxx"
#include "ElemTransformerAction.hxx"
// --> OD 2005-06-29 #i50322#
#include "PropertyActionsOOo.hxx"
// <--
#ifndef _XMLOFF_TRANSFORMERTOKENMAP_HXX
#include "TransformerTokenMap.hxx"
#endif
#include <xmloff/xmluconv.hxx>

#ifndef _XMLOFF_TRANSFORMERBASE_HXX
#include "TransformerBase.hxx"
#endif
#include "TContextVector.hxx"

using ::rtl::OUString;
using ::rtl::OUStringBuffer;
using namespace ::osl;
using namespace ::xmloff::token;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::i18n;
using namespace ::com::sun::star::xml::sax;

// -----------------------------------------------------------------------------

namespace
{
bool lcl_ConvertAttr( OUString & rOutAttribute, sal_Int32 nParam )
{
    bool bResult = false;
    enum XMLTokenEnum eTokenToRename =
        static_cast< enum XMLTokenEnum >( nParam & 0xffff );
    if( eTokenToRename != XML_TOKEN_INVALID &&
        IsXMLToken( rOutAttribute, eTokenToRename ))
    {
        enum XMLTokenEnum eReplacementToken =
            static_cast< enum XMLTokenEnum >( nParam >> 16 );
        rOutAttribute = GetXMLToken( eReplacementToken );
        bResult = true;
    }
    return bResult;
}
} // anonymous namespace

// -----------------------------------------------------------------------------

XMLTransformerContext *XMLTransformerBase::CreateContext( sal_uInt16 nPrefix,
	const OUString& rLocalName, const OUString& rQName )
{
	XMLTransformerActions::key_type aKey( nPrefix, rLocalName );
	XMLTransformerActions::const_iterator aIter =
		GetElemActions().find( aKey );

	if( !(aIter == GetElemActions().end()) )
	{
		sal_uInt32 nActionType = (*aIter).second.m_nActionType;
		if( (nActionType & XML_ETACTION_USER_DEFINED) != 0 )
		{
			XMLTransformerContext *pContext =
				CreateUserDefinedContext( (*aIter).second,
									rQName );
			OSL_ENSURE( pContext && !pContext->IsPersistent(),
						"unknown or not persistent action" );
			return pContext;
		}

		switch( nActionType )
		{
		case XML_ETACTION_COPY_CONTENT:
			return new XMLIgnoreTransformerContext( *this, rQName, sal_False,
												sal_False );
		case XML_ETACTION_COPY:
			return new XMLTransformerContext( *this, rQName );
		case XML_ETACTION_RENAME_ELEM:
			return new XMLRenameElemTransformerContext( *this, rQName,
					(*aIter).second.GetQNamePrefixFromParam1(),
					(*aIter).second.GetQNameTokenFromParam1() );
		case XML_ETACTION_RENAME_ELEM_ADD_ATTR:
			return new XMLRenameElemTransformerContext( *this, rQName,
					(*aIter).second.GetQNamePrefixFromParam1(),
					(*aIter).second.GetQNameTokenFromParam1(),
					(*aIter).second.GetQNamePrefixFromParam2(),
					(*aIter).second.GetQNameTokenFromParam2(),
				   	static_cast< XMLTokenEnum >( (*aIter).second.m_nParam3 ) );
		case XML_ETACTION_RENAME_ELEM_PROC_ATTRS:
			return new XMLProcAttrTransformerContext( *this, rQName,
					(*aIter).second.GetQNamePrefixFromParam1(),
					(*aIter).second.GetQNameTokenFromParam1(),
				   	static_cast< sal_uInt16 >( (*aIter).second.m_nParam2 ) );
		case XML_ETACTION_RENAME_ELEM_ADD_PROC_ATTR:
			return new XMLProcAddAttrTransformerContext( *this, rQName,
					(*aIter).second.GetQNamePrefixFromParam1(),
					(*aIter).second.GetQNameTokenFromParam1(),
				   	static_cast< sal_uInt16 >(
						(*aIter).second.m_nParam3  >> 16 ),
					(*aIter).second.GetQNamePrefixFromParam2(),
					(*aIter).second.GetQNameTokenFromParam2(),
				   	static_cast< XMLTokenEnum >(
						(*aIter).second.m_nParam3 & 0xffff ) );
		case XML_ETACTION_RENAME_ELEM_COND:
			{
				const XMLTransformerContext *pCurrent = GetCurrentContext();
				if( pCurrent->HasQName(
							(*aIter).second.GetQNamePrefixFromParam2(),
							(*aIter).second.GetQNameTokenFromParam2() ) )
					return new XMLRenameElemTransformerContext( *this, rQName,
							(*aIter).second.GetQNamePrefixFromParam1(),
							(*aIter).second.GetQNameTokenFromParam1() );
			}
			break;
		case XML_ETACTION_RENAME_ELEM_PROC_ATTRS_COND:
			{
				const XMLTransformerContext *pCurrent = GetCurrentContext();
				if( pCurrent->HasQName(
							(*aIter).second.GetQNamePrefixFromParam3(),
							(*aIter).second.GetQNameTokenFromParam3() ) )
					return new XMLProcAttrTransformerContext( *this, rQName,
							(*aIter).second.GetQNamePrefixFromParam1(),
							(*aIter).second.GetQNameTokenFromParam1(),
							static_cast< sal_uInt16 >( (*aIter).second.m_nParam2 ) );
				else
					return new XMLProcAttrTransformerContext( *this, rQName,
							static_cast< sal_uInt16 >( (*aIter).second.m_nParam2 ) );
			}
		case XML_ETACTION_PROC_ATTRS:
			return new XMLProcAttrTransformerContext( *this, rQName,
				   	static_cast< sal_uInt16 >( (*aIter).second.m_nParam1 ) );
		case XML_ETACTION_PROC_ATTRS_COND:
			{
				const XMLTransformerContext *pCurrent = GetCurrentContext();
				if( pCurrent->HasQName(
							(*aIter).second.GetQNamePrefixFromParam1(),
							(*aIter).second.GetQNameTokenFromParam1() ) )
					return new XMLProcAttrTransformerContext( *this, rQName,
							static_cast< sal_uInt16 >( (*aIter).second.m_nParam2 ) );
			}
			break;
		case XML_ETACTION_MOVE_ATTRS_TO_ELEMS:
			return new XMLCreateElemTransformerContext( *this, rQName,
				   	static_cast< sal_uInt16 >( (*aIter).second.m_nParam1 ) );
		case XML_ETACTION_MOVE_ELEMS_TO_ATTRS:
			return new XMLMergeElemTransformerContext( *this, rQName,
				   	static_cast< sal_uInt16 >( (*aIter).second.m_nParam1 ) );
		default:
			OSL_ENSURE( sal_False, "unknown action" );
			break;
		}
	}

	// default is copying
	return new XMLTransformerContext( *this, rQName );
}

XMLTransformerActions *XMLTransformerBase::GetUserDefinedActions( sal_uInt16 )
{
	return 0;
}

XMLTransformerBase::XMLTransformerBase( XMLTransformerActionInit *pInit,
									::xmloff::token::XMLTokenEnum *pTKMapInit )
	throw () :
	m_pNamespaceMap( new SvXMLNamespaceMap ),
	m_pReplaceNamespaceMap( new SvXMLNamespaceMap ),
	m_pContexts( new XMLTransformerContextVector ),
	m_pElemActions( new XMLTransformerActions( pInit ) ),
	m_pTokenMap( new XMLTransformerTokenMap( pTKMapInit ) )
{
	GetNamespaceMap().Add( GetXMLToken(XML_NP_XLINK), GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK );
	GetNamespaceMap().Add( GetXMLToken(XML_NP_DC), GetXMLToken(XML_N_DC), XML_NAMESPACE_DC );
	GetNamespaceMap().Add( GetXMLToken(XML_NP_MATH), GetXMLToken(XML_N_MATH), XML_NAMESPACE_MATH );
	GetNamespaceMap().Add( GetXMLToken(XML_NP_OOO), GetXMLToken(XML_N_OOO), XML_NAMESPACE_OOO );
	GetNamespaceMap().Add( GetXMLToken(XML_NP_DOM), GetXMLToken(XML_N_DOM), XML_NAMESPACE_DOM );
	GetNamespaceMap().Add( GetXMLToken(XML_NP_OOOW), GetXMLToken(XML_N_OOOW), XML_NAMESPACE_OOOW );
	GetNamespaceMap().Add( GetXMLToken(XML_NP_OOOC), GetXMLToken(XML_N_OOOC), XML_NAMESPACE_OOOC );
}

XMLTransformerBase::~XMLTransformerBase() throw ()
{
	ResetTokens();

	delete m_pNamespaceMap;
	delete m_pReplaceNamespaceMap;
	delete m_pContexts;
	delete m_pElemActions;
	delete m_pTokenMap;
}

void SAL_CALL XMLTransformerBase::startDocument( void )
	throw( SAXException, RuntimeException )
{
	m_xHandler->startDocument();
}

void SAL_CALL XMLTransformerBase::endDocument( void )
	throw( SAXException, RuntimeException)
{
	m_xHandler->endDocument();
}

void SAL_CALL XMLTransformerBase::startElement( const OUString& rName,
										 const Reference< XAttributeList >& rAttrList )
	throw(SAXException, RuntimeException)
{
	SvXMLNamespaceMap *pRewindMap = 0;

	bool bRect = rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "presentation:show-shape" ) );
	(void)bRect;

	// Process namespace attributes. This must happen before creating the
	// context, because namespace decaration apply to the element name itself.
	XMLMutableAttributeList *pMutableAttrList = 0;
	Reference< XAttributeList > xAttrList( rAttrList );
	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
	for( sal_Int16 i=0; i < nAttrCount; i++ )
	{
		const OUString& rAttrName = xAttrList->getNameByIndex( i );
		if( ( rAttrName.getLength() >= 5 ) &&
            ( rAttrName.compareTo( GetXMLToken(XML_XMLNS), 5 ) == 0 ) &&
			( rAttrName.getLength() == 5 || ':' == rAttrName[5] ) )
		{
			if( !pRewindMap )
			{
				pRewindMap = m_pNamespaceMap;
				m_pNamespaceMap = new SvXMLNamespaceMap( *m_pNamespaceMap );
			}
			const OUString& rAttrValue = xAttrList->getValueByIndex( i );

            OUString aPrefix( ( rAttrName.getLength() == 5 )
                                 ? OUString()
                                 : rAttrName.copy( 6 ) );
			// Add namespace, but only if it is known.
			sal_uInt16 nKey = m_pNamespaceMap->AddIfKnown( aPrefix, rAttrValue );
			// If namespace is unknown, try to match a name with similar
			// TC Id an version
            if( XML_NAMESPACE_UNKNOWN == nKey  )
			{
				OUString aTestName( rAttrValue );
				if( SvXMLNamespaceMap::NormalizeOasisURN( aTestName ) )
					nKey = m_pNamespaceMap->AddIfKnown( aPrefix, aTestName );
			}
			// If that namespace is not known, too, add it as unknown
            if( XML_NAMESPACE_UNKNOWN == nKey  )
				nKey = m_pNamespaceMap->Add( aPrefix, rAttrValue );

			const OUString& rRepName = m_pReplaceNamespaceMap->GetNameByKey( nKey );
			if( rRepName.getLength() )
			{
				if( !pMutableAttrList )
				{
					pMutableAttrList = new XMLMutableAttributeList( xAttrList );
					xAttrList = pMutableAttrList;
				}

				pMutableAttrList->SetValueByIndex( i, rRepName );
			}
		}
	}

	// Get element's namespace and local name.
	OUString aLocalName;
	sal_uInt16 nPrefix =
		m_pNamespaceMap->GetKeyByAttrName( rName, &aLocalName );

	// If there are contexts already, call a CreateChildContext at the topmost
	// context. Otherwise, create a default context.
	::rtl::Reference < XMLTransformerContext > xContext;
	if( !m_pContexts->empty() )
	{
		xContext = m_pContexts->back()->CreateChildContext( nPrefix,
														  aLocalName,
														  rName,
														  xAttrList );
	}
	else
	{
		xContext = CreateContext( nPrefix, aLocalName, rName );
	}

	OSL_ENSURE( xContext.is(), "XMLTransformerBase::startElement: missing context" );
	if( !xContext.is() )
		xContext = new XMLTransformerContext( *this, rName );

	// Remember old namespace map.
	if( pRewindMap )
		xContext->SetRewindMap( pRewindMap );

	// Push context on stack.
	m_pContexts->push_back( xContext );

	// Call a startElement at the new context.
	xContext->StartElement( xAttrList );
}

void SAL_CALL XMLTransformerBase::endElement( const OUString&
#ifdef DBG_UTIL
rName
#endif
)
	throw(SAXException, RuntimeException)
{
	if( !m_pContexts->empty() )
	{
		// Get topmost context
		::rtl::Reference< XMLTransformerContext > xContext = m_pContexts->back();

#ifdef DBG_UTIL
		OSL_ENSURE( xContext->GetQName() == rName,
				"XMLTransformerBase::endElement: popped context has wrong lname" );
#endif

		// Call a EndElement at the current context.
		xContext->EndElement();

		// and remove it from the stack.
		m_pContexts->pop_back();

		// Get a namespace map to rewind.
		SvXMLNamespaceMap *pRewindMap = xContext->GetRewindMap();

		// Delete the current context.
		xContext = 0;

		// Rewind a namespace map.
		if( pRewindMap )
		{
			delete m_pNamespaceMap;
			m_pNamespaceMap = pRewindMap;
		}
	}
}

void SAL_CALL XMLTransformerBase::characters( const OUString& rChars )
	throw(SAXException, RuntimeException)
{
	if( !m_pContexts->empty() )
	{
		m_pContexts->back()->Characters( rChars );
	}
}

void SAL_CALL XMLTransformerBase::ignorableWhitespace( const OUString& rWhitespaces )
	throw(SAXException, RuntimeException)
{
	m_xHandler->ignorableWhitespace( rWhitespaces );
}

void SAL_CALL XMLTransformerBase::processingInstruction( const OUString& rTarget,
									   const OUString& rData )
	throw(SAXException, RuntimeException)
{
	m_xHandler->processingInstruction( rTarget, rData );
}

void SAL_CALL XMLTransformerBase::setDocumentLocator( const Reference< XLocator >& rLocator )
	throw(SAXException, RuntimeException)
{
	m_xLocator = rLocator;
}

// XExtendedDocumentHandler
void SAL_CALL XMLTransformerBase::startCDATA( void ) throw(SAXException, RuntimeException)
{
	if( m_xExtHandler.is() )
		m_xExtHandler->startCDATA();
}

void SAL_CALL XMLTransformerBase::endCDATA( void ) throw(RuntimeException)
{
	if( m_xExtHandler.is() )
		m_xExtHandler->endCDATA();
}

void SAL_CALL XMLTransformerBase::comment( const OUString& rComment )
	throw(SAXException, RuntimeException)
{
	if( m_xExtHandler.is() )
		m_xExtHandler->comment( rComment );
}

void SAL_CALL XMLTransformerBase::allowLineBreak( void )
	throw(SAXException, RuntimeException)
{
	if( m_xExtHandler.is() )
		m_xExtHandler->allowLineBreak();
}

void SAL_CALL XMLTransformerBase::unknown( const OUString& rString )
	throw(SAXException, RuntimeException)
{
	if( m_xExtHandler.is() )
		m_xExtHandler->unknown( rString );
}

// XInitialize
void SAL_CALL XMLTransformerBase::initialize( const Sequence< Any >& aArguments )
	throw(Exception, RuntimeException)
{
	const sal_Int32 nAnyCount = aArguments.getLength();
	const Any* pAny = aArguments.getConstArray();

	for( sal_Int32 nIndex = 0; nIndex < nAnyCount; nIndex++, pAny++ )
    {
        // #b6236750# use isAssignableFrom instead of comparing the types to
        // allow XExtendedDocumentHandler instead of XDocumentHandler (used in
        // writeOasis2OOoLibraryElement in sfx2).
        // The Any shift operator can't be used to query the type because it
        // uses queryInterface, and the model also has a XPropertySet interface.

        // document handler
		if( ::getCppuType( (const Reference< XDocumentHandler >*) 0 ).isAssignableFrom( pAny->getValueType() ) )
			m_xHandler.set( *pAny, UNO_QUERY );

        // property set to transport data across
		if( ::getCppuType( (const Reference< XPropertySet >*) 0 ).isAssignableFrom( pAny->getValueType() ) )
			m_xPropSet.set( *pAny, UNO_QUERY );

		// xmodel
		if( ::getCppuType( (const Reference< ::com::sun::star::frame::XModel >*) 0 ).isAssignableFrom( pAny->getValueType() ) )
			mxModel.set( *pAny, UNO_QUERY );
	}

	if( m_xPropSet.is() )
	{
		Any aAny;
		OUString sRelPath, sName;
		Reference< XPropertySetInfo > xPropSetInfo =
			m_xPropSet->getPropertySetInfo();
		OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamRelPath" ) );
		if( xPropSetInfo->hasPropertyByName(sPropName) )
		{
			aAny = m_xPropSet->getPropertyValue(sPropName);
			aAny >>= sRelPath;
		}
		sPropName = OUString( RTL_CONSTASCII_USTRINGPARAM("StreamName" ) );
		if( xPropSetInfo->hasPropertyByName(sPropName) )
		{
			aAny = m_xPropSet->getPropertyValue(sPropName);
			aAny >>= sName;
		}
		if( sName.getLength() )
		{
			m_aExtPathPrefix = OUString( RTL_CONSTASCII_USTRINGPARAM("../" ) );

			// If there is a rel path within a package, then append
			// additional '../'. If the rel path contains an ':', then it is
			// an absolute URI (or invalid URI, because zip files don't
			// permit ':'), and it will be ignored.
			if( sRelPath.getLength() )
			{
				sal_Int32 nColPos = sRelPath.indexOf( ':' );
				OSL_ENSURE( -1 == nColPos,
							"StreamRelPath contains ':', absolute URI?" );

				if( -1 == nColPos )
				{
					OUString sTmp = m_aExtPathPrefix;
					sal_Int32 nPos = 0;
					do
					{
						m_aExtPathPrefix += sTmp;
						nPos = sRelPath.indexOf( '/', nPos + 1 );
					}
					while( -1 != nPos );
				}
			}

		}
	}
}

static MapUnit lcl_getUnit( const OUString& rValue )
{
	MapUnit nDestUnit;
	if( rValue.endsWithIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "cm" ) ) )
		nDestUnit = MAP_CM;
	else if ( rValue.endsWithIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "mm" ) ) )
		nDestUnit = MAP_MM;
	else
		nDestUnit = MAP_INCH;
	return nDestUnit;
}

XMLMutableAttributeList *XMLTransformerBase::ProcessAttrList(
		Reference< XAttributeList >& rAttrList, sal_uInt16 nActionMap,
	   	sal_Bool bClone	)
{
	XMLMutableAttributeList *pMutableAttrList = 0;
	XMLTransformerActions *pActions = GetUserDefinedActions( nActionMap );
	OSL_ENSURE( pActions, "go no actions" );
	if( pActions )
	{
		sal_Int16 nAttrCount = rAttrList.is() ? rAttrList->getLength() : 0;
		for( sal_Int16 i=0; i < nAttrCount; ++i )
		{
			const OUString& rAttrName = rAttrList->getNameByIndex( i );
			const OUString& rAttrValue = rAttrList->getValueByIndex( i );
			OUString aLocalName;
			sal_uInt16 nPrefix = GetNamespaceMap().GetKeyByAttrName( rAttrName,
														   &aLocalName );

			XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
			XMLTransformerActions::const_iterator aIter =
					pActions->find( aKey );
			if( !(aIter == pActions->end() ) )
			{
				if( !pMutableAttrList )
				{
					pMutableAttrList = new XMLMutableAttributeList( rAttrList,
																	bClone );
					rAttrList = pMutableAttrList;
				}

				sal_uInt32 nAction = (*aIter).second.m_nActionType;
				sal_Bool bRename = sal_False;
				switch( nAction )
				{
				case XML_ATACTION_RENAME:
					bRename = sal_True;
					break;
				case XML_ATACTION_COPY:
					break;
				case XML_ATACTION_REMOVE:
				case XML_ATACTION_STYLE_DISPLAY_NAME:
					pMutableAttrList->RemoveAttributeByIndex( i );
					--i;
					--nAttrCount;
					break;
				case XML_ATACTION_RENAME_IN2INCH:
					bRename = sal_True;
				case XML_ATACTION_IN2INCH:
					{
						OUString aAttrValue( rAttrValue );
						if( ReplaceSingleInWithInch( aAttrValue ) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_INS2INCHS:
					{
						OUString aAttrValue( rAttrValue );
						if( ReplaceInWithInch( aAttrValue ) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_RENAME_INCH2IN:
					bRename = sal_True;
				case XML_ATACTION_INCH2IN:
					{
						OUString aAttrValue( rAttrValue );
						if( ReplaceSingleInchWithIn( aAttrValue ) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_INCHS2INS:
					{
						OUString aAttrValue( rAttrValue );
						if( ReplaceInchWithIn( aAttrValue ) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_TWIPS2IN:
					{
						OUString aAttrValue( rAttrValue );

						XMLTransformerBase::ReplaceSingleInchWithIn( aAttrValue );
						if( isWriter() )
						{
							MapUnit nDestUnit = lcl_getUnit( aAttrValue );

							// convert twips value to inch
							sal_Int32 nMeasure;
							if( SvXMLUnitConverter::convertMeasure(nMeasure, aAttrValue, MAP_100TH_MM ) )
							{

                                // --> OD 2004-10-29 #i13778#,#i36248#
                                // apply correct twip-to-1/100mm
                                nMeasure = (sal_Int32)( nMeasure >= 0
                                                        ? ((nMeasure*127+36)/72)
                                                        : ((nMeasure*127-36)/72) );
                                // <--

								rtl::OUStringBuffer aBuffer;
								SvXMLUnitConverter::convertMeasure( aBuffer, nMeasure, MAP_100TH_MM, nDestUnit );
								aAttrValue = aBuffer.makeStringAndClear();
							}
						}

						pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_RENAME_DECODE_STYLE_NAME_REF:
					bRename = sal_True;
				case XML_ATACTION_DECODE_STYLE_NAME:
				case XML_ATACTION_DECODE_STYLE_NAME_REF:
					{
						OUString aAttrValue( rAttrValue );
						if( DecodeStyleName(aAttrValue) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_ENCODE_STYLE_NAME:
					{
						OUString aAttrValue( rAttrValue );
						if( EncodeStyleName(aAttrValue) )
						{
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
							OUString aNewAttrQName(
								GetNamespaceMap().GetQNameByKey(
									nPrefix,
								::xmloff::token::GetXMLToken(
								XML_DISPLAY_NAME ) ) );
							pMutableAttrList->AddAttribute( aNewAttrQName,
															rAttrValue );
						}
					}
					break;
				case XML_ATACTION_RENAME_ENCODE_STYLE_NAME_REF:
					bRename = sal_True;
				case XML_ATACTION_ENCODE_STYLE_NAME_REF:
					{
						OUString aAttrValue( rAttrValue );
						if( EncodeStyleName(aAttrValue) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_RENAME_NEG_PERCENT:
					bRename = sal_True;
				case XML_ATACTION_NEG_PERCENT:
					{
						OUString aAttrValue( rAttrValue );
						if( NegPercent( aAttrValue ) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_RENAME_ADD_NAMESPACE_PREFIX:
					bRename = sal_True;
				case XML_ATACTION_ADD_NAMESPACE_PREFIX:
					{
						OUString aAttrValue( rAttrValue );
						sal_uInt16 nValPrefix =
							static_cast<sal_uInt16>(
									bRename ? (*aIter).second.m_nParam2
											: (*aIter).second.m_nParam1);
						if( AddNamespacePrefix( aAttrValue, nValPrefix ) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_ADD_APP_NAMESPACE_PREFIX:
					{
						OUString aAttrValue( rAttrValue );
						sal_uInt16 nValPrefix =
							static_cast<sal_uInt16>((*aIter).second.m_nParam1);
						if( IsXMLToken( GetClass(), XML_SPREADSHEET  ) )
							nValPrefix = XML_NAMESPACE_OOOC;
						else if( IsXMLToken( GetClass(), XML_TEXT  ) )
							nValPrefix = XML_NAMESPACE_OOOW;
						if( AddNamespacePrefix( aAttrValue, nValPrefix ) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_RENAME_REMOVE_NAMESPACE_PREFIX:
					bRename = sal_True;
				case XML_ATACTION_REMOVE_NAMESPACE_PREFIX:
					{
						OUString aAttrValue( rAttrValue );
						sal_uInt16 nValPrefix =
							static_cast<sal_uInt16>(
									bRename ? (*aIter).second.m_nParam2
											: (*aIter).second.m_nParam1);
						if( RemoveNamespacePrefix( aAttrValue, nValPrefix ) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_REMOVE_ANY_NAMESPACE_PREFIX:
					{
						OUString aAttrValue( rAttrValue );
						if( RemoveNamespacePrefix( aAttrValue ) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_URI_OOO:
					{
						OUString aAttrValue( rAttrValue );
						if( ConvertURIToOASIS( aAttrValue,
							static_cast< sal_Bool >((*aIter).second.m_nParam1)))
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_URI_OASIS:
					{
						OUString aAttrValue( rAttrValue );
						if( ConvertURIToOOo( aAttrValue,
							static_cast< sal_Bool >((*aIter).second.m_nParam1)))
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
                case XML_ATACTION_RENAME_ATTRIBUTE:
                    {
                        OUString aAttrValue( rAttrValue );
                        RenameAttributeValue(
                            aAttrValue,
                            (*aIter).second.m_nParam1,
                            (*aIter).second.m_nParam2,
                            (*aIter).second.m_nParam3 );
                        pMutableAttrList->SetValueByIndex( i, aAttrValue );
                    }
                    break;
                case XML_ATACTION_RNG2ISO_DATETIME:
                    {
						OUString aAttrValue( rAttrValue );
						if( ConvertRNGDateTimeToISO( aAttrValue ))
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
                    }
                    break;
                case XML_ATACTION_RENAME_RNG2ISO_DATETIME:
                    {
						OUString aAttrValue( rAttrValue );
						if( ConvertRNGDateTimeToISO( aAttrValue ))
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
                        bRename = sal_True;
                    }
                    break;
				case XML_ATACTION_IN2TWIPS:
					{
						OUString aAttrValue( rAttrValue );
						XMLTransformerBase::ReplaceSingleInWithInch( aAttrValue );

						if( isWriter() )
						{
							MapUnit nDestUnit = lcl_getUnit( aAttrValue );

							// convert inch value to twips and export as faked inch
							sal_Int32 nMeasure;
							if( SvXMLUnitConverter::convertMeasure(nMeasure, aAttrValue, MAP_100TH_MM ) )
							{

                                // --> OD 2004-10-29 #i13778#,#i36248#
                                // apply correct 1/100mm-to-twip conversion
                                nMeasure = (sal_Int32)( nMeasure >= 0
                                                        ? ((nMeasure*72+63)/127)
                                                        : ((nMeasure*72-63)/127) );
                                // <--

								OUStringBuffer aBuffer;
								SvXMLUnitConverter::convertMeasure( aBuffer, nMeasure, MAP_100TH_MM, nDestUnit );
								aAttrValue = aBuffer.makeStringAndClear();
							}
						}

						pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_SVG_WIDTH_HEIGHT_OOO:
					{
						OUString aAttrValue( rAttrValue );
						ReplaceSingleInchWithIn( aAttrValue );

						MapUnit nDestUnit = lcl_getUnit( aAttrValue );

						sal_Int32 nMeasure;
						if( SvXMLUnitConverter::convertMeasure(nMeasure, aAttrValue, MAP_100TH_MM ) )
						{

							if( nMeasure > 0 )
								nMeasure -= 1;
							else if( nMeasure < 0 )
								nMeasure += 1;


							OUStringBuffer aBuffer;
							SvXMLUnitConverter::convertMeasure( aBuffer, nMeasure, MAP_100TH_MM, nDestUnit );
                            aAttrValue = aBuffer.makeStringAndClear();
						}

						pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_SVG_WIDTH_HEIGHT_OASIS:
					{
						OUString aAttrValue( rAttrValue );
						ReplaceSingleInWithInch( aAttrValue );

						MapUnit nDestUnit = lcl_getUnit( aAttrValue );

						sal_Int32 nMeasure;
						if( SvXMLUnitConverter::convertMeasure(nMeasure, aAttrValue, MAP_100TH_MM ) )
						{

							if( nMeasure > 0 )
								nMeasure += 1;
							else if( nMeasure < 0 )
								nMeasure -= 1;


							OUStringBuffer aBuffer;
							SvXMLUnitConverter::convertMeasure( aBuffer, nMeasure, MAP_100TH_MM, nDestUnit );
                            aAttrValue = aBuffer.makeStringAndClear();
						}

						pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_DECODE_ID:
					{
						OUString aAttrValue;

						const sal_Int32 nLen = rAttrValue.getLength();
						OUStringBuffer aBuffer;

						sal_Int32 pos;
						for( pos = 0; pos < nLen; pos++ )
						{
							sal_Unicode c = rAttrValue[pos];
							if( (c >= '0') && (c <= '9') )
								aBuffer.append( c );
							else
								aBuffer.append( (sal_Int32)c );
						}

						pMutableAttrList->SetValueByIndex( i, aBuffer.makeStringAndClear() );
					}
					break;
                // --> OD 2005-06-10 #i50322# - special handling for the
                // transparency of writer background graphics.
                case XML_ATACTION_WRITER_BACK_GRAPHIC_TRANSPARENCY:
                    {
                        // determine, if it's the transparency of a document style
                        XMLTransformerContext* pFirstContext = (*m_pContexts)[0].get();
                        OUString aFirstContextLocalName;
                        /* sal_uInt16 nFirstContextPrefix = */
                            GetNamespaceMap().GetKeyByAttrName( pFirstContext->GetQName(),
                                                                &aFirstContextLocalName );
                        bool bIsDocumentStyle(
                            ::xmloff::token::IsXMLToken( aFirstContextLocalName,
                                                         XML_DOCUMENT_STYLES ) );
                        // no conversion of transparency value for document
                        // styles, because former OpenOffice.org version writes
                        // writes always a transparency value of 100% and doesn't
                        // read the value. Thus, it's intepreted as 0%
                        if ( !bIsDocumentStyle )
                        {
                            OUString aAttrValue( rAttrValue );
                            NegPercent(aAttrValue);
                            pMutableAttrList->SetValueByIndex( i, aAttrValue );
                        }
                        bRename = sal_True;
                    }
                    break;
                // <--
				case XML_ATACTION_SHAPEID:
				{
					OUString sNewValue( RTL_CONSTASCII_USTRINGPARAM( "shape" ) );
					sNewValue += rAttrValue;
					pMutableAttrList->SetValueByIndex( i, sNewValue );
					break;
				}

				default:
					OSL_ENSURE( sal_False, "unknown action" );
					break;
				}

				if( bRename )
				{
					OUString aNewAttrQName(
						GetNamespaceMap().GetQNameByKey(
							(*aIter).second.GetQNamePrefixFromParam1(),
							::xmloff::token::GetXMLToken(
								(*aIter).second.GetQNameTokenFromParam1()) ) );
					pMutableAttrList->RenameAttributeByIndex( i,
															  aNewAttrQName );
				}
			}
		}
	}

	return pMutableAttrList;
}

sal_Bool XMLTransformerBase::ReplaceSingleInchWithIn( OUString& rValue )
{
	sal_Bool bRet = sal_False;
	sal_Int32 nPos = rValue.getLength();
	while( nPos && rValue[nPos-1] <= ' ' )
		--nPos;
	if( nPos > 2 &&
		('c'==rValue[nPos-2] || 'C'==rValue[nPos-2]) &&
		('h'==rValue[nPos-1] || 'H'==rValue[nPos-1]) )
	{
		rValue =rValue.copy( 0, nPos-2 );
		bRet = sal_True;
	}

	return bRet;
}

sal_Bool XMLTransformerBase::ReplaceInchWithIn( OUString& rValue )
{
	sal_Bool bRet = sal_False;
	sal_Int32 nPos = 1;
	while( nPos < rValue.getLength()-3 )
	{
		sal_Unicode c = rValue[nPos];
		if( 'i'==c || 'I'==c )
		{
			c = rValue[nPos-1];
			if( (c >= '0' && c <= '9') || '.' == c )
			{
				c = rValue[nPos+1];
				if( 'n'==c || 'N'==c )
				{
					c = rValue[nPos+2];
					if( 'c'==c || 'C'==c )
					{
						c = rValue[nPos+3];
						if( 'h'==c || 'H'==c )
						{
							rValue = rValue.replaceAt( nPos,
								4, GetXMLToken(XML_UNIT_INCH) );
							nPos += 2;
							bRet = sal_True;
							continue;
						}
					}
				}
			}
		}
		++nPos;
	}

	return bRet;
}

sal_Bool XMLTransformerBase::ReplaceSingleInWithInch( OUString& rValue )
{
	sal_Bool bRet = sal_False;

	sal_Int32 nPos = rValue.getLength();
	while( nPos && rValue[nPos-1] <= ' ' )
		--nPos;
	if( nPos > 2 &&
		('i'==rValue[nPos-2] ||
			'I'==rValue[nPos-2]) &&
		('n'==rValue[nPos-1] ||
			'N'==rValue[nPos-1]) )
	{
		nPos -= 2;
		rValue = rValue.replaceAt( nPos, rValue.getLength() - nPos,
										   GetXMLToken(XML_INCH) );
		bRet = sal_True;
	}

	return bRet;
}

sal_Bool XMLTransformerBase::ReplaceInWithInch( OUString& rValue )
{
	sal_Bool bRet = sal_False;
	sal_Int32 nPos = 1;
	while( nPos < rValue.getLength()-1 )
	{
		sal_Unicode c = rValue[nPos];
		if( 'i'==c || 'I'==c )
		{
			c = rValue[nPos-1];
			if( (c >= '0' && c <= '9') || '.' == c )
			{
				c = rValue[nPos+1];
				if( 'n'==c || 'N'==c )
				{
					rValue = rValue.replaceAt( nPos,
									2, GetXMLToken(XML_INCH) );
					nPos += 4;
					bRet = sal_True;
					continue;
				}
			}
		}
		++nPos;
	}

	return bRet;
}

sal_Bool XMLTransformerBase::EncodeStyleName( OUString& rName ) const
{
	static sal_Char aHexTab[] = "0123456789abcdef";

	sal_Bool bEncoded = sal_False;

	sal_Int32 nLen = rName.getLength();
	OUStringBuffer aBuffer( nLen );

	for( sal_Int32 i = 0; i < nLen; i++ )
	{
		sal_Unicode c = rName[i];
		sal_Bool bValidChar = sal_False;
		if( c < 0x00ffU )
		{
			bValidChar =
				(c >= 0x0041 && c <= 0x005a) ||
				(c >= 0x0061 && c <= 0x007a) ||
				(c >= 0x00c0 && c <= 0x00d6) ||
				(c >= 0x00d8 && c <= 0x00f6) ||
				(c >= 0x00f8 && c <= 0x00ff) ||
				( i > 0 && ( (c >= 0x0030 && c <= 0x0039) ||
							 c == 0x00b7 || c == '-' || c == '.') );
		}
		else
		{
			if( (c >= 0xf900U && c <= 0xfffeU) ||
			 	(c >= 0x20ddU && c <= 0x20e0U))
			{
				bValidChar = sal_False;
			}
			else if( (c >= 0x02bbU && c <= 0x02c1U) || c == 0x0559 ||
					 c == 0x06e5 || c == 0x06e6 )
			{
				bValidChar = sal_True;
			}
			else if( c == 0x0387 )
			{
				bValidChar = i > 0;
			}
			else
			{
				if( !xCharClass.is() )
				{
					Reference< XMultiServiceFactory > xFactory =
						comphelper::getProcessServiceFactory();
					if( xFactory.is() )
					{
						try
						{
							const_cast < XMLTransformerBase * >(this)
								->xCharClass =
									Reference < XCharacterClassification >(
								xFactory->createInstance(
									OUString::createFromAscii(
						"com.sun.star.i18n.CharacterClassification_Unicode") ),
								UNO_QUERY );

							OSL_ENSURE( xCharClass.is(),
					"can't instantiate character clossification component" );
						}
						catch( com::sun::star::uno::Exception& )
						{
						}
					}
				}
				if( xCharClass.is() )
				{
					sal_Int16 nType = xCharClass->getType( rName, i );

					switch( nType )
					{
					case UnicodeType::UPPERCASE_LETTER:		// Lu
					case UnicodeType::LOWERCASE_LETTER:		// Ll
					case UnicodeType::TITLECASE_LETTER:		// Lt
					case UnicodeType::OTHER_LETTER:			// Lo
					case UnicodeType::LETTER_NUMBER: 		// Nl
						bValidChar = sal_True;
						break;
					case UnicodeType::NON_SPACING_MARK:		// Ms
					case UnicodeType::ENCLOSING_MARK:		// Me
					case UnicodeType::COMBINING_SPACING_MARK:	//Mc
					case UnicodeType::MODIFIER_LETTER:		// Lm
					case UnicodeType::DECIMAL_DIGIT_NUMBER:	// Nd
						bValidChar = i > 0;
						break;
					}
				}
			}
		}
		if( bValidChar )
		{
			aBuffer.append( c );
		}
		else
		{
			aBuffer.append( static_cast< sal_Unicode >( '_' ) );
			if( c > 0x0fff )
				aBuffer.append( static_cast< sal_Unicode >(
							aHexTab[ (c >> 12) & 0x0f ]  ) );
			if( c > 0x00ff )
				aBuffer.append( static_cast< sal_Unicode >(
						aHexTab[ (c >> 8) & 0x0f ] ) );
			if( c > 0x000f )
				aBuffer.append( static_cast< sal_Unicode >(
						aHexTab[ (c >> 4) & 0x0f ] ) );
			aBuffer.append( static_cast< sal_Unicode >(
						aHexTab[ c & 0x0f ] ) );
			aBuffer.append( static_cast< sal_Unicode >( '_' ) );
			bEncoded = sal_True;
		}
	}

	if( aBuffer.getLength() > (1<<15)-1 )
		bEncoded = sal_False;

	if( bEncoded )
		rName = aBuffer.makeStringAndClear();
	return bEncoded;
}

sal_Bool XMLTransformerBase::DecodeStyleName( OUString& rName )
{
	sal_Bool bEncoded = sal_False;

	sal_Int32 nLen = rName.getLength();
	OUStringBuffer aBuffer( nLen );

	sal_Bool bWithinHex = sal_False;
	sal_Unicode cEnc = 0;
	for( sal_Int32 i = 0; i < nLen; i++ )
	{
		sal_Unicode c = rName[i];
		if( '_' == c )
		{
			if( bWithinHex )
			{
				aBuffer.append( cEnc );
				cEnc = 0;
			}
			else
			{
				bEncoded = sal_True;
			}
			bWithinHex = !bWithinHex;
		}
		else if( bWithinHex )
		{
			sal_Unicode cDigit;
			if( c >= '0' && c <= '9' )
			{
				cDigit = c - '0';
			}
    		else if( c >= 'a' && c <= 'f' )
			{
				cDigit = c - 'a' + 10;
			}
			else if( c >= 'A' && c <= 'F' )
			{
				cDigit = c - 'A' + 10;
			}
			else
			{
				// error
				bEncoded = sal_False;
				break;
			}
			cEnc = (cEnc << 4) + cDigit;
		}
		else
		{
			aBuffer.append( c );
		}
	}

	if( bEncoded )
		rName = aBuffer.makeStringAndClear();
	return bEncoded;
}

sal_Bool XMLTransformerBase::NegPercent( OUString& rValue )
{
	sal_Bool bRet = sal_False;
    sal_Bool bNeg = sal_False;
    double nVal = 0;

    sal_Int32 nPos = 0;
    sal_Int32 nLen = rValue.getLength();

    // skip white space
    while( nPos < nLen && sal_Unicode(' ') == rValue[nPos] )
        nPos++;

    if( nPos < nLen && sal_Unicode('-') == rValue[nPos] )
    {
        bNeg = sal_True;
        nPos++;
    }

    // get number
    while( nPos < nLen &&
           sal_Unicode('0') <= rValue[nPos] &&
           sal_Unicode('9') >= rValue[nPos] )
    {
        // TODO: check overflow!
        nVal *= 10;
        nVal += (rValue[nPos] - sal_Unicode('0'));
        nPos++;
    }
    double nDiv = 1.;
    if( nPos < nLen && sal_Unicode('.') == rValue[nPos] )
    {
        nPos++;

        while( nPos < nLen &&
               sal_Unicode('0') <= rValue[nPos] &&
               sal_Unicode('9') >= rValue[nPos] )
        {
            // TODO: check overflow!
            nDiv *= 10;
            nVal += ( static_cast<double>(rValue[nPos] - sal_Unicode('0')) / nDiv );
            nPos++;
        }
    }

    // skip white space
    while( nPos < nLen && sal_Unicode(' ') == rValue[nPos] )
        nPos++;

    if( nPos < nLen &&  sal_Unicode('%') == rValue[nPos] )
    {
    	if( bNeg )
       		nVal = -nVal;
		nVal += .5;

		sal_Int32 nIntVal = 100 - static_cast<sal_Int32>( nVal );

		OUStringBuffer aNewValBuffer;
		aNewValBuffer.append( nIntVal );
    	aNewValBuffer.append( sal_Unicode('%' ) );

		rValue = aNewValBuffer.makeStringAndClear();
		bRet = sal_True;
	}

	return bRet;
}

sal_Bool XMLTransformerBase::AddNamespacePrefix( ::rtl::OUString& rName,
							 sal_uInt16 nPrefix ) const
{
	rName = GetNamespaceMap().GetQNameByKey( nPrefix, rName, sal_False );
	return sal_True;
}

sal_Bool XMLTransformerBase::RemoveNamespacePrefix( ::rtl::OUString& rName,
							sal_uInt16 nPrefixOnly ) const
{
	OUString aLocalName;
	sal_uInt16 nPrefix =
		GetNamespaceMap()._GetKeyByAttrName( rName, &aLocalName, sal_False );
	sal_Bool bRet = XML_NAMESPACE_UNKNOWN != nPrefix &&
					(USHRT_MAX == nPrefixOnly || nPrefix == nPrefixOnly);
	if( bRet )
		rName = aLocalName;

	return bRet;
}

sal_Bool XMLTransformerBase::ConvertURIToOASIS( ::rtl::OUString& rURI,
										sal_Bool bSupportPackage ) const
{
	sal_Bool bRet = sal_False;
	if( m_aExtPathPrefix.getLength() && rURI.getLength() )
	{
		sal_Bool bRel = sal_False;
		switch( rURI[0] )
		{
		case '#':
			// no rel path, but
			// for package URIs, the '#' has to be removed
			if( bSupportPackage )
			{
				rURI = rURI.copy( 1 );
				bRet = sal_True;
			}
			break;
		case '/':
			// no rel path; nothing to do
			break;
		case '.':
			// a rel path; to keep URI simple, remove './', if there
			bRel = sal_True;
			if( rURI.getLength() > 1 && '/' == rURI[1] )
			{
				rURI = rURI.copy( 2 );
				bRet = sal_True;
			}
			break;
		default:
			// check for a RFC2396 schema
			{
				bRel = sal_True;
				sal_Int32 nPos = 1;
				sal_Int32 nLen = rURI.getLength();
				while( nPos < nLen )
				{
					switch( rURI[nPos] )
					{
					case '/':
						// a relative path segment
						nPos = nLen;	// leave loop
						break;
					case ':':
						// a schema
						bRel = sal_False;
						nPos = nLen;	// leave loop
						break;
					default:
						// we don't care about any other characters
						break;
					}
					++nPos;
				}
			}
		}

		if( bRel )
		{
			OUString sTmp( m_aExtPathPrefix );
			sTmp += rURI;
			rURI = sTmp;
			bRet = sal_True;
		}
	}

	return bRet;
}

sal_Bool XMLTransformerBase::ConvertURIToOOo( ::rtl::OUString& rURI,
										sal_Bool bSupportPackage ) const
{
	sal_Bool bRet = sal_False;
	if( rURI.getLength() )
	{
		sal_Bool bPackage = sal_False;
		switch( rURI[0] )
		{
		case '/':
			// no rel path; nothing to to
			break;
		case '.':
			// a rel path
			if( 0 == rURI.compareTo( m_aExtPathPrefix,
									 m_aExtPathPrefix.getLength() ) )
			{
				// an external URI; remove '../'
				rURI = rURI.copy( m_aExtPathPrefix.getLength() );
				bRet = sal_True;
			}
			else
			{
				bPackage = sal_True;
			}
			break;
		default:
			// check for a RFC2396 schema
			{
				bPackage = sal_True;
				sal_Int32 nPos = 1;
				sal_Int32 nLen = rURI.getLength();
				while( nPos < nLen )
				{
					switch( rURI[nPos] )
					{
					case '/':
						// a relative path segment within the package
						nPos = nLen;	// leave loop
						break;
					case ':':
						// a schema
						bPackage = sal_False;
						nPos = nLen;	// leave loop
						break;
					default:
						// we don't care about any other characters
						break;
					}
					++nPos;
				}
			}
		}

		if( bPackage && bSupportPackage )
		{
			OUString sTmp( OUString::valueOf( sal_Unicode( '#' ) ) );
			if( 0 == rURI.compareToAscii( "./", 2 ) )
				rURI = rURI.copy( 2 );
			sTmp += rURI;
			rURI = sTmp;
			bRet = sal_True;
		}
	}

	return bRet;
}

sal_Bool XMLTransformerBase::RenameAttributeValue(
    OUString& rOutAttributeValue,
    sal_Int32 nParam1,
    sal_Int32 nParam2,
    sal_Int32 nParam3 )
{
    return ( lcl_ConvertAttr( rOutAttributeValue, nParam1) ||
             lcl_ConvertAttr( rOutAttributeValue, nParam2) ||
             lcl_ConvertAttr( rOutAttributeValue, nParam3) );
}

// static
bool XMLTransformerBase::ConvertRNGDateTimeToISO( ::rtl::OUString& rDateTime )
{
    if( rDateTime.getLength() > 0 &&
        rDateTime.indexOf( sal_Unicode('.')) != -1 )
    {
        rDateTime = rDateTime.replace( sal_Unicode('.'), sal_Unicode(','));
        return true;
    }

    return false;
}

XMLTokenEnum XMLTransformerBase::GetToken( const OUString& rStr ) const
{
	XMLTransformerTokenMap::const_iterator aIter =
		m_pTokenMap->find( rStr );
	if( aIter == m_pTokenMap->end() )
		return XML_TOKEN_END;
	else
		return (*aIter).second;
}



const XMLTransformerContext *XMLTransformerBase::GetCurrentContext() const
{
	OSL_ENSURE( !m_pContexts->empty(), "empty stack" );


	return m_pContexts->empty() ? 0 : m_pContexts->back().get();
}

const XMLTransformerContext *XMLTransformerBase::GetAncestorContext(
														sal_uInt32 n ) const
{
	XMLTransformerContextVector::size_type nSize =
		m_pContexts->size();
	XMLTransformerContextVector::size_type nPos =
		static_cast<XMLTransformerContextVector::size_type>( n );

	OSL_ENSURE( nSize >nPos+2 , "invalid context" );

	return nSize > nPos+2 ? (*m_pContexts)[nSize-(nPos+2)].get() : 0;
}

bool XMLTransformerBase::isWriter() const
{
	Reference< XServiceInfo > xSI( mxModel, UNO_QUERY );
	return	xSI.is() &&
		(	xSI->supportsService( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextDocument" ) ) ) ||
			xSI->supportsService( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.WebDocument" ) ) ) ||
			xSI->supportsService( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.GlobalDocument" ) ) ) );
}
