package nl.tudelft.lifetiles.tree.model; import java.util.StringTokenizer; /** * A simple parser that will parse a single tree in newick format * to a simple tree. * * @author Albert Smit * */ public final class PhylogeneticTreeParser { /** * Uninstantiable class. */ private PhylogeneticTreeParser() { // do nothing } /** * parses the String the parser has been given. * the String is first tokenized, * after which the method iterates over all tokens. * * @param tree * The string describing the tree * @return The parsed tree. */ public static PhylogeneticTreeItem parse(final String tree) { PhylogeneticTreeItem root = new PhylogeneticTreeItem(); // split the string into tokens, and keep the delimiters in the list so // we have // information about the next token. StringTokenizer tokenizer = new StringTokenizer(tree, "(:,);", true); PhylogeneticTreeItem currentNode = root; // loop over all tokens while (tokenizer.hasMoreTokens()) { String currentToken = tokenizer.nextToken(); // this starts a list of child nodes, add a child node and make it // our current node if ("(".equals(currentToken)) { // parser needs to instantiate objects. @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") PhylogeneticTreeItem newChild = new PhylogeneticTreeItem(); newChild.setParent(currentNode); currentNode = newChild; } else if (":".equals(currentToken)) { // next token is a distance, add it to the current node String distanceToken = tokenizer.nextToken(); double distance = Double.parseDouble(distanceToken); currentNode.setDistance(distance); } else if (",".equals(currentToken)) { // next token is another child, add a new child to the list and // make it the current node currentNode = currentNode.getParent(); // parser needs to instantiate objects. @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") PhylogeneticTreeItem newChild = new PhylogeneticTreeItem(); newChild.setParent(currentNode); currentNode = newChild; } else if (")".equals(currentToken)) { // list of children ends, go up 1 level so we can add a name and // distance to this node // if they are specified currentNode = currentNode.getParent(); } else if (";".equals(currentToken)) { // tree is done, nothing special needs to be done break; } else { // final case, the current token is text, // so the current token is a name. currentNode.setName(currentToken); } } return root; } }