edu.isi.karma.view.VWorksheet.java Source code

Java tutorial

Introduction

Here is the source code for edu.isi.karma.view.VWorksheet.java

Source

/*******************************************************************************
 * 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.view;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import edu.isi.karma.controller.update.WorksheetListUpdate;
import edu.isi.karma.rep.HNode;
import edu.isi.karma.rep.HNodePath;
import edu.isi.karma.rep.HTable;
import edu.isi.karma.rep.Table;
import edu.isi.karma.rep.TablePager;
import edu.isi.karma.rep.Worksheet;
import edu.isi.karma.util.JSONUtil;
import edu.isi.karma.view.ViewPreferences.ViewPreference;

public class VWorksheet extends ViewEntity {

    private final Worksheet worksheet;

    /**
     * Marks whether the data in the view is consistent with the data in the
     * memory representation. When false, it means that the view should be
     * refreshed, and an indication should be shown to the user to indicate that
     * an explicit refresh is needed.
     */
    private boolean upToDate = true;

    /**
     * When true, the view should show the worksheet collapsed so that the
     * headers are visible but the data is hidden.
     */
    private boolean collapsed = false;

    /**
     * The column headers shown in this view. The hidden columns do not appear
     * in this list. A roundtrip to the server is required to make hidden
     * columns appear.
     */

    //private final List<HNodePath> columns;

    private ArrayList<VHNode> headerViewNodes;

    /**
     * The maximum number of rows to show in the nested tables.
     */
    private int maxRowsToShowInNestedTables;

    /**
     * We create a TablePager for the top level table and every nested table we
     * see. It records how the table is scrolled.
     */
    private Map<String, TablePager> tableId2TablePager = new HashMap<>();

    private static Logger logger = LoggerFactory.getLogger(VWorksheet.class);

    VWorksheet(String id, Worksheet worksheet, List<HNodePath> columns, VWorkspace vWorkspace) {
        super(id);
        this.worksheet = worksheet;
        //this.columns = columns;
        this.maxRowsToShowInNestedTables = vWorkspace.getPreferences()
                .getIntViewPreferenceValue(ViewPreference.maxRowsToShowInNestedTables);

        // Force creation of the TablePager for the top table.
        getTablePager(worksheet.getDataTable(),
                vWorkspace.getPreferences().getIntViewPreferenceValue(ViewPreference.defaultRowsToShowInTopTables));

        this.headerViewNodes = initHeaderViewNodes(worksheet.getHeaders());
    }

    private ArrayList<VHNode> initHeaderViewNodes(HTable table) {
        ArrayList<VHNode> vNodes = new ArrayList<>();
        for (String hNodeId : table.getOrderedNodeIds()) {
            HNode node = table.getHNode(hNodeId);
            VHNode vNode = new VHNode(node.getId(), node.getColumnName());
            if (node.hasNestedTable()) {
                HTable nestedTable = node.getNestedTable();
                ArrayList<VHNode> nestedNodes = initHeaderViewNodes(nestedTable);
                for (VHNode nestedVNode : nestedNodes) {
                    vNode.addNestedNode(nestedVNode);
                }
            }
            vNodes.add(vNode);
        }
        return vNodes;
    }

    private TablePager getTablePager(Table table, int size) {
        TablePager tp = tableId2TablePager.get(table.getId());
        if (tp != null) {
            return tp;
        } else {
            tp = new TablePager(table, size);
            tableId2TablePager.put(table.getId(), tp);
            return tp;
        }
    }

    public TablePager getTopTablePager() {
        return tableId2TablePager.get(worksheet.getDataTable().getId());
    }

    public TablePager getNestedTablePager(Table table) {
        return getTablePager(table, maxRowsToShowInNestedTables);
    }

    public TablePager getTablePager(String tableId) {
        return tableId2TablePager.get(tableId);
    }

    public Map<String, TablePager> getTableId2TablePager() {
        return tableId2TablePager;
    }

    public void setTableId2TablePager(Map<String, TablePager> tableId2TablePager) {
        this.tableId2TablePager = tableId2TablePager;
    }

    public String getWorksheetId() {
        return worksheet.getId();
    }

    public Worksheet getWorksheet() {
        return worksheet;
    }

    public boolean isUpToDate() {
        return upToDate;
    }

    public void setUpToDate(boolean upToDate) {
        this.upToDate = upToDate;
    }

    public boolean isCollapsed() {
        return collapsed;
    }

    public void setCollapsed(boolean collapsed) {
        this.collapsed = collapsed;
    }

    public int getMaxRowsToShowInNestedTables() {
        return maxRowsToShowInNestedTables;
    }

    public void setMaxRowsToShowInNestedTables(int maxRowsToShowInNestedTables) {
        this.maxRowsToShowInNestedTables = maxRowsToShowInNestedTables;
    }

    public ArrayList<VHNode> getHeaderViewNodes() {
        return this.headerViewNodes;
    }

    public JSONArray getHeaderViewNodesJSON() {
        JSONArray newColumns = new JSONArray();
        for (VHNode node : this.headerViewNodes) {
            newColumns.put(getJSONRep(node));
        }
        return newColumns;
    }

    private JSONObject getJSONRep(VHNode node) {
        JSONObject obj = new JSONObject();
        obj.put("id", node.getId());
        obj.put("name", node.getColumnName());
        obj.put("visible", node.isVisible());
        if (node.hasNestedTable()) {
            JSONArray children = new JSONArray();
            for (VHNode childNode : node.getNestedNodes()) {
                children.put(getJSONRep(childNode));
            }
            obj.put("children", children);
        }
        return obj;
    }

    public ArrayList<String> getHeaderVisibleNodes() {
        return getVisibleViewNodes(this.headerViewNodes);
    }

    private ArrayList<String> getVisibleViewNodes(ArrayList<VHNode> list) {
        ArrayList<String> visibleNodeIds = new ArrayList<>();
        for (VHNode node : list) {
            if (node.isVisible()) {
                visibleNodeIds.add(node.getId());
                visibleNodeIds.addAll(getVisibleViewNodes(node.getNestedNodes()));
            }
        }
        return visibleNodeIds;
    }

    public ArrayList<String> getHeaderVisibleLeafNodes() {
        return getHeaderVisibleLeafNodes(this.headerViewNodes);
    }

    private ArrayList<String> getHeaderVisibleLeafNodes(ArrayList<VHNode> list) {
        ArrayList<String> visibleNodeIds = new ArrayList<>();
        for (VHNode node : list) {
            if (node.isVisible()) {
                if (node.hasNestedTable()) {
                    visibleNodeIds.addAll(getHeaderVisibleLeafNodes(node.getNestedNodes()));
                } else {
                    visibleNodeIds.add(node.getId());
                }
            }
        }
        return visibleNodeIds;
    }

    //   public ArrayList<VHNode> getHeaderViewNodes(String id) {
    //      if(id.equals(worksheet.getHeaders().getId()))
    //         return this.headerViewNodes;
    //      
    //      return getChildHeaderNodes(this.headerViewNodes, id);
    //   }
    //   
    //   private ArrayList<VHNode> getChildHeaderNodes(ArrayList<VHNode> vNodes, String id) {
    //      ArrayList<VHNode> children = null;
    //      for(VHNode node : vNodes) {
    //         if(node.getId().equals(id)) {
    //            children = node.getNestedNodes();
    //            break;
    //         }
    //         
    //         if(node.hasNestedTable()) {
    //            ArrayList<VHNode> matchingChild = getChildHeaderNodes(node.getNestedNodes(), id);
    //            if(matchingChild != null) {
    //               children = matchingChild;
    //               break;
    //            }
    //         }
    //      }
    //      return children;
    //   }
    //   
    public boolean isHeaderNodeVisible(String hnodeId) {
        return getHeaderVisibleNodes().contains(hnodeId);
    }

    private ArrayList<VHNode> generateOrganizedColumns(JSONArray columns) {
        ArrayList<VHNode> vNodes = new ArrayList<>();

        for (int i = 0; i < columns.length(); i++) {
            JSONObject column = columns.getJSONObject(i);

            if (column.has("id") && column.get("id") instanceof String) {
                try {
                    VHNode vNode = new VHNode(column.getString("id"), column.get("name").toString());
                    vNode.setVisible(column.getBoolean("visible"));
                    if (column.has("children")) {
                        ArrayList<VHNode> nestedNodes = generateOrganizedColumns(column.getJSONArray("children"));
                        for (VHNode nestedVNode : nestedNodes) {
                            vNode.addNestedNode(nestedVNode);
                        }
                    }
                    vNodes.add(vNode);
                } catch (Exception e) {
                    logger.error("Error organizing column:" + column.toString(), e);
                }
            }
        }

        return vNodes;
    }

    public void organizeColumns(JSONArray columns) {
        this.headerViewNodes = generateOrganizedColumns(columns);
    }

    public void organizeColumns(ArrayList<VHNode> columns) {
        this.headerViewNodes.clear();
        this.headerViewNodes.addAll(columns);
    }

    public void updateHeaderViewNodes(ArrayList<VHNode> oldOrderedNodes) {

        ArrayList<String> oldPaths = new ArrayList<>();
        for (VHNode node : oldOrderedNodes)
            oldPaths.addAll(node.getAllPaths());

        ArrayList<String> newPaths = new ArrayList<>();
        for (VHNode node : this.headerViewNodes)
            newPaths.addAll(node.getAllPaths());

        //1/. Get all paths in old that are not in new
        ArrayList<String> pathsToDel = new ArrayList<>();
        for (String oldPath : oldPaths) {
            if (!newPaths.contains(oldPath)) {
                pathsToDel.add(oldPath);
            }
        }

        //2. Get all paths in new that are not in old
        ArrayList<String> pathsToAdd = new ArrayList<>();
        for (int i = 0; i < newPaths.size(); i++) {
            String newPath = newPaths.get(i);
            if (!oldPaths.contains(newPath)) {
                if (i != 0) {
                    String after = newPaths.get(i - 1);
                    int difference = StringUtils.countMatches(after, "/") - StringUtils.countMatches(newPath, "/");
                    for (int k = 0; k < difference; k++) {
                        after = after.substring(0, after.lastIndexOf("/"));
                    }
                    pathsToAdd.add(newPath + "$$" + after);
                } else {
                    pathsToAdd.add(newPath + "$$" + "null");
                }
            }
        }

        ArrayList<VHNode> allNodes = new ArrayList<>();
        allNodes.addAll(oldOrderedNodes);
        this.headerViewNodes = allNodes;

        for (String path : pathsToDel) {
            deleteHeaderViewPath(this.headerViewNodes, path);
        }

        for (String path : pathsToAdd) {
            addHeaderViewPath(path);
        }
    }

    private void addHeaderViewPath(String path) {
        int after = path.indexOf("$$");
        String afterPath = path.substring(after + 2);
        path = path.substring(0, after);

        ArrayList<VHNode> parentList = this.headerViewNodes;
        int idx;

        String pathStart = path;

        if ((idx = pathStart.lastIndexOf("/")) != -1) {
            String parentSig = path.substring(0, idx);
            pathStart = path.substring(idx + 1);

            VHNode parentNode = VHNode.getVHNodeFromPath(parentSig, this.headerViewNodes);
            parentList = parentNode.getNestedNodes();
        }

        idx = pathStart.indexOf(":");
        String id = pathStart.substring(0, idx);
        String name = pathStart.substring(idx + 1);
        VHNode newNode = new VHNode(id, name);

        int insertIdx = -1;
        idx = afterPath.lastIndexOf("/");
        if (idx != -1)
            afterPath = afterPath.substring(idx + 1);
        for (int i = 0; i < parentList.size(); i++) {
            VHNode node = parentList.get(i);
            if (node.getNodePathSignature().equals(afterPath)) {
                insertIdx = i;
                break;
            }
        }
        parentList.add(insertIdx + 1, newNode);
    }

    private void deleteHeaderViewPath(ArrayList<VHNode> nodes, String path) {
        int idx = path.indexOf("/");
        String pathStart = path, pathEnd = null;
        if (idx != -1) {
            pathStart = path.substring(0, idx);
            pathEnd = path.substring(idx + 1);
        }

        for (VHNode node : nodes) {
            if (node.getNodePathSignature().equals(pathStart)) {
                if (pathEnd == null) {
                    nodes.remove(node);
                } else {
                    deleteHeaderViewPath(node.getNestedNodes(), pathEnd);
                }
                break;
            }

        }
    }

    public void generateWorksheetListJson(String prefix, PrintWriter pw) {
        pw.println(prefix + "{");
        String newPref = prefix + "  ";

        pw.println(newPref + JSONUtil.json(WorksheetListUpdate.JsonKeys.worksheetId, this.getWorksheetId()));
        pw.println(newPref + JSONUtil.json(WorksheetListUpdate.JsonKeys.isUpToDate, upToDate));
        pw.println(newPref + JSONUtil.json(WorksheetListUpdate.JsonKeys.isCollapsed, collapsed));

        pw.println(newPref + JSONUtil.json(WorksheetListUpdate.JsonKeys.encoding, worksheet.getEncoding()));
        pw.println(newPref + JSONUtil.jsonLast(WorksheetListUpdate.JsonKeys.title, worksheet.getTitle()));

        pw.println(prefix + "}");
    }
}