Since you liked it so much, I made a version for you that will work "out of the box". Downgrading java syntax can be quite painful, so I made it ready for you.
Steps:
1) Create a new "User Defined Java Class" step
2) Make sure the previous step produce rows with fields "child" (String) and "parent" (String)
3) Click checkbox "Clear the result fields?" in lower right corner
4) Add an output Fieldname in the "Fields" tab below, Fieldname = hierarchy and Type = String)
5) Copy code below into main "Class code" text box
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
Map nodes = new HashMap();
Set rootNodeNames = new HashSet();
Iterator rootNodeNamesIterator = null;
// Instructions:
// 1) Click checkbox "Clear the result fields?" in lower right corner
// 2) Add an output Fieldname in the "Fields" tab below:
// Fieldname = hierarchy
// Type = String
public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException
{
Object[] r = null;
if (first)
{
first = false;
while (true) //first read all incoming rows
{
r = getRow();
if (r == null)
{
break;
}
String childName = get(Fields.In, "child").getString(r);
String parentName = get(Fields.In, "parent").getString(r);
storeRow(childName, parentName);
for (Iterator it = nodes.entrySet().iterator(); it.hasNext();) //make a set of all root nodes
{
Map.Entry pairs = (Map.Entry) it.next();
Node node = (Node)pairs.getValue();
rootNodeNames.add(node.getRootNode().name);
}
}
rootNodeNamesIterator = rootNodeNames.iterator(); //store iterator for processing output rows
}
return setOutputRow();
}
private boolean setOutputRow() throws KettleException
{
if(rootNodeNamesIterator.hasNext())
{
String rootNodeName = (String)rootNodeNamesIterator.next();
Node rootNode = (Node)nodes.get(rootNodeName);
String result = rootNode.name;
Node child = rootNode.child;
while(child != null)
{
result = result + "," + child.name;
child = child.child;
}
Object[] r = createOutputRow(null, data.outputRowMeta.size());
get(Fields.Out, "hierarchy").setValue(r, result);
putRow(data.outputRowMeta, r);
return true;
}
setOutputDone();
return false;
}
private void storeRow(String childName, String parentName)
{
Node childNode = new Node(childName);
Node parentNode = new Node(parentName);
if(nodes.containsKey(parentName)) // if parent already exists, use the existing node
{
parentNode = (Node)nodes.get(parentName);
}
if(parentNode.hasName()) //if parent is valid
{
parentNode.setChild(childNode);
childNode.setParent(parentNode);
nodes.put(parentName, parentNode);
}
nodes.put(childName, childNode);
}
class Node {
String name = null;
Node parent = null;
Node child = null;
public Node()
{
}
public Node(String name)
{
this.name = name;
}
boolean hasName()
{
return (name != null);
}
boolean hasParent()
{
return (parent != null);
}
boolean hasChild()
{
return (child != null);
}
void setChild(Node n)
{
child = n;
}
void setParent(Node n)
{
parent = n;
}
Node getRootNode()
{
if(parent == null)
{
return this;
}
return parent.getRootNode();
}
}