/*
* ====================================================================
* 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.gui.tree;
import java.util.*;
import org.apache.jmeter.util.*;
import org.apache.jmeter.control.TestPlan;
import org.apache.jmeter.threads.ThreadGroup;
import org.apache.jmeter.config.ConfigElement;
import org.apache.jmeter.timers.Timer;
import org.apache.jmeter.samplers.SampleListener;
import org.apache.jmeter.gui.JMeterComponentModel;
import org.apache.jmeter.util.ListedHashTree;
import org.apache.log4j.Category;
import org.apache.jmeter.control.SamplerController;
import org.apache.jmeter.control.WorkBench;
/************************************************************
* Title: JMeter Description: Copyright: Copyright (c) 2000 Company: Apache
* This class simulates a tree and eliminates the need for the swing
* components. Most of the code in this class has been borrowed from
* JMeterTreeModel.
*
*@author Tushar Bhatia
*@created June 18, 2001
*@version 1.0
*@see org.apache.jmeter.NonGuiDriver
***********************************************************/
public class NonGuiTree extends NonGuiTreeNode
{
private Category log = Category.getInstance(NonGuiTree.class);
/************************************************************
* !ToDo (Constructor description)
***********************************************************/
public NonGuiTree()
{
super(null);
log.info("Adding Test Plan");
this.insertNodeInto(new NonGuiTreeNode(TestPlan.createTestPlan("Test Plan")), 0);
log.info("Adding WorkBench");
this.insertNodeInto(new NonGuiTreeNode(new WorkBench("WorkBench", false)), 1);
}
/************************************************************
* !ToDoo (Method description)
*
*@return !ToDo (Return description)
***********************************************************/
public NonGuiTreeNode getRoot()
{
return this;
}
/************************************************************
* !ToDo
*
*@param subTree !ToDo
*@param current !ToDo
***********************************************************/
public void addSubTree(ListedHashTree subTree, NonGuiTreeNode current)
{
if (log.isDebugEnabled())
{
log.debug("addSubTree:" + (current == null ? "null" : current.getUserObject().getClass().getName()));
}
Iterator iter = subTree.list().iterator();
while (iter.hasNext())
{
JMeterComponentModel item = (JMeterComponentModel)iter.next();
if (item instanceof TestPlan)
{
current = (NonGuiTreeNode)((NonGuiTreeNode)getRoot()).getChildAt(0);
addSubTree(subTree.get(item), current);
}
else
{
addSubTree(subTree.get(item), addComponent(item, current));
}
}
}
/************************************************************
* Returns the JMeterComponentModel after compiling(adding all children to
* different objects) after parsing the tree. To invoke this method use the
* following code: <br>
* <pre>
*NonGuiTree ngt = new NonGuiTree();
* pass the LinkedHashTree to this class to store all the components.
*ngt.addSubTree(linkedHashTree, null);
* now compile
*TestPlan tp = (TestPlan)ngt.compileComponent(ngt.getChildAt(0));
*Collection threads = tp.getThreadGroups();
*.
*.
* and work on the threads by passing them to the engine etc.
*</pre>
*
*@param node !ToDo (Parameter description)
*@return !ToDo (Return description)
*@see org.apache.NonGuiDriver
***********************************************************/
public JMeterComponentModel compileComponent(NonGuiTreeNode node)
{
if (log.isDebugEnabled())
{
log.debug("compileComponent:" + node.getUserObject().getClass().getName());
}
traverseNode(node);
return (JMeterComponentModel)node.getUserObject();
}
private NonGuiTreeNode addComponent(JMeterComponentModel component, NonGuiTreeNode node)
{
if (log.isDebugEnabled())
{
log.debug("addComponent:" + (component == null ? "null" : component.getClass().getName()) +
", " + node.getUserObject().getClass().getName());
}
NonGuiTreeNode newNode = new NonGuiTreeNode(component);
node.insertNodeInto(newNode, node.getChildCount());
newNode.setParent(node);
return newNode;
}
private void traverseNode(NonGuiTreeNode node)
{
if (log.isDebugEnabled())
{
log.debug("traverseNode:" + node.getUserObject().getClass().getName());
}
Enumeration enum = node.children();
while (enum.hasMoreElements())
{
NonGuiTreeNode child = (NonGuiTreeNode)enum.nextElement();
traverseNode(child);
}
NonGuiTreeNode parent = (NonGuiTreeNode)node.getParent();
if (node != null && parent != null)
{
addChildToParent(node.getUserObject(), parent.getUserObject());
}
}
private void addChildToParent(Object child, Object parent)
{
if (log.isDebugEnabled())
{
log.debug("addChildToParent:" + (child != null ? child.getClass().getName() : "null") + ", " +
(parent != null ? parent.getClass().getName() : "null"));
}
if (parent instanceof ThreadGroup)
{
if (child instanceof Timer)
{
((ThreadGroup)parent).addTimer((Timer)child);
}
else if (child instanceof ConfigElement)
{
((ThreadGroup)parent).addConfigElement((ConfigElement)child);
}
else if (child instanceof SamplerController)
{
((ThreadGroup)parent).addSamplerController((SamplerController)child);
}
else if (child instanceof SampleListener)
{
((ThreadGroup)parent).addListener((SampleListener)child);
// Open the file if this is a Filer.
if (child instanceof org.apache.jmeter.reporters.Filer)
{
org.apache.jmeter.reporters.Filer filer = (org.apache.jmeter.reporters.Filer)child;
log.debug("Opening the file:" + filer.getFile());
filer.open();
//filer.setAutoFlush(true);
}
}
}
else if (parent instanceof SamplerController)
{
if (child instanceof SamplerController)
{
((SamplerController)parent).addSamplerController((SamplerController)child);
}
else if (child instanceof ConfigElement)
{
((SamplerController)parent).addConfigElement((ConfigElement)child);
}
}
else if (parent instanceof TestPlan)
{
if (child instanceof ThreadGroup)
{
((TestPlan)parent).addThreadGroup((ThreadGroup)child);
}
}
}
}