/*
* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache JMeter" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache JMeter", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.jmeter.save.old.xml;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.apache.log.Hierarchy;
import org.apache.log.Logger;
import org.apache.jorphan.collections.HashTree;
import org.apache.jorphan.collections.ListedHashTree;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
/************************************************************
* Title: Description: Copyright: Copyright (c) 2000 Company:
*
*@author
*@created $Date: 2002/10/17 19:47:17 $
*@version 1.0
***********************************************************/
public class XmlHandler extends DefaultHandler
{
transient private static Logger log = Hierarchy.getDefaultHierarchy().getLoggerFor(
"jmeter.util");
protected LinkedList objectStack;
NameSpaceHandler informer;
List finalHandlers;
ListedHashTree objectHierarchy = new ListedHashTree();
boolean replaced = false;
/************************************************************
* !ToDo (Constructor description)
*
*@param informer !ToDo (Parameter description)
***********************************************************/
public XmlHandler(NameSpaceHandler informer)
{
this.informer = informer;
objectStack = new LinkedList();
finalHandlers = new LinkedList();
}
/************************************************************
* !ToDoo (Method description)
*
*@return !ToDo (Return description)
***********************************************************/
public ListedHashTree getDataTree()
{
if (!replaced)
{
replaceWithModels(objectHierarchy);
}
replaced = true;
return objectHierarchy;
}
/************************************************************
* HandlerBase implementation This reports an error that has occured. This
* indicates that a rule was broken in validation, but that parsing can
* continue.
*
*@param e !ToDo (Parameter description)
*@exception SAXException !ToDo (Exception description)
***********************************************************/
public void fatalError(SAXParseException e) throws SAXException
{
log.error("***Parsing Fatal Error**\n" +
" Line: " + e.getLineNumber() + "\n" +
" URI: " + e.getSystemId() + "\n" +
" Message: " + e.getMessage());
throw new SAXException("Fatal Error encountered");
}
/************************************************************
* HandlerBase implementation This reports a fatal error that has occured.
* This indicates that a rule was broken that makes continued parsing
* impossible.
*
*@param errs parse error message
*@exception SAXException !ToDo (Exception description)
***********************************************************/
public void error(SAXParseException errs) throws SAXException
{
log.error("***Parsing Error**\n" +
" Line: " + errs.getLineNumber() + "\n" +
" URI: " + errs.getSystemId() + "\n" +
" Message: " + errs.getMessage());
throw new SAXException("Error encountered");
}
/************************************************************
* HandlerBase implementation This reports a warning that has occured; this
* indicates that while no XML rules were broken, something appears to be
* incorrect or missing.
*
*@param err parse warning message
*@exception SAXException !ToDo (Exception description)
***********************************************************/
public void warning(SAXParseException err) throws SAXException
{
log.warn("***Parsing Warning**\n" +
" Line: " + err.getLineNumber() + "\n" +
" URI: " + err.getSystemId() + "\n" +
" Message: " + err.getMessage());
throw new SAXException("Warning encountered");
}
/************************************************************
* !ToDo (Method description)
*
*@param chardata !ToDo (Parameter description)
*@param start !ToDo (Parameter description)
*@param end !ToDo (Parameter description)
*@exception SAXException !ToDo (Exception description)
***********************************************************/
public void characters(char[] chardata, int start, int end) throws SAXException
{
try
{
if(start >= 0 && start < chardata.length && (end + start) <= chardata.length)
{
getCurrentHandler().handleData(new String(chardata, start, end));
}
}
catch (Exception e)
{
log.error("",e);
}
}
/************************************************************
* !ToDo (Method description)
*
*@param uri !ToDo (Parameter description)
*@param localName !ToDo (Parameter description)
*@param qName !ToDo (Parameter description)
*@param atts !ToDo (Parameter description)
***********************************************************/
public void startElement(String uri, String localName, String qName, Attributes atts)
{
documentElement(localName+":"+qName, atts);
TagHandler newXmlObject = informer.getXmlObject(qName, atts);
if (newXmlObject == null)
{
try
{
getCurrentHandler().passToHandler(qName, atts);
}
catch (Exception ex)
{
log.debug("No current Handler for " + qName);
}
}
else
{
newXmlObject.setXmlParent(this);
objectHierarchy.add(objectStack, newXmlObject);
objectStack.addLast(newXmlObject);
try
{
getCurrentHandler().passToHandler(qName, atts);
}
catch (Exception ex)
{
log.debug("(2)No current Handler for " + qName);
}
}
}
/************************************************************
* HandlerBase implementation
*
*@param uri !ToDo (Parameter description)
*@param localName !ToDo (Parameter description)
*@param qName !ToDo (Parameter description)
*@exception SAXException !ToDo (Exception description)
***********************************************************/
public void endElement(java.lang.String uri, java.lang.String localName,
java.lang.String qName) throws SAXException
{
try
{
getCurrentHandler().passToHandler(qName);
}
catch (Exception ex)
{
//log.error("",ex);
}
if (currentHandlerIsDone())
{
TagHandler currentHandler = (TagHandler)objectStack.removeLast();
try
{
TagHandler previousHandler = (TagHandler)objectStack.getLast();
previousHandler.notifySubElementEnded(currentHandler.getModel());
}
catch(Exception e)
{
}
}
}
/************************************************************
* !ToDo (Method description)
*
*@param handler !ToDo (Parameter description)
*@return !ToDo (Return description)
***********************************************************/
public List takeChildObjects(TagHandler handler)
{
List stack = new LinkedList();
Iterator iter = objectStack.iterator();
while (iter.hasNext())
{
Object item = iter.next();
stack.add(item);
if (item.equals(handler))
{
break;
}
}
HashTree subTree = objectHierarchy.getTree(stack);
if (subTree == null)
{
return new LinkedList();
}
List items = new LinkedList(subTree.list());
iter = items.iterator();
while (iter.hasNext())
{
Object item = iter.next();
replaceSubItems(subTree, item);
subTree.remove(item);
}
return items;
}
/************************************************************
* !ToDoo (Method description)
*
*@param tagName !ToDo (Parameter description)
*@param atts !ToDo (Parameter description)
*@return !ToDo (Return description)
***********************************************************/
protected TagHandler getXmlObject(String tagName, Attributes atts)
{
return informer.getXmlObject(tagName, atts);
}
/************************************************************
* !ToDoo (Method description)
*
*@return !ToDo (Return description)
*@exception NoCurrentHandlerException !ToDo (Exception description)
***********************************************************/
protected TagHandler getCurrentHandler() throws NoCurrentHandlerException
{
if (objectStack.size() == 0)
{
throw new NoCurrentHandlerException();
}
else
{
return (TagHandler)objectStack.getLast();
}
}
private void replaceWithModels(HashTree tree)
{
log.debug("XML elements: "+tree.list());
Iterator iter = new LinkedList(tree.list()).iterator();
while (iter.hasNext())
{
TagHandler item = (TagHandler)iter.next();
tree.replace(item,item.getModel());
replaceWithModels(tree.getTree(item.getModel()));
}
}
private boolean currentHandlerIsDone()
{
try
{
return getCurrentHandler().isDone();
}
catch (NoCurrentHandlerException e)
{
return false;
}
}
private void documentElement(String name, Attributes atts)
{
if(log.isDebugEnabled())
{
log.debug("startElement= " + name);
for (int i = 0; i < atts.getLength(); i++)
{
log.debug(" Attribute= " + atts.getQName(i) + "=" + atts.getValue(i));
}
}
}
private void replaceSubItems(HashTree subTree, Object item)
{
HashTree subSubTree = subTree.getTree(item);
Collection subItems = subSubTree.list();
Iterator iter2 = subItems.iterator();
while (iter2.hasNext())
{
Object subItem = iter2.next();
subTree.set(subItem, subSubTree.getTree(subItem));
}
}
}