/******************************************************************************* * 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; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author szekely * */ public class Table extends RepEntity { @SuppressWarnings("unused") private static Logger logger = LoggerFactory.getLogger(Table.class); // The worksheet where I am defined. private final String worksheetId; // the HTable that defines my properties private final String hTableId; // My rows. private final ArrayList<Row> rows = new ArrayList<Row>(); // mariam /** * The node that this table is a nested table in. */ private Node nestedTableInNode; Table(String myWorksheetId, String id, String hTableId) { super(id); this.worksheetId = myWorksheetId; this.hTableId = hTableId; } // mariam public void setNestedTableInNode(Node n) { nestedTableInNode = n; } public Node getNestedTableInNode() { return nestedTableInNode; } public String getHTableId() { return hTableId; } public String getWorksheetId() { return worksheetId; } public Row addRow(RepFactory factory) { Row r = factory.createRow(hTableId, worksheetId); rows.add(r); // mariam r.setBelongsToTable(this); return r; } public int getNumRows() { return rows.size(); } /** * We need to add a new Node to each row in this table to provide a place * holder to store it's values. * * @param newHNode * added, assume to be part of this table. * @param factory */ void addNodeToDataTable(HNode newHNode, RepFactory factory) { for (Row r : rows) { r.addNodeToDataTable(newHNode, this, factory); } } //mariam public void removeNodeFromDataTable(String hNodeId) { for (Row r : rows) { r.removeNode(hNodeId); } } /** * The HNode acquired a nested HTable, so we need to add placeholders on all * rows for it. * * @param hNode * @param factory */ public void addNestedTableToDataTable(HNode hNode, RepFactory factory) { for (Row r : rows) { r.addNestedTableToDataTable(hNode, this, factory); } } /** * @param startIndex * , first row at index 0. * @param count * @return the requested number of rows or less if the count or startIndex * are out of bounds. */ public ArrayList<Row> getRows(int startIndex, int count) { ArrayList<Row> result = new ArrayList<Row>(); if (rows.size() > 0) { for (int i = Math.min(startIndex, rows.size() - 1); i < Math.min( startIndex + count, rows.size()); i++) { result.add(rows.get(i)); } } return result; } @Override public void prettyPrint(String prefix, PrintWriter pw, RepFactory factory) { pw.print(prefix); pw.print("Table/" + id + "/" + hTableId + ": "); pw.println(factory.getHTable(hTableId).getTableName()); for (Row r : rows) { r.prettyPrint(prefix, pw, factory); } } /** * Populates the nodes Collection (present in the argument) with nodes from * the table that satisfy the given path. * * @param path * Path to a given column * @param nodes * Collection of nodes that satisfy the path */ public void collectNodes(HNodePath path, Collection<Node> nodes) { if (nodes == null) nodes = new ArrayList<Node>(); collectNodes(path, nodes, rows); } private void collectNodes(HNodePath path, Collection<Node> nodes, List<Row> rows) { RowIterator: for (Row r : rows) { Collection<Node> nodesInRow = r.getNodes(); for (Node n : nodesInRow) { if (n.getHNodeId().equals(path.getFirst().getId())) { // Check if the path has only one HNode if (path.getRest() == null || path.getRest().isEmpty()) { nodes.add(n); continue RowIterator; } // Check if the node has a nested table if (n.hasNestedTable()) { int numRows = n.getNestedTable().getNumRows(); if (numRows == 0) continue RowIterator; List<Row> rowsNestedTable = n.getNestedTable().getRows( 0, numRows); if (rowsNestedTable != null && rowsNestedTable.size() != 0) collectNodes(path.getRest(), nodes, rowsNestedTable); } } } } } /** * * * @param value * an orphan value is a value that was the value of a node, but * the node acquired a nested table, so the value now needs to be * reocred in the nested table (this table). */ public void addOrphanValue(CellValue value, RepFactory factory) { HTable hTable = factory.getHTable(hTableId); HNode hNode = hTable.addAutomaticallyGeneratedColumn( HTable.ORPHAN_COLUMN_NAME, factory.getWorksheet(worksheetId), factory); // If the nested table is empty we need to add a row where we can store // the value. if (rows.isEmpty()) { addRow(factory); } setValueInAllRows(hNode.getId(), value, factory); } public void setValueInAllRows(String hNodeId, CellValue value, RepFactory factory) { // logger.info("Setting value of column " + factory.getColumnName(hNodeId) + " to " // + value.asString()); for (Row r : rows) { // logger.info("Setting value of column " + factory.getColumnName(hNodeId) + " in row " // + r.getId() + " to " + value.asString()); r.setValue(hNodeId, value, Node.NodeStatus.original, factory); } } }