/**************************************************************
 *
 * 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 org.w3c.dom.Node;
import com.sun.star.xml.sax.XDocumentHandler;
import org.w3c.dom.Attr;
import org.w3c.dom.NamedNodeMap;

/*
 * this class is used to parse a document into SAX events
 */
class ParsingThread
{
	/*
	 * the Node which will be handled with in the next step
	 */
	private Node m_node;

	/*
	 * the event to be handled in the next step.
	 * true means endElement event, false otherwise.
	 */
	private boolean m_bIsEndEvent;

	/*
	 * the document handler which receives generated SAX events
	 */
	private XDocumentHandler m_xDocumentHandler;

	/*
	 * the TestTool which receives UI feedbacks
	 */
	private TestTool m_testTool;


        ParsingThread(Node node, XDocumentHandler xDocumentHandler, TestTool testTool)
        {
        	m_node = node;
        	m_xDocumentHandler = xDocumentHandler;
        	m_testTool = testTool;

        	m_bIsEndEvent = false;
        }

        /*
         * changes the document handler.
         */
        protected void setHandler(XDocumentHandler xDocumentHandler)
        {
        	this.m_xDocumentHandler = xDocumentHandler;
        }

        /*
         * sends the next SAX event.
         * when there is no further step, then false is returned,
         * otherwise, true returned.
         */
        protected boolean nextStep()
        {
        	boolean rc = true;

        	try
        	{
	        	String message;
			int type = m_node.getNodeType();
			if (!m_bIsEndEvent)
			/*
			 * the next event is not a endElement event.
			 */
			{
				switch (type)
				{
				case Node.DOCUMENT_NODE: /* startDocument */
					m_testTool.updatesCurrentSAXEventInformation("startDocument");
					m_xDocumentHandler.startDocument();
					m_testTool.updatesUIs();
					break;
				case Node.ELEMENT_NODE: /* startElement */
					String nodeName = m_node.getNodeName();
					message = "startElement:"+nodeName;
					NamedNodeMap attrs = m_node.getAttributes();

					AttributeListHelper attributeListHelper = new AttributeListHelper();

					int length = attrs.getLength();
					for (int i=0; i<length; ++i)
					{
						Attr attr = (Attr)attrs.item(i);
						attributeListHelper.setAttribute(attr.getName(), "CDATA", attr.getValue());
						message += " "+attr.getName()+"='"+attr.getValue()+"'";
					}

					m_testTool.updatesCurrentSAXEventInformation(message);
					m_xDocumentHandler.startElement(m_node.getNodeName(), attributeListHelper);

					m_testTool.updatesUIs();
					break;
				case Node.TEXT_NODE: /* characters */
					message = m_node.getNodeValue();
					if (message != null)
					{
						m_testTool.updatesCurrentSAXEventInformation("characters:"+message);
						m_xDocumentHandler.characters(message);
						m_testTool.updatesUIs();
					}
					break;
				case Node.COMMENT_NODE: /* comment */
					break;
				case Node.PROCESSING_INSTRUCTION_NODE: /* PI */
					m_testTool.updatesCurrentSAXEventInformation("processingInstruction:"+m_node.getNodeName()+" "+m_node.getNodeValue());
					m_xDocumentHandler.processingInstruction(m_node.getNodeName(), m_node.getNodeValue());
					m_testTool.updatesUIs();
					break;
				}

				/*
				 * figures out the event for the next step.
				 */
				switch (type)
				{
					case Node.DOCUMENT_NODE:
					case Node.ELEMENT_NODE:
						if (m_node.hasChildNodes())
						/*
						 * for a Document node or an Element node,
						 * if the node has children, then the next event will be for its
						 * first child node.
						 */
						{
							m_node = m_node.getFirstChild();
						}
						else
						/*
						 * otherwise, the next event will be endElement.
						 */
						{
							m_bIsEndEvent = true;
						}
						break;
					case Node.TEXT_NODE:
					case Node.PROCESSING_INSTRUCTION_NODE:
					case Node.COMMENT_NODE:
						Node nextNode = m_node.getNextSibling();
						if (nextNode != null)
						/*
						 * for other kinds of node,
						 * if it has a next sibling, then the next event will be for that
						 * sibling.
						 */
						{
							m_node = nextNode;
						}
						else
						/*
						 * otherwise, the next event will be the endElement for the node's
						 * parent node.
						 */
						{
							m_node = m_node.getParentNode();
							m_bIsEndEvent = true;
						}
						break;
				}
			}
			else
			/*
			 * the next event is an endElement event.
			 */
			{
				switch (type)
				{
					case Node.DOCUMENT_NODE: /* endDocument */
						m_testTool.updatesCurrentSAXEventInformation("endDocument");
						m_xDocumentHandler.endDocument();
						m_testTool.updatesUIs();

						/*
						 * no further steps.
						 */
						rc = false;
						break;
					case Node.ELEMENT_NODE: /* endElement */
						m_testTool.updatesCurrentSAXEventInformation("endElement:"+m_node.getNodeName());
						m_xDocumentHandler.endElement(m_node.getNodeName());
						m_testTool.updatesUIs();

						Node nextNode = m_node.getNextSibling();
						if (nextNode != null)
						/*
						 * if the node has a next sibling, then the next event will be the
						 * start event for that sibling node.
						 */
						{
							m_node = nextNode;
							m_bIsEndEvent = false;
						}
						else
						/*
						 * otherwise, the next event will be the endElement for the node's
						 * parent node.
						 */
						{
							m_node = m_node.getParentNode();
						}
						break;
				}
			}
		}
		catch(  com.sun.star.xml.sax.SAXException e)
		{
			e.printStackTrace();

			/*
			 * forces to end.
			 */
			rc = false;
		}

		return rc;
	}
}
