/*
* 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 org.apache.jmeter.engine;
import java.util.LinkedList;
import org.apache.jmeter.engine.util.NoThreadClone;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jorphan.collections.HashTree;
import org.apache.jorphan.collections.HashTreeTraverser;
import org.apache.jorphan.collections.ListedHashTree;
/**
* Clones the test tree, skipping test elements that implement {@link NoThreadClone} by default.
*/
public class TreeCloner implements HashTreeTraverser {
private final ListedHashTree newTree;
private final LinkedList<Object> objects = new LinkedList<>();
private final boolean honourNoThreadClone;
/**
* Clone the test tree, honouring NoThreadClone markers.
*
*/
public TreeCloner() {
this(true);
}
/**
* Clone the test tree.
*
* @param honourNoThreadClone set false to clone NoThreadClone nodes as well
*/
public TreeCloner(boolean honourNoThreadClone) {
newTree = new ListedHashTree();
this.honourNoThreadClone = honourNoThreadClone;
}
/**
* {@inheritDoc}
*/
@Override
public final void addNode(Object node, HashTree subTree) {
node = addNodeToTree(node);
addLast(node);
}
/**
* @param node Node to add to tree or not
* @return Object node (clone or not)
*/
protected Object addNodeToTree(Object node) {
if ( (node instanceof TestElement) // Check can cast for clone
// Don't clone NoThreadClone unless honourNoThreadClone == false
&& (!honourNoThreadClone || !(node instanceof NoThreadClone))
) {
node = ((TestElement) node).clone();
newTree.add(objects, node);
} else {
newTree.add(objects, node);
}
return node;
}
/**
* add node to objects LinkedList
* @param node Object
*/
private void addLast(Object node) {
objects.addLast(node);
}
@Override
public void subtractNode() {
objects.removeLast();
}
public ListedHashTree getClonedTree() {
return newTree;
}
@Override
public void processPath() {
}
}