/**************************************************************
 * 
 * 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.
 * 
 *************************************************************/



package com.sun.star.xml.security.uno;

/* uno classes */
import com.sun.star.uno.UnoRuntime;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.lang.XInitialization;
import com.sun.star.uno.XComponentContext;

import com.sun.star.xml.crypto.*;
import com.sun.star.xml.crypto.sax.*;

/*
 * this class maintains the data for an encryption operation.
 */
class EncryptionEntity extends SecurityEntity
{
	private int m_nEncryptionElementCollectorId;
	
	EncryptionEntity(
		XSecuritySAXEventKeeper xSAXEventKeeper,
		boolean isExporting,
		Object resultListener,
		XXMLSecurityContext xXMLSecurityContext,
		XXMLSignature xXMLSignature,
		XXMLEncryption xXMLEncryption,
		XMultiComponentFactory xRemoteServiceManager,
		XComponentContext xRemoteContext)
	{
		super(xSAXEventKeeper, xXMLSecurityContext, xXMLSignature,
			 xXMLEncryption, xRemoteServiceManager, xRemoteContext);
		
		m_nEncryptionElementCollectorId = m_xSAXEventKeeper.addSecurityElementCollector(
			ElementMarkPriority.AFTERMODIFY,
			true);
			
		m_xSAXEventKeeper.setSecurityId(m_nEncryptionElementCollectorId, m_nSecurityId);
		
		if (isExporting)
		{
			try
			{
				/*
				 * creates a Encryptor.
				 */
				Object encryptor = m_xRemoteServiceManager.createInstanceWithContext(
					TestTool.ENCRYPTOR_COMPONENT, m_xRemoteContext);
					
				m_xReferenceResolvedListener = 
					(XReferenceResolvedListener)UnoRuntime.queryInterface(
						XReferenceResolvedListener.class, encryptor); 
	
				/*
				 * initializes the Encryptor.
				 */
				XInitialization xInitialization =
					(XInitialization)UnoRuntime.queryInterface(
						XInitialization.class, m_xReferenceResolvedListener);
				Object args[]=new Object[5];
				args[0] = new Integer(m_nSecurityId).toString();
				args[1] = m_xSAXEventKeeper;
				args[2] = new Integer(m_nEncryptionElementCollectorId).toString();
				args[3] = m_xXMLSecurityContext.getSecurityEnvironment();
				args[4] = m_xXMLEncryption;
				xInitialization.initialize(args);
				
				/*
				 * sets encryption result listener.
				 */
				XEncryptionResultBroadcaster m_xEncryptionResultBroadcaster = 
					(XEncryptionResultBroadcaster)UnoRuntime.queryInterface(
						XEncryptionResultBroadcaster.class, m_xReferenceResolvedListener);
				m_xEncryptionResultBroadcaster.addEncryptionResultListener(
					(XEncryptionResultListener)UnoRuntime.queryInterface(
						XEncryptionResultListener.class, resultListener));
			}
			catch( com.sun.star.uno.Exception e)
			{
				e.printStackTrace();
			}
		}
		else
		{
			try{
				/*
				 * creates a Decryptor.
				 */
				Object decryptor = m_xRemoteServiceManager.createInstanceWithContext(
					TestTool.DECRYPTOR_COMPONENT, m_xRemoteContext);
					
				m_xReferenceResolvedListener = 
					(XReferenceResolvedListener)UnoRuntime.queryInterface(
						XReferenceResolvedListener.class, decryptor); 
	
				/*
				 * initializes the Decryptor.
				 */
				XInitialization xInitialization = (XInitialization)UnoRuntime.queryInterface(XInitialization.class, m_xReferenceResolvedListener);
				Object args[]=new Object[5];
				args[0] = new Integer(m_nSecurityId).toString();
				args[1] = m_xSAXEventKeeper;
				args[2] = new Integer(m_nEncryptionElementCollectorId).toString();
				args[3] = m_xXMLSecurityContext;
				args[4] = m_xXMLEncryption;
				xInitialization.initialize(args);
				
				/*
				 * sets decryption result listener.
				 */
				XDecryptionResultBroadcaster m_xDecryptionResultBroadcaster = 
					(XDecryptionResultBroadcaster)UnoRuntime.queryInterface(
						XDecryptionResultBroadcaster.class, m_xReferenceResolvedListener);
				m_xDecryptionResultBroadcaster.addDecryptionResultListener(
					(XDecryptionResultListener)UnoRuntime.queryInterface(
						XDecryptionResultListener.class, resultListener));
			}
			catch( com.sun.star.uno.Exception e)
			{
				e.printStackTrace();
			}
		}
		
		/*
		 * creates a Blocker.
		 */
		int blockerId = m_xSAXEventKeeper.addBlocker();
		m_xSAXEventKeeper.setSecurityId(blockerId, m_nSecurityId);
		
		try
		{
			XBlockerMonitor xBlockerMonitor = (XBlockerMonitor)UnoRuntime.queryInterface(
				XBlockerMonitor.class, m_xReferenceResolvedListener);
			xBlockerMonitor.setBlockerId(blockerId);
		}
		catch( com.sun.star.uno.Exception e)
		{
			e.printStackTrace();
		}

		/*
		 * configures the resolve listener for the encryption template.
		 */
		XReferenceResolvedBroadcaster xReferenceResolvedBroadcaster = 
			(XReferenceResolvedBroadcaster)UnoRuntime.queryInterface(
				XReferenceResolvedBroadcaster.class, m_xSAXEventKeeper);
		xReferenceResolvedBroadcaster.addReferenceResolvedListener(m_nEncryptionElementCollectorId, m_xReferenceResolvedListener);
	}
	
	/*
	 * add the reference to this encryption.
	 *
	 * 1. askes the SAXEventKeeper to add a ElementCollector to for the new
	 * referenced element;
	 * 2. configures this ElementCollector's security id;
	 * 3. tells the SAXEventKeeper which listener will receive the reference
	 * resolved notification.
	 * 4. notifies the SignatureCollector about the reference id.
	 */
	protected boolean setReference(boolean isExporting)
	{
		boolean rc = false;
		
		int referenceId = m_xSAXEventKeeper.addSecurityElementCollector(
			isExporting?
			(ElementMarkPriority.AFTERMODIFY):(ElementMarkPriority.BEFOREMODIFY),
			true);
				
		m_xSAXEventKeeper.setSecurityId(referenceId, m_nSecurityId);

		XReferenceResolvedBroadcaster xReferenceResolvedBroadcaster = 
			(XReferenceResolvedBroadcaster)UnoRuntime.queryInterface(
				XReferenceResolvedBroadcaster.class, m_xSAXEventKeeper);
		xReferenceResolvedBroadcaster.addReferenceResolvedListener(
			referenceId, m_xReferenceResolvedListener);
			
		try
		{
			XReferenceCollector xReferenceCollector = 
				(XReferenceCollector)UnoRuntime.queryInterface(
					XReferenceCollector.class, m_xReferenceResolvedListener);
			xReferenceCollector.setReferenceId(referenceId);
		}
		catch( com.sun.star.uno.Exception e)
		{
			e.printStackTrace();
			rc = false;
		}
		
		return rc;
	}
}

