/**************************************************************
 *
 * 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 control 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();
		}
		*/
	}
}
