/** * Copyright (c) 2009, iPlant Collaborative, Texas Advanced Computing Center This software is licensed * under the CC-GNU GPL version 2.0 or later. License: http://creativecommons.org/licenses/GPL/2.0/ */ package org.iplantc.phyloviewer.client.tree.viewer.model; import java.util.Collections; import java.util.Comparator; import java.util.Set; import org.iplantc.phyloviewer.shared.model.INode; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArray; import com.google.gwt.json.client.JSONObject; public class JsNode extends JavaScriptObject implements INode { protected JsNode() { } @Override public final native int getId() /*-{ return this.id; }-*/; @Override public final native void setId(int id) /*-{ this.id = id; }-*/; public final native String getLabel() /*-{ return this.name; }-*/; public final native void setLabel(String label) /*-{ this.name = label; }-*/; private final native <T extends JavaScriptObject> JsArray<T> getNativeChildren() /*-{ return this.children; }-*/; public final int getNumberOfChildren() { if(null == this.getNativeChildren()) return 0; return this.getNativeChildren().length(); } public final JsNode getChild(int index) { return (JsNode)this.getNativeChildren().get(index); } public final INode[] getChildren() { JsNode[] children = new JsNode[getNumberOfChildren()]; for(int i = 0;i < getNumberOfChildren();i++) { children[i] = getChild(i); } return children; } public final Boolean isLeaf() { return 0 == this.getNumberOfChildren(); } public final int getNumberOfLeafNodes() { int count = 0; if(this.isLeaf()) { count = 1; } else { for(int i = 0;i < this.getNumberOfChildren();++i) { count += this.getChild(i).getNumberOfLeafNodes(); } } return count; } private final int _findMaximumDepthToLeafImpl(int currentDepth) { int localMaximum = currentDepth; if(!this.isLeaf()) { for(int i = 0;i < this.getNumberOfChildren();++i) { int depth = this.getChild(i)._findMaximumDepthToLeafImpl(currentDepth + 1); if(depth > localMaximum) { localMaximum = depth; } } } return localMaximum; } public final int findMaximumDepthToLeaf() { return this._findMaximumDepthToLeafImpl(0); } public final String findLabelOfFirstLeafNode() { if(this.isLeaf()) { return this.getLabel(); } return this.getChild(0).findLabelOfFirstLeafNode(); } @Override public final void sortChildrenBy(Comparator<INode> comparator) { if(this.getNumberOfChildren() > 0) { NodeList list = new NodeList(getNativeChildren()); Collections.sort(list, comparator); } } @Override public final int getNumberOfNodes() { int count = 1; for(int i = 0;i < getNumberOfChildren();i++) { INode child = getChild(i); count += child.getNumberOfNodes(); } return count; } @Override public final native Double getBranchLength() /*-{ this.branchLength; }-*/; @Override public final native void setBranchLength(Double branchLength) /*-{ this.branchLength = branchLength; }-*/; @Override public final double findMaximumDistanceToLeaf() { return this.findMaximumDistanceToLeaf(0.0); } private double findMaximumDistanceToLeaf(double currentDistance) { double localMaximum = currentDistance; int numChildren = this.getNumberOfChildren(); if(0 < numChildren) { for(int i = 0;i < numChildren;++i) { JsNode child = this.getChild(i); double distance = child.findMaximumDistanceToLeaf(currentDistance + this.getBranchLength()); if(distance > localMaximum) { localMaximum = distance; } } } return localMaximum; } @Override public final String getMetaDataString() { JSONObject object = new JSONObject ( this.getMetaDataStringNative() ); return object.toString(); } private final native JavaScriptObject getMetaDataStringNative() /*-{ return this.metadata; }-*/; @Override public final INode mrca(Set<INode> nodes) { /* * FIXME return the most recent common ancestor of the given set of nodes within this INode's * subtree. Return null if this subtree does not contain all of the nodes. Probably need a parent * reference to do this with any kind of efficiency */ return null; } }