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

import java.util.Stack;
import java.util.Vector;

/* 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.sax.XDocumentHandler;
import com.sun.star.xml.sax.XAttributeList;
import com.sun.star.xml.sax.SAXException;

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

/*
 * the XMLSecurityFrameworkController class is used to controll the xml security framework.
 */
public class XMLSecurityFrameworkController 
	implements XDocumentHandler, XSignatureCreationResultListener, XSignatureVerifyResultListener,
		   XEncryptionResultListener, XDecryptionResultListener, XSAXEventKeeperStatusChangeListener
{
	/*
	 * UNO framework component
	 */
	private XMultiComponentFactory  m_xRemoteServiceManager;
	private XComponentContext       m_xRemoteContext;
	
	/*
	 * xml security related UNO components
	 */
	private XSecuritySAXEventKeeper m_xSAXEventKeeper;
	private XXMLDocumentWrapper     m_xXMLDocumentWrapper;
	private XDocumentHandler        m_xOutputHandler;
	private XXMLSecurityContext     m_xXMLSecurityContext;
	private XXMLSignature           m_xXMLSignature;
	private XXMLEncryption          m_xXMLEncryption;
	
        /*
         * used to reserve the current SAX ancestor path
         */
	private Stack  m_currentPath;
	
	/*
	 * maintains all SignatureEntities.
	 */
	private Vector m_signatureList;
	
	/*
	 * maintains all EncryptionEntities.
	 */
	private Vector m_encryptionList;
	
	/*
	 * maintains all unsolved reference Ids.
	 * These ids are strings which is the value of the id attribute
	 * of the referenced element.
	 */
	private Vector m_vUnsolvedReferenceIds;
	
	/*
	 * maintains all unsolved reference keeper ids.
	 * The keeper id is used to uniquely identify a bufferred element
	 * by the SAXEventKeeper.
	 */
	private Vector m_vUnsolvedReferencedKeeperIds;
	
	/*
	 * maintains the left time that each unsolved reference can be 
	 * claimed.
	 */
	private Vector m_vUnsolvedReferenceRefNum;
	
	/*
	 * whether exporting or importing
	 */
	private boolean m_bIsExporting;
	
	/*
	 * whether java or c
	 */
	private boolean m_bIsJavaBased;
	
	/*
	 * whether the SAXEventKeeper is blocking
	 */
	private boolean m_bIsBlocking;
	
	/*
	 * whether it is collecting a bufferred element
	 */
	private boolean m_bIsInsideCollectedElement;
	
	/*
	 * whether a SAXEventKeeper is in the SAX chain
	 */
	private boolean m_bSAXEventKeeperIncluded;

	/*
	 * the ParsingThread used to parse the document
	 */
	private ParsingThread m_parsingThread;
	
	/*
	 * the next document handler that will receives SAX events
	 * from the parsing thread.
	 * if the SAXEventKeeper is on the SAX chain, then this
	 * variable will be the SAXEventKeeper, otherwise, this
	 * variable will be the xOutputHandler.
	 */
	private XDocumentHandler m_xExportHandler;
	
	/*
	 * the TestTool used to feedback information
	 */
	private TestTool m_testTool;
	
	/*
	 * for encryption target
	 */
	private boolean m_bIsEncryptionTarget;
	private EncryptionEntity m_EncryptionForTarget;
	
	XMLSecurityFrameworkController(
		TestTool testTool,
		boolean bIsExporting,
		boolean bIsJavaBased,
		XDocumentHandler xOutputHandler,
		ParsingThread parsingThread,
		XXMLSecurityContext xXMLSecurityContext,
		XXMLSignature xXMLSignature,
		XXMLEncryption xXMLEncryption,
		XMultiComponentFactory xRemoteServiceManager,
		XComponentContext xRemoteContext)
	{
		m_bIsExporting = bIsExporting;
		m_bIsJavaBased = bIsJavaBased;
		
		m_xOutputHandler = xOutputHandler;
		m_xXMLSecurityContext = xXMLSecurityContext;
		m_xXMLSignature = xXMLSignature;
		m_xXMLEncryption = xXMLEncryption;
		m_xRemoteServiceManager = xRemoteServiceManager;
		m_xRemoteContext = xRemoteContext;
		
		m_testTool = testTool;
		m_parsingThread = parsingThread;
		
		m_signatureList = new Vector();
		m_encryptionList = new Vector();
		
		m_vUnsolvedReferenceIds = new Vector();
		m_vUnsolvedReferencedKeeperIds = new Vector();
		m_vUnsolvedReferenceRefNum = new Vector();
		
		m_xXMLDocumentWrapper = null;
		m_xSAXEventKeeper = null;
		
		m_bSAXEventKeeperIncluded = false;
		m_bIsBlocking = false;
		m_bIsInsideCollectedElement = false;
		
		m_bIsEncryptionTarget = false;
		m_EncryptionForTarget = null;

		changeOutput();
		
		m_currentPath = new Stack();
		
		foundSecurityRelated();
	}
	
/**************************************************************************************
 * private methods
 **************************************************************************************/
 
        /*
         * changes the output document handler.
         */
        private void changeOutput()
        {
		if (m_bIsExporting)
		{
			m_parsingThread.setHandler(this);
			
			/*
			 * If the SAXEventKeeper is in the SAX chain, then redirects output
			 * to the SAXEventKeeper, otherwise, to the m_xOutputHandler
			 */
			if (m_bSAXEventKeeperIncluded)
			{
				m_xExportHandler = (XDocumentHandler)UnoRuntime.queryInterface(
							XDocumentHandler.class, m_xSAXEventKeeper);
				m_xSAXEventKeeper.setNextHandler(m_xOutputHandler);
				
				m_testTool.updatesSAXChainInformation("XMLExporter -> SAXEventKeeper -> SAXWriter");
			}
			else
			{
				m_xExportHandler = m_xOutputHandler;
				m_testTool.updatesSAXChainInformation("XMLExporter -> SAXWriter");
			}
		}
		else
		{
			if (m_bSAXEventKeeperIncluded)
			{
				m_parsingThread.setHandler(
					(XDocumentHandler)UnoRuntime.queryInterface(XDocumentHandler.class, m_xSAXEventKeeper));
				m_xSAXEventKeeper.setNextHandler(this);
				m_testTool.updatesSAXChainInformation("SAXParser -> SAXEventKeeper -> XMLImporter");
			}
			else
			{
				m_parsingThread.setHandler(this);
				m_testTool.updatesSAXChainInformation("SAXParser -> XMLImporter");
			}
			m_xExportHandler = m_xOutputHandler;
		}
	}
        
        /*
         * handles the situation when a security related element is found.
         * if the SAXEventKeeper is not initialized, then creates a
         * SAXEventKeeper.
         * the return value represents whether the SAXEventKeeper is newly
         * created.
         */	
	private boolean foundSecurityRelated()
	{
		if (m_xSAXEventKeeper == null)
		{
			m_testTool.showMessage("Message from : "+
						(m_bIsExporting?"XMLExporter":"XMLImporter")+
						"\n\nA security related content found, a SAXEventKeeper is created.\n ");
			
			m_bIsBlocking = false;
			m_bIsInsideCollectedElement = false;

			try
			{
				/*
				 * creates an XMLDocumentWrapper component.
				 */
				Object xmlDocumentObj = null;
				
				if (m_bIsJavaBased)
				{
					xmlDocumentObj = m_xRemoteServiceManager.createInstanceWithContext(
						TestTool.XMLDOCUMENTWRAPPER_COMPONENT_JAVA, m_xRemoteContext);
				}
				else
				{
					xmlDocumentObj = m_xRemoteServiceManager.createInstanceWithContext(
						TestTool.XMLDOCUMENTWRAPPER_COMPONENT_C, m_xRemoteContext);
				}
				
				m_xXMLDocumentWrapper = (XXMLDocumentWrapper)UnoRuntime.queryInterface(
					XXMLDocumentWrapper.class, xmlDocumentObj);
					
				/*
				 * creates a SAXEventKeeper component.
				 */
				Object saxEventKeeperObj = m_xRemoteServiceManager.createInstanceWithContext(
					TestTool.SAXEVENTKEEPER_COMPONENT, m_xRemoteContext);

				m_xSAXEventKeeper = 
					(XSecuritySAXEventKeeper)UnoRuntime.queryInterface(
						XSecuritySAXEventKeeper.class, saxEventKeeperObj); 
	                        
	                        /*
	                         * initializes the SAXEventKeeper component with the XMLDocumentWrapper component.
	                         */
				XInitialization xInitialization = 
					(XInitialization)UnoRuntime.queryInterface(
						XInitialization.class, m_xSAXEventKeeper);
				Object args[]=new Object[1];
				args[0] = m_xXMLDocumentWrapper;
				xInitialization.initialize(args);
			}
			catch( com.sun.star.uno.Exception e)
			{
				e.printStackTrace();
			}
			
			/*
			 * configures the SAXEventKeeper's status change listener.
			 */
			XSAXEventKeeperStatusChangeBroadcaster xSaxEventKeeperStatusChangeBroadcaster = 
				(XSAXEventKeeperStatusChangeBroadcaster)UnoRuntime.queryInterface(
					XSAXEventKeeperStatusChangeBroadcaster.class, m_xSAXEventKeeper); 
			xSaxEventKeeperStatusChangeBroadcaster.addSAXEventKeeperStatusChangeListener(this);
		}
		
		boolean rc = !m_bSAXEventKeeperIncluded;
		
		/*
		 * changes the export document handler.
		 */
		m_bSAXEventKeeperIncluded=true;
		changeOutput();

		return rc;
	}

	/*
	 * finds key element or referenced element for a signature.
	 */
	private void findKeyOrReference(SecurityEntity signatureEntity, String uriStr, boolean isFindingKey)
	{
		int i=0;
		
		while (i<m_vUnsolvedReferenceIds.size())
		{
			String id = (String)m_vUnsolvedReferenceIds.elementAt(i);
			
			if (id.equals(uriStr))
			{
				int refNum = ((Integer)m_vUnsolvedReferenceRefNum.elementAt(i)).intValue();
				int keeperId = ((Integer)m_vUnsolvedReferencedKeeperIds.elementAt(i)).intValue();
				
				if (isFindingKey)
				{
					/*
					 * clones a new ElementCollector for the key element.
					 */
					int cloneKeeperId = m_xSAXEventKeeper.cloneElementCollector(
						keeperId,
						m_bIsExporting?
						(ElementMarkPriority.BEFOREMODIFY):(ElementMarkPriority.AFTERMODIFY));
					
					/*
					 * notifies the key keeper id.
					 */
					signatureEntity.setKeyId(cloneKeeperId);
					
					/*
					 * sets the security id for the key.
					 */
					m_xSAXEventKeeper.setSecurityId(cloneKeeperId, signatureEntity.getSecurityId());
	
					/*
					 * sets the resolve listener.
					 */
					XReferenceResolvedBroadcaster xReferenceResolvedBroadcaster =
						(XReferenceResolvedBroadcaster)UnoRuntime.queryInterface(
							XReferenceResolvedBroadcaster.class, m_xSAXEventKeeper);
					xReferenceResolvedBroadcaster.addReferenceResolvedListener(
						cloneKeeperId,
						signatureEntity.getReferenceListener());
				}
				else
				{
					/*
					 * clones a new ElementCollector for the referenced element.
					 */
					int cloneKeeperId = m_xSAXEventKeeper.cloneElementCollector(
						keeperId, 
						m_bIsExporting?
						(ElementMarkPriority.AFTERMODIFY):(ElementMarkPriority.BEFOREMODIFY));
					
					/*
					 * sets the security id.
					 */
					m_xSAXEventKeeper.setSecurityId(cloneKeeperId, signatureEntity.getSecurityId());
					
					/*
					 * sets the resolve listener.
					 */
					XReferenceResolvedBroadcaster xReferenceResolvedBroadcaster =
						(XReferenceResolvedBroadcaster)UnoRuntime.queryInterface(
							XReferenceResolvedBroadcaster.class, m_xSAXEventKeeper);
					xReferenceResolvedBroadcaster.addReferenceResolvedListener(cloneKeeperId,
						signatureEntity.getReferenceListener());
						
					try{
						XReferenceCollector xReferenceCollector =
							(XReferenceCollector)UnoRuntime.queryInterface(
								XReferenceCollector.class, signatureEntity.getReferenceListener());
						xReferenceCollector.setReferenceId(cloneKeeperId);
					}
					catch( com.sun.star.uno.Exception e)
					{
						e.printStackTrace();
					}
				}
					
				/*
				 * if this unsolved reference reaches its max reference number, remove this reference
				 * from all vectors.
				 */
				refNum--;
				if (refNum == 0)
				{
					m_xSAXEventKeeper.removeElementCollector(keeperId);
					m_vUnsolvedReferenceIds.remove(i);
					m_vUnsolvedReferencedKeeperIds.remove(i);
					m_vUnsolvedReferenceRefNum.remove(i);
				}
				else
				{
					m_vUnsolvedReferenceRefNum.setElementAt(new Integer(refNum),(i));
					++i;
				}
				
				/*
				 * If it is find a key, then no further search is needed, one
				 * signature has one key at most.
				 */
				if (isFindingKey)
				{
					break;
				}
			}
			else
			{
				++i;
			}
		}
	}
        
	/*
	 * checks whether a startElement event represents any security related information.
	 * return true if this event can't be forwarded into the SAX chain.
	 */
	private boolean checkSecurityElement(String localName, com.sun.star.xml.sax.XAttributeList xattribs)
	{
		boolean rc = false;
		
		if (localName.equals("Signature"))
		/*
		 * this element is a Signature element.
		 */
		{
			SignatureEntity signatureEntity = new SignatureEntity(
				m_xSAXEventKeeper,
				m_bIsExporting,
				this,
				m_xXMLSecurityContext,
				m_xXMLSignature,
				m_xXMLEncryption,
				m_xRemoteServiceManager,
				m_xRemoteContext);

			m_signatureList.add(signatureEntity);
			m_currentPath.push(signatureEntity);
		}
		else if(localName.equals("Reference"))
		{
			if (!m_currentPath.empty())
			{
				Object signedInfo = m_currentPath.pop();
				
				if (!m_currentPath.empty())
				{
					Object objSignature = m_currentPath.peek();
			
					if ((objSignature instanceof SignatureEntity) && signedInfo.toString().equals("SignedInfo"))
					/*
					 * this element is a Reference element in a signature.
					 */
					{
						String uriStr = xattribs.getValueByName("URI");
						
						if (uriStr.charAt(0) == '#')
						{
							uriStr = uriStr.substring(1);
							SignatureEntity signatureEntity = (SignatureEntity)objSignature;
			
							if (uriStr != null && uriStr.length()>0)
							{
								signatureEntity.addReferenceId(uriStr);
								findKeyOrReference(signatureEntity, uriStr, false);
							}
						}
					}
				}
				m_currentPath.push(signedInfo);
			}
			m_currentPath.push(localName);
		}
		else if(localName.equals("KeyValue") || 
		        localName.equals("KeyName") ||
		        localName.equals("X509Data") ||
		        localName.equals("EncryptedKey"))
		{
			if (!m_currentPath.empty())
			{
				Object keyInfo = m_currentPath.pop();
				
				if (!m_currentPath.empty())
				{
					Object objSorE = m_currentPath.peek();
					
					if ((objSorE instanceof SignatureEntity) && keyInfo.toString().equals("KeyInfo"))
					/*
					 * this element is the key element of a signature.
					 */
					{
						SignatureEntity signatureEntity = (SignatureEntity)objSorE;
						signatureEntity.setKeyId(0);
					}
					else if ((objSorE instanceof EncryptionEntity) && keyInfo.toString().equals("KeyInfo"))
					/*
					 * this element is the key element of an encryption.
					 */
					{
						EncryptionEntity theEncryption = (EncryptionEntity)objSorE;
						theEncryption.setKeyId(0);
					}
				}
				m_currentPath.push(keyInfo);
			}
			
			m_currentPath.push(localName);
		}
		else if(localName.equals("RetrievalMethod"))
		{
			if (!m_currentPath.empty())
			{
				Object keyInfo = m_currentPath.pop();
				
				if (!m_currentPath.empty())
				{
					Object objSorE = m_currentPath.peek();
					
					if ((objSorE instanceof SignatureEntity) && keyInfo.toString().equals("KeyInfo"))
					/*
					 * this element is the RetrievalMethod element in a signature,
					 * which will include the key uri of this signature.
					 */
					{
						String uriStr = xattribs.getValueByName("URI");
						SignatureEntity signatureEntity = (SignatureEntity)objSorE;
		
						if (uriStr != null && uriStr.length()>0)
						{
							signatureEntity.setKeyURI(uriStr);
							findKeyOrReference(signatureEntity,uriStr, true);
						}
					}
					else if ((objSorE instanceof EncryptionEntity) && keyInfo.toString().equals("KeyInfo"))
					/*
					 * this element is the RetrievalMethod element in an encryption,
					 * which will include the key uri of this encryption.
					 */
					{
						String uriStr = xattribs.getValueByName("URI");
						EncryptionEntity theEncryption = (EncryptionEntity)objSorE;
		
						if (uriStr != null && uriStr.length()>0)
						{
							theEncryption.setKeyURI(uriStr);
							findKeyOrReference(theEncryption, uriStr, true);
						}
					}
				}
				m_currentPath.push(keyInfo);
			}
			m_currentPath.push(localName);
		}
		else if (localName.equals("EncryptedData")) /* || localName.equals("EncryptedKey")) */
		/*
		 * this element is an Encryption element.
		 */
		{
			EncryptionEntity theEncryption = new EncryptionEntity(
				m_xSAXEventKeeper,
				m_bIsExporting,
				this,
				m_xXMLSecurityContext,
				m_xXMLSignature,
				m_xXMLEncryption,
				m_xRemoteServiceManager,
				m_xRemoteContext);
				
			m_encryptionList.add(theEncryption);
			
			if (m_bIsExporting)
			{
				m_currentPath.push(theEncryption);
			}
			else
			{
				String uriStr = xattribs.getValueByName("keyURI");
				if (uriStr != null && uriStr.length()>0)
				{
					theEncryption.setKeyURI(uriStr);
					findKeyOrReference(theEncryption,uriStr, true);
				}
				else
				{
					theEncryption.setKeyId(0);
				}
				
				rc = true;
			}
		}
		else
		/*
		 * not a security related element.
		 */
		{
			m_currentPath.push(localName);
		}
		
		return rc;
	}
	
	/*
	 * checks whether a startElement event is referenced by any security entity.
	 */
	private void checkReference(String localName, com.sun.star.xml.sax.XAttributeList xattribs, String id)
	{
		String refNumStr = xattribs.getValueByName("refNum");
		
		if ( m_bIsEncryptionTarget )
		{
			m_EncryptionForTarget.setReference(m_bIsExporting);
			m_bIsEncryptionTarget = false;
		}
		
		if (id != null && id.length()>0 )
		/*
		 * only if this element has id attribute, then it can be referenced by
		 * a security entity.
		 */
		{
			/*
			 * if this element has an "refNum" attribute, then the value will be
			 * the max referencing number on this element, otherwise, set the max
			 * referencing number to 999.
			 */
			int refNum = 999;
			
			if (refNumStr != null && refNumStr.length()>0 )
			{
				refNum = new Integer(refNumStr).intValue();
			}
			
			int length;
				
			/*
			 * searches the signature list to check whether any sigture has
			 * reference on this element.
			 */
			length = m_signatureList.size();
			for (int i=0; i<length; ++i)
			{
				SignatureEntity signatureEntity = (SignatureEntity)m_signatureList.elementAt(i);
				
				if (signatureEntity.setReference(id, m_bIsExporting))
				{
					refNum--;
				}
				
				if (signatureEntity.setKey(id, m_bIsExporting))
				{
					refNum--;
				}
			}
			
			/*
			 * searches the encryption list for reference.
			 */
			length = m_encryptionList.size();
			for (int i=0; i<length; ++i)
			{
				EncryptionEntity theEncryption = (EncryptionEntity)m_encryptionList.elementAt(i);
				
				if (theEncryption.setKey(id, m_bIsExporting))
				{
					refNum--;
				}
			}
			
			/*
			 * if the max referencing number is not reached, then add this element
			 * into the unsolved reference list.
			 */
			if (refNum>0)
			{
				int keeperId;
				
				if (localName.equals("EncryptedKey"))
				{
					keeperId = m_xSAXEventKeeper.addSecurityElementCollector(
						m_bIsExporting?
						(ElementMarkPriority.BEFOREMODIFY):(ElementMarkPriority.AFTERMODIFY),
						true);
				}
				else
				{
					keeperId = m_xSAXEventKeeper.addSecurityElementCollector(
						m_bIsExporting?
						(ElementMarkPriority.AFTERMODIFY):(ElementMarkPriority.BEFOREMODIFY),
						false);
				}
					
				m_vUnsolvedReferenceIds.add(id);
				m_vUnsolvedReferencedKeeperIds.add(new Integer(keeperId));
				m_vUnsolvedReferenceRefNum.add(new Integer(refNum));
			}
		}
	}
	
	/*
	 * configures the output handler.
	 */
	private void setOutputHandler(XDocumentHandler handler)
	{
		m_xOutputHandler = handler;
		changeOutput();
	}
	
	
/**************************************************************************************
 * protected methods
 **************************************************************************************/
        
        /*
         * methods used to transfer unsolved reference information.
         */
	protected Vector getUnsolvedReferenceIds()
	{
		return m_vUnsolvedReferenceIds;
	}
	
	protected Vector getUnsolvedReferenceKeeperIds()
	{
		return m_vUnsolvedReferencedKeeperIds;
	}

	protected Vector getUnsolvedReferenceRefNum()
	{
		return m_vUnsolvedReferenceRefNum;
	}
	
	protected String getBufferNodeTreeInformation()
	{
		if (m_xSAXEventKeeper != null)
		{
			return m_xSAXEventKeeper.printBufferNodeTree();
		}
		else
		{
			return null;
		}
	}
	
	protected void getDocument(XDocumentHandler handler)
	{
		if (m_xXMLDocumentWrapper != null)
		{
			try
			{
				m_xXMLDocumentWrapper.getTree(handler);
			}
			catch(SAXException e)
			{
				e.printStackTrace();
			}
		}
	}
	
	protected void endMission()
	{
		while (m_signatureList.size()>0 || m_encryptionList.size()>0)
		{
			if (m_signatureList.size()>0)
			{
				SignatureEntity signatureEntity = (SignatureEntity)m_signatureList.elementAt(0);
				m_signatureList.remove(0);
				signatureEntity.endMission();
			}
			else if (m_encryptionList.size()>0)
			{
				EncryptionEntity theEncryption = (EncryptionEntity)m_encryptionList.elementAt(0);
				m_encryptionList.remove(0);
				theEncryption.endMission();
			}
		}
		
		while (m_vUnsolvedReferenceIds.size()>0)
		{
			int keeperId = ((Integer)m_vUnsolvedReferencedKeeperIds.elementAt(0)).intValue();
			m_xSAXEventKeeper.removeElementCollector(keeperId);
			m_vUnsolvedReferenceIds.remove(0);
			m_vUnsolvedReferencedKeeperIds.remove(0);
			m_vUnsolvedReferenceRefNum.remove(0);
		}
		
		m_xSAXEventKeeper.setNextHandler(null);
		
		XSAXEventKeeperStatusChangeBroadcaster xSaxEventKeeperStatusChangeBroadcaster = 
			(XSAXEventKeeperStatusChangeBroadcaster)UnoRuntime.queryInterface(
				XSAXEventKeeperStatusChangeBroadcaster.class, m_xSAXEventKeeper); 
		xSaxEventKeeperStatusChangeBroadcaster.addSAXEventKeeperStatusChangeListener(null);
		
		m_xSAXEventKeeper = null;
		m_xXMLDocumentWrapper = null;
		m_xOutputHandler = null;
		m_xXMLSecurityContext = null;
		m_xXMLSignature = null;
		m_xXMLEncryption = null;
		
		m_xExportHandler = null;
		m_parsingThread.setHandler(null);
	}

/**************************************************************************************
 * public methods
 **************************************************************************************/

	/*
	 * XDocumentHandler
	 */
        public void startDocument()
	{
		try{
			m_xExportHandler.startDocument();
		}
		catch( com.sun.star.xml.sax.SAXException e)
		{
			e.printStackTrace();
		}
		
	}

        public void endDocument()
	{
		try{
			m_xExportHandler.endDocument();
		}
		catch( com.sun.star.xml.sax.SAXException e)
		{
			e.printStackTrace();
		}
	}
	
	public void startElement (String str, com.sun.star.xml.sax.XAttributeList xattribs)
	{
		try{
			String idAttr = xattribs.getValueByName("id");
			if (idAttr == null)
			{
				idAttr = xattribs.getValueByName("Id");
			}
			
			boolean hasIdAttr = (idAttr != null && idAttr.length()>0 );
			boolean needResend = false;
			
			if (hasIdAttr ||
			    (str.equals("Signature")||str.equals("EncryptedData")))/* || str.equals("EncryptedKey"))) */
			{
				if (foundSecurityRelated() && !m_bIsExporting)
				{
					needResend = true;
				}
			}
			
			boolean suppressToNext = checkSecurityElement(str, xattribs);
			
			checkReference(str, xattribs, idAttr);
			
			if (needResend)
			{
				m_xSAXEventKeeper.setNextHandler(null);
				
				XDocumentHandler saxEventKeeperHandler = 
					(XDocumentHandler)UnoRuntime.queryInterface(
						XDocumentHandler.class, m_xSAXEventKeeper);
				saxEventKeeperHandler.startElement(str, xattribs);
				m_xSAXEventKeeper.setNextHandler((XDocumentHandler)this);
			}

			if (!suppressToNext)
			{
				m_xExportHandler.startElement(str, xattribs);
			}
		}
		catch( com.sun.star.xml.sax.SAXException e)
		{
			e.printStackTrace();
		}
	}

	public void endElement(String str)
	{
		if (!m_currentPath.empty())
		{
	        	Object obj = m_currentPath.pop();
        	
        		if (obj.toString().equals("SignedInfo"))
        		{
				if (!m_currentPath.empty())
				{
		        		Object objSignature = m_currentPath.peek();
		        		if (objSignature != null && objSignature instanceof SignatureEntity)
	        			{
	        				((SignatureEntity)objSignature).setReferenceNumber();
	        			}
	        		}
	        	}
	        	else if (obj instanceof EncryptionEntity)
	        	{
       				m_bIsEncryptionTarget = true;
				m_EncryptionForTarget = (EncryptionEntity)obj;

	        	}
        	}
		
		try{
			m_xExportHandler.endElement(str);
		}
		catch( com.sun.star.xml.sax.SAXException e)
		{
			e.printStackTrace();
		}
	}
	
	public void characters(String str)
	{
		try{
		        m_xExportHandler.characters(str);
		}
		catch( com.sun.star.xml.sax.SAXException e)
		{
			e.printStackTrace();
		}
	}
	
	public void ignorableWhitespace(String str)
	{
	}
	
	public void processingInstruction(String aTarget, String aData)
	{
		try{
			m_xExportHandler.processingInstruction(aTarget, aData);
		}
		catch( com.sun.star.xml.sax.SAXException e)
		{
			e.printStackTrace();
		}
	}

	public void setDocumentLocator (com.sun.star.xml.sax.XLocator xLocator ) 
		throws com.sun.star.xml.sax.SAXException
	{
	}
	
	
	/*
	 * XSignatureCreationResultListener
	 */
	public void signatureCreated(int securityId, SecurityOperationStatus creationResult)
	{
		String message = new String();
		message += "A Signature is created:";
		message += "\nSecurity Id = "+securityId;
		message += "\nCreation result = "+((creationResult==SecurityOperationStatus.OPERATION_SUCCEEDED)?"Succeed":"Fail");
		
		m_testTool.showMessage("Message from : SignatureCreator\n\n"+message+"\n ");
	}

	/*
	 * XSignatureVerifyResultListener
	 */
	public void signatureVerified(int securityId, SecurityOperationStatus verifyResult)
	{
		String message = new String();
		message += "A Signature is verified:";
		message += "\nSecurity Id = "+securityId;
		message += "\nVerify result = "+((verifyResult==SecurityOperationStatus.OPERATION_SUCCEEDED)?"Succeed":"Fail");
		
		m_testTool.showMessage("Message from : SignatureVerifier\n\n"+message+"\n ");
	}

	/*
	 * XEncryptionResultListener
	 */
	public void encrypted(int securityId, SecurityOperationStatus encryptionResult)
	{
		String message = new String();
		message += "An EncryptedData is encrypted:";
		message += "\nSecurity Id = "+securityId;
		message += "\nEncrypt result = "+((encryptionResult==SecurityOperationStatus.OPERATION_SUCCEEDED)?"Succeed":"Fail");
		
		m_testTool.showMessage("Message from : Encryptor\n\n"+message+"\n ");
	}
	
	/*
	 * XDecryptionResultListener methods
	 */
	public void decrypted(int securityId, SecurityOperationStatus decryptionResult)
	{
		String message = new String();
		message += "An EncryptedData is decrypted:";
		message += "\nSecurity Id = "+securityId;
		message += "\nDecrypt result = "+((decryptionResult==SecurityOperationStatus.OPERATION_SUCCEEDED)?"Succeed":"Fail");
		
		m_testTool.showMessage("Message from : Decryptor\n\n"+message+"\n ");
	}
	
	/*
	 * XSAXEventKeeperStatusChangeListener methods
	 */
	public void blockingStatusChanged(boolean isBlocking)
	{
		m_testTool.showMessage("Message from : SAXEventKeeper\n\n"+
					(isBlocking?"The SAX event stream is blocked.":"The SAX event stream is unblocked.")+
					"\n ");
		
		this.m_bIsBlocking = isBlocking;
	}
	
	public void collectionStatusChanged(boolean isInsideCollectedElement)
	{
		m_testTool.showMessage("Message from : SAXEventKeeper\n\n"+
					(isInsideCollectedElement?"Begin to buffer data ...":"End of data bufferring.")+
					"\n ");
					
		/*
		this.m_bIsInsideCollectedElement = isInsideCollectedElement;
		
		if ( !m_bIsInsideCollectedElement && !m_bIsBlocking)
		{
			m_bSAXEventKeeperIncluded = false;
		}
		else
		{
			m_bSAXEventKeeperIncluded = true;
		}
		changeOutput();
		*/
	}
	
	public void bufferStatusChanged(boolean isBufferEmpty)
	{
		m_testTool.showMessage("Message from : SAXEventKeeper\n\n"+
					(isBufferEmpty?"All bufferred data are released, the SAXEventKeeper is destroyed.":"buffer data appears.")+
					"\n ");
		/*
		if (isBufferEmpty)
		{
			m_xXMLDocumentWrapper = null;
			m_xSAXEventKeeper = null;
			m_bSAXEventKeeperIncluded = false;
			changeOutput();
		}
		*/
	}
}

