/**************************************************************
 *
 * 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_xmlsecurity.hxx"

#include "encryptionengine.hxx"
#include <com/sun/star/xml/crypto/XXMLEncryptionTemplate.hpp>
#include <com/sun/star/xml/wrapper/XXMLElementWrapper.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>

namespace cssu = com::sun::star::uno;
namespace cssl = com::sun::star::lang;
namespace cssxc = com::sun::star::xml::crypto;
namespace cssxw = com::sun::star::xml::wrapper;

#define ENCRYPTION_TEMPLATE "com.sun.star.xml.crypto.XMLEncryptionTemplate"

#define	DECLARE_ASCII( SASCIIVALUE )																			\
	rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SASCIIVALUE ) )

EncryptionEngine::EncryptionEngine( )
        :m_nIdOfBlocker(-1)
{
}

bool EncryptionEngine::checkReady() const
/****** EncryptionEngine/checkReady ******************************************
 *
 *   NAME
 *	checkReady -- checks the conditions for the main operation.
 *
 *   SYNOPSIS
 *	bReady = checkReady( );
 *
 *   FUNCTION
 *	checks whether all following conditions are satisfied:
 *	1. the main operation has't begun yet;
 *	2. the key material is known;
 *	3. the id of the template blocker is known;
 *	4. both the key element and the encryption template
 *	   are bufferred.
 *
 *   INPUTS
 *	empty
 *
 *   RESULT
 *	bReady - true if all conditions are satisfied, false otherwise
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	bool rc = true;

	sal_Int32 nKeyInc = 0;
	if (m_nIdOfKeyEC != 0)
	{
		nKeyInc = 1;
	}

	if (m_bMissionDone ||
	    m_nIdOfKeyEC == -1 ||
	    m_nIdOfBlocker == -1 ||
	    1+nKeyInc > m_nNumOfResolvedReferences )
	{
		rc = false;
	}

	return rc;
}

void EncryptionEngine::tryToPerform( )
    	throw (cssu::Exception, cssu::RuntimeException)
/****** EncryptionEngine/tryToPerform ****************************************
 *
 *   NAME
 *	tryToPerform -- tries to perform the encryption/decryption operation.
 *
 *   SYNOPSIS
 *	tryToPerform( );
 *
 *   FUNCTION
 *	if the situation is ready, perform following operations.
 *	1. prepares a encryption template;
 *	2. calls the encryption bridge component;
 *	3. clears up all used resources;
 *	4. notifies the result listener;
 *	5. sets the "accomplishment" flag.
 *
 *   INPUTS
 *	empty
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	if (checkReady())
	{
		const rtl::OUString sEncryptionTemplate (
			RTL_CONSTASCII_USTRINGPARAM( ENCRYPTION_TEMPLATE ) );
		cssu::Reference < cssxc::XXMLEncryptionTemplate > xEncryptionTemplate(
			mxMSF->createInstance( sEncryptionTemplate ), cssu::UNO_QUERY );

		OSL_ASSERT( xEncryptionTemplate.is() );

		cssu::Reference< cssxw::XXMLElementWrapper > xXMLElement
			= m_xSAXEventKeeper->getElement( m_nIdOfTemplateEC );

		xEncryptionTemplate->setTemplate(xXMLElement);

		startEngine( xEncryptionTemplate );

		/*
		 * done
		 */
		clearUp( );

		notifyResultListener();

		m_bMissionDone = true;
	}
}

void EncryptionEngine::clearUp( ) const
/****** EncryptionEngine/clearup *********************************************
 *
 *   NAME
 *	clearUp -- clear up all resources used by this operation.
 *
 *   SYNOPSIS
 *	clearUp( );
 *
 *   FUNCTION
 *	cleaning resources up includes:
 *	1. releases the ElementCollector for the encryption template element;
 *	2. releases the Blocker for the encryption template element;
 *	3. releases the ElementCollector for the key element, if there is one.
 *
 *   INPUTS
 *	empty
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	cssu::Reference < cssxc::sax::XReferenceResolvedBroadcaster >
		xReferenceResolvedBroadcaster( m_xSAXEventKeeper, cssu::UNO_QUERY );

	xReferenceResolvedBroadcaster->removeReferenceResolvedListener(
		m_nIdOfTemplateEC,
		(const cssu::Reference < cssxc::sax::XReferenceResolvedListener >)((SecurityEngine *)this));

	m_xSAXEventKeeper->removeElementCollector(m_nIdOfTemplateEC);

	if (m_nIdOfBlocker != -1)
	{
		m_xSAXEventKeeper->removeBlocker(m_nIdOfBlocker);
	}

	if (m_nIdOfKeyEC != 0 && m_nIdOfKeyEC != -1)
	{
		m_xSAXEventKeeper->removeElementCollector(m_nIdOfKeyEC);
	}
}

/* XBlockerMonitor */
void SAL_CALL EncryptionEngine::setBlockerId( sal_Int32 id )
	throw (com::sun::star::uno::Exception, com::sun::star::uno::RuntimeException)
{
	m_nIdOfBlocker = id;
	tryToPerform();
}
