/******************************************************************************* * Copyright 2012 University of Southern California * * Licensed 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. * * This code was developed by the Information Integration Group as part * of the Karma project at the Information Sciences Institute of the * University of Southern California. For more information, publications, * and related projects, please see: http://www.isi.edu/integration ******************************************************************************/ package edu.isi.karma.rep.hierarchicalheadings; import java.util.ArrayList; import java.util.List; import java.util.Map; import edu.isi.karma.view.Stroke; import edu.isi.karma.view.Stroke.StrokeStyle; import edu.isi.karma.view.alignmentHeadings.AlignmentNode; public class HHTree { private List<HHTNode> rootNodes = new ArrayList<HHTNode>(); private int colIndex; private int maxDepth; public static int getFrontier(Map<String, Integer> map) { return 0; } public void constructHHTree(TForest forest) { /*** Create HHTNode for each TNode with same set of children ***/ populateHHTreeFromRootTNodes(forest.getRoots()); /*** Calculate the startCol and endCol for each HHTNode ***/ calculateStartColAndEndCol(); /*** Calculate depth for each HHTNode ***/ calculateDepth(); /*** Calculate left and right border ***/ calculateLeftAndRightStroke(rootNodes); /*** Calculate the complete list of left and right strokes ***/ calculateLeftAndRightStrokes(); // Debug // printHHTree(); } public int countRootNodes() { return colIndex; } private void calculateLeftAndRightStrokes() { for(HHTNode root:rootNodes){ // Add the left and right stroke to the list root.getLeftStrokes().add(root.getLeftStroke()); root.getRightStrokes().add(root.getRightStroke()); // Add the stroke to children (if any) if(!root.isLeaf()) calculateLeftAndRightStrokes(root); } } private void calculateLeftAndRightStrokes(HHTNode node) { List<HHTNode> children = node.getChildren(); List<Stroke> leftStrokes = node.getLeftStrokes(); List<Stroke> rightStrokes = node.getRightStrokes(); for(int i = 0; i<children.size();i++){ HHTNode child = children.get(i); // Add the stroke of its own to the list child.getLeftStrokes().add(child.getLeftStroke()); child.getRightStrokes().add(child.getRightStroke()); // If its the first child, add the parents left stroke if(i == 0) { child.getLeftStrokes().addAll(leftStrokes); // If its the only child, also add the right stroke if(children.size() == 1) { child.getRightStrokes().addAll(rightStrokes); } } // If its the last child, add the right stroke else if (i == children.size()-1) { child.getRightStrokes().addAll(rightStrokes); } if(!child.isLeaf()) { calculateLeftAndRightStrokes(child); } } } private void calculateLeftAndRightStroke(List<HHTNode> nodes) { for (int i = 0; i < nodes.size(); i++) { HHTNode child = nodes.get(i); String id = child.gettNode().getId(); int depth = child.getDepth(); // If its the first child if (i == 0) { Stroke nodeOuterStroke = new Stroke(StrokeStyle.outer, id, depth); child.setLeftStroke(nodeOuterStroke); // If its the only child if (nodes.size() == 1) { child.setRightStroke(nodeOuterStroke); } else { Stroke nodeNoneStroke = new Stroke(StrokeStyle.none, id, depth); child.setRightStroke(nodeNoneStroke); } } else { Stroke nodeInnerStroke = new Stroke(StrokeStyle.inner, id, depth); child.setLeftStroke(nodeInnerStroke); // If its the last child in the list if (i == nodes.size() - 1) { Stroke nodeOuterStroke = new Stroke(StrokeStyle.outer, id, depth); child.setRightStroke(nodeOuterStroke); } else { Stroke nodeNoneStroke = new Stroke(StrokeStyle.none, id, depth); child.setRightStroke(nodeNoneStroke); } } if (!child.isLeaf()) { calculateLeftAndRightStroke(child.getChildren()); } } } private void calculateDepth() { for (HHTNode root : rootNodes) { calculateDepth(root, 0); } } private void calculateDepth(HHTNode node, int depth) { node.setDepth(depth); // Keep account of the maximum depth in the HHTree if(depth > maxDepth) maxDepth = depth; if (!node.isLeaf()) { for (HHTNode child : node.getChildren()) { calculateDepth(child, depth + 1); } } } private void populateHHTreeFromRootTNodes(List<TNode> roots) { for (TNode root : roots) { HHTNode rootNode = new HHTNode(root); if (!isTNodeLeaf(root)) { populateChildren(root, rootNode); } rootNodes.add(rootNode); } } private void calculateStartColAndEndCol() { for (HHTNode root : rootNodes) { calculateStartColAndEndCol(root); } } private void calculateStartColAndEndCol(HHTNode node) { if (node.isLeaf()) { node.setStartCol(colIndex); node.setEndCol(colIndex++); } else { List<HHTNode> children = node.getChildren(); for (int i = 0; i < children.size(); i++) { HHTNode child = children.get(i); calculateStartColAndEndCol(child); } node.setStartCol(children.get(0).getStartCol()); node.setEndCol(children.get(children.size() - 1).getEndCol()); } } // private void printHHTree() { // for (HHTNode root : rootNodes) { // root.prettyprint(""); // } // } private void populateChildren(TNode node, HHTNode rootNode) { List<TNode> children = node.getChildren(); List<HHTNode> childrenList = new ArrayList<HHTNode>(); for (TNode child : children) { HHTNode childNode = new HHTNode(child); childrenList.add(childNode); if (!isTNodeLeaf(child)) populateChildren(child, childNode); } rootNode.setChildren(childrenList); } private boolean isTNodeLeaf(TNode node) { if (node.getChildren() == null || node.getChildren().size() == 0) return true; else return false; } public int getMaxDepth() { return maxDepth; } public List<HHTNode> getRootNodes() { return rootNodes; } public void computeHTMLColSpanUsingColCoordinates(ColumnCoordinateSet ccMap, ColspanMap cspanmap) { for(HHTNode root:rootNodes) { computeHTMLColSpan(root, ccMap, cspanmap); } } private void computeHTMLColSpan(HHTNode node, ColumnCoordinateSet ccMap, ColspanMap cspanmap) { int startIndex = cspanmap.getSpan(node).getStartIndex(); int endIndex = cspanmap.getSpan(node).getEndIndex(); int numHtmlColsBetween = ccMap.getNumberOfCoordinatesBetweenTwoIndexes(startIndex, endIndex, node.getDepth()); node.setHtmlColSpan(numHtmlColsBetween); if(!node.isLeaf()) { for(HHTNode child:node.getChildren()) { computeHTMLColSpan(child, ccMap, cspanmap); } } } public void computeHTMLColSpanUsingLeafColumnIndices(ColumnCoordinateSet ccMap, LeafColumnIndexMap indexMap) { for(HHTNode root:rootNodes) { computeHTMLColSpanUsingLeafColumnIndices(root, ccMap, indexMap); } } private int computeHTMLColSpanUsingLeafColumnIndices(HHTNode node, ColumnCoordinateSet ccMap, LeafColumnIndexMap indexMap) { if(node.isLeaf()) { TNode tNode = node.gettNode(); if(tNode instanceof AlignmentNode) { AlignmentNode aNode = (AlignmentNode) tNode; String hNodeId = aNode.getSemanticTypeHNodeId(); int colIndex = indexMap.getColumnIndex(hNodeId); int htmlColSpan = ccMap.getCoordinatesCountForIndex(colIndex); node.setHtmlColSpan(htmlColSpan); return htmlColSpan; } else return 0; } else { int htmlColSpan = 0; List<HHTNode> children = node.getChildren(); for(HHTNode child:children) { int c = computeHTMLColSpanUsingLeafColumnIndices(child, ccMap, indexMap); htmlColSpan += c; } node.setHtmlColSpan(htmlColSpan); return htmlColSpan; } } }