org.geworkbench.engine.ccm.CCMTableModel.java Source code

Java tutorial

Introduction

Here is the source code for org.geworkbench.engine.ccm.CCMTableModel.java

Source

package org.geworkbench.engine.ccm;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.swing.JOptionPane;
import javax.swing.table.AbstractTableModel;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.geworkbench.engine.config.UILauncher;

/**
 * CCMTableModel
 * 
 */
class CCMTableModel extends AbstractTableModel {
    private static final long serialVersionUID = 3986726808587129205L;
    private static Log log = LogFactory.getLog(CCMTableModel.class);

    public static final boolean NO_VALIDATION = false;

    // TODO all these indices should be private. it takes more refactoring to do
    // it though.
    static final int SELECTION_INDEX = 0;
    static final int NAME_INDEX = 1;
    static final int AUTHOR_INDEX = 2;
    static final int VERSION_INDEX = 3;
    static final int TUTORIAL_URL_INDEX = 4;
    static final int TOOL_URL_INDEX = 5;

    // FIXME the following indices are really identifiers instead of index
    static final int CLASS_INDEX = 7;
    static final int DESCRIPTION_INDEX = 8;
    static final int LICENSE_INDEX = 11;
    static final int DOCUMENTATION_INDEX = 13;
    static final int CATEGORY_INDEX = 17;

    static final int HIDDEN_INDEX = 20;
    static final int LAST_VISIBLE_COLUMN = TOOL_URL_INDEX;

    static final int FIRST_STRING_COLUMN = NAME_INDEX;

    private String[] columnNames = { "On/Off", "Name", "Author", "Version", "Tutorial", "Tool URL" };
    Vector<PluginComponent> rows = new Vector<PluginComponent>();
    Map<PluginComponent, Boolean> selected = new HashMap<PluginComponent, Boolean>();

    private Map<PluginComponent, String> resourceFolders = new HashMap<PluginComponent, String>();
    private Map<PluginComponent, File> files = new HashMap<PluginComponent, File>();

    private ComponentConfigurationManager manager = null;

    private String loadedFilterValue = null;
    private String typeFilterValue = null;
    private String keywordFilterValue = null;

    /*
     * Constructor
     */
    public CCMTableModel(ComponentConfigurationManager manager) {
        super();

        this.manager = manager;
        PluginComponent.clearCategoryList();
        for (File file : manager.cwbFile)
            loadGuiModelFromFiles(file);
        Collections.sort(rows, new TableNameComparator());
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.swing.table.TableModel#getColumnCount()
     */
    public int getColumnCount() {
        return columnNames.length;
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.swing.table.TableModel#getRowCount()
     */
    public int getRowCount() {
        return getModelRowCount();
    }

    /**
     * 
     * @return
     */
    final public int getModelRowCount() {
        return rows.size();
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.swing.table.AbstractTableModel#getColumnName(int)
     */
    @Override
    public String getColumnName(int col) {
        return columnNames[col];
    }

    /**
     * (non-Javadoc)
     * 
     * @see javax.swing.table.AbstractTableModel#getColumnClass(int) Without
     *      this method, the check box column would default to a String
     */
    @Override
    public Class<?> getColumnClass(int column) {
        if (column == SELECTION_INDEX) {
            return Boolean.class;
        } else if (column == AUTHOR_INDEX) {
            return HyperLink.class;
        } else if (column == TUTORIAL_URL_INDEX || column == TOOL_URL_INDEX) {
            return ImageLink.class;
        } else {
            return String.class;
        }
    }

    static class HyperLink {
        public HyperLink(String author, String authorUrl) {
            text = author;
            url = authorUrl;
        }

        String text;
        String url;
    }

    // FIXME make tooltip is supported
    static class ImageLink {
        ImageLink(String strUrl) {
            if (strUrl == null || strUrl == "") {
                image = LinkIcon.GRAYED;
            } else {
                image = LinkIcon.COLORED;
            }
            url = strUrl;
        }

        LinkIcon image;
        String url;
    }

    enum LinkIcon {
        COLORED, GRAYED
    };

    /**
     * (non-Javadoc)
     * 
     * @see javax.swing.table.AbstractTableModel#isCellEditable(int, int)
     */
    @Override
    public boolean isCellEditable(int row, int column) {
        if (column == SELECTION_INDEX) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * (non-Javadoc)
     * 
     * @see javax.swing.table.TableModel#getValueAt(int, int)
     */
    public Object getValueAt(int row, int column) {
        return getModelValueAt(row, column);
    }

    final Object getModelValueAt(int row, int column) {
        PluginComponent record = rows.get(row);
        switch (column) {
        case SELECTION_INDEX:
            return (Boolean) selected.get(record);
        case NAME_INDEX:
            return (String) record.getName();
        case VERSION_INDEX:
            return (String) record.getVersion();
        case AUTHOR_INDEX:
            return new HyperLink(record.getAuthor(), record.getAuthorUrl());
        case TUTORIAL_URL_INDEX:
            return new ImageLink(record.getTutorialUrl());
        case TOOL_URL_INDEX:
            return new ImageLink(record.getToolUrl());
        case CLASS_INDEX:
            return (String) record.getClazz();
        case DESCRIPTION_INDEX:
            return (String) record.getDescription();
        case LICENSE_INDEX:
            return (String) record.getLicense();
        case DOCUMENTATION_INDEX:
            return (String) record.getDocumentation();
        case CATEGORY_INDEX:
            return (String[]) record.getCategory();
        case HIDDEN_INDEX:
            return (Boolean) record.isHidden();
        default:
            log.error("Invalid column index");
            return null;
        }
    }

    /**
     * set selected status to opposite for a given row
     * 
     * @param row
     * @return
     */
    void switchSelected(int row) {
        Boolean selected = (Boolean) getModelValueAt(row, CCMTableModel.SELECTION_INDEX);
        Boolean reset = new Boolean(!selected.booleanValue());
        selectRow(reset, row, CCMTableModel.NO_VALIDATION);
    }

    /**
     * select a given row without checking validation
     * 
     * @param row
     * @return
     */
    boolean selectWithoutValiation(int row, boolean selected) {
        return selectRow(new Boolean(selected), row, CCMTableModel.NO_VALIDATION);
    }

    /**
     * (non-Javadoc)
     * 
     * @see javax.swing.table.TableModel#getRowByClazz(String)
     */
    final public int getModelRowByClazz(String clazz) {

        for (int i = 0; i < rows.size(); i++) {
            PluginComponent record = rows.get(i);
            String rowClazz = record.getClazz();
            if (clazz.equalsIgnoreCase(rowClazz)) {
                return i;
            }
        }
        return -1;
    }

    /**
     * (non-Javadoc)
     * 
     * @see javax.swing.table.AbstractTableModel#setValueAt(java.lang.Object,
     *      int, int)
     */
    @Override
    public void setValueAt(Object value, int row, int column) {
        if (column == 0)
            selectRow(value, row, true);
    }

    String getResourceFolder(int rowNumber) {
        return resourceFolders.get(rows.get(rowNumber));
    }

    File getFile(int rowNumber) {
        return files.get(rows.get(rowNumber));
    }

    /**
     * (non-Javadoc)
     * 
     * @see javax.swing.table.AbstractTableModel#setValueAt(java.lang.Object,
     *      int, int, boolean)
     */
    final boolean selectRow(Object value, int modelRow, boolean validation) {
        PluginComponent record = rows.get(modelRow);

        selected.put(record, (Boolean) value);

        Boolean currentChoice = (Boolean) getModelValueAt(modelRow, CCMTableModel.SELECTION_INDEX);

        List<String> required = record.getRequired();
        List<String> related = record.getRelated();
        String folder = resourceFolders.get(record);
        File file = files.get(record);

        List<String> unselectedRequired = new ArrayList<String>();
        for (int i = 0; i < required.size(); i++) {
            String requiredClazz = required.get(i);
            Integer requiredRow = getModelRowByClazz(requiredClazz);
            Boolean requiredSelected = (Boolean) getModelValueAt(requiredRow.intValue(),
                    CCMTableModel.SELECTION_INDEX);
            if (!requiredSelected) {
                unselectedRequired.add(requiredClazz);
            }
        }

        if (currentChoice.booleanValue()) {
            /* PLUGIN SELECTED */
            String propFileName = null;
            String cwbFileName = file.getName();
            if (cwbFileName.endsWith(".cwb.xml")) {
                propFileName = cwbFileName.replace(".cwb.xml", ".ccmproperties");
            } else {
                log.error(".cwb.xml file is expected. Actual file name " + cwbFileName);
            }
            String licenseAccepted = ComponentConfigurationManager.readProperty(folder, propFileName,
                    "licenseAccepted");
            Boolean boolRequired = record.isMustAccept();
            boolean bRequired = boolRequired.booleanValue();
            if ((bRequired && (licenseAccepted == null))
                    || (bRequired && licenseAccepted != null && !licenseAccepted.equalsIgnoreCase("true"))) {
                String componentName = (String) getModelValueAt(modelRow, CCMTableModel.NAME_INDEX);

                String title = "Terms Acceptance";
                String message = "\nBy clicking \"I Accept\", you signify that you \nhave read and accept the terms of the license \nagreement for the \""
                        + componentName
                        + "\" application.\n\nTo view this license, exit out of this dialog and click \non the View License button below.\n\n";
                Object[] options = { "I Accept", "No, thanks" };
                int choice = JOptionPane.showOptionDialog(null, message, title, JOptionPane.YES_NO_OPTION,
                        JOptionPane.PLAIN_MESSAGE, null, options, options[0]);

                if (choice != 0) {
                    ComponentConfigurationManager.writeProperty(folder, propFileName, "licenseAccepted", "false");
                    selected.put(record, new Boolean(false));
                    return false;
                }
                ComponentConfigurationManager.writeProperty(folder, propFileName, "licenseAccepted", "true");
            }

            if (!validation) {
                fireTableDataChanged();
                return true;
            }

            if (unselectedRequired.size() > 0 || related.size() > 0) {
                DependencyManager dmanager = new DependencyManager(this, unselectedRequired, modelRow, related);
                dmanager.checkDependency();
            }
        } else {
            /* PLUGIN UNSELECTED */
            List<Integer> dependentPlugins = null;

            String unselectedPluginClazz = "Plugin is missing a Class descriptor";
            int unselectedRow = modelRow;
            if (unselectedRow >= 0) {
                unselectedPluginClazz = (String) getModelValueAt(unselectedRow, CCMTableModel.CLASS_INDEX);
            }

            dependentPlugins = new ArrayList<Integer>();
            /*
             * Find Plugins that are dependent on this unselected plugin.
             */
            int rowCount = getModelRowCount();
            for (int i = 0; i < rowCount; i++) {

                /*
                 * If the potentially dependent plugin is not selected,
                 * don't bother to see if it is dependent
                 */
                Boolean selected = (Boolean) getModelValueAt(i, CCMTableModel.SELECTION_INDEX);
                if (!selected.booleanValue()) {
                    continue;
                }

                List<String> requiredList = rows.get(i).getRequired();

                for (int j = 0; j < requiredList.size(); j++) {
                    String requiredClazz = requiredList.get(j);
                    if (unselectedPluginClazz.equalsIgnoreCase(requiredClazz)) {
                        dependentPlugins.add(new Integer(i));
                        break;
                    }
                }
            }

            if (!validation) {
                fireTableDataChanged();
                return true;
            }

            /* If dependencies are found, then popup a dialog */
            if (dependentPlugins.size() > 0) {
                DependencyManager dmanager = new DependencyManager(this, dependentPlugins, modelRow);
                dmanager.checkDependency();
            }
        }

        //      fireTableCellUpdated(modelRow, column);//FIXME no use

        return true;
    }

    private void loadGuiModelFromFiles(File file) {

        String comDir = UILauncher.getComponentsDirectory();
        String path = file.getAbsolutePath();
        int index = path.indexOf(comDir) + comDir.length() + 1;
        String folderName = path.substring(index, path.indexOf(System.getProperty("file.separator"), index));

        PluginComponent ccmComponent = manager.getPluginsFromFile(file);

        if (ccmComponent == null) {
            return;
        }

        String name = ccmComponent.getPluginName();
        if (name == null) {
            return;
        }

        String propFileName = null;
        String cwbFileName = file.getName();
        if (cwbFileName.endsWith(".cwb.xml")) {
            propFileName = cwbFileName.replace(".cwb.xml", ".ccmproperties");
        } else {
            log.error(".cwb.xml file is expected. File name " + cwbFileName);
            return;
        }

        String onOff = ComponentConfigurationManager.readProperty(folderName, propFileName, "on-off");

        if (onOff != null && onOff.equalsIgnoreCase("true")) {
            selected.put(ccmComponent, new Boolean(true));
        } else {
            selected.put(ccmComponent, new Boolean(false));
        }

        rows.add(ccmComponent);
        resourceFolders.put(ccmComponent, folderName);
        files.put(ccmComponent, file);
    }

    final public String getLoadedFilterValue() {
        return loadedFilterValue;
    }

    final public void setLoadedFilterValue(String loadedFilterValue) {
        this.loadedFilterValue = loadedFilterValue;
    }

    final public String getTypeFilterValue() {
        return typeFilterValue;
    }

    final public void setTypeFilterValue(String typeFilterValue) {
        this.typeFilterValue = typeFilterValue;
    }

    final public String getKeywordFilterValue() {
        return keywordFilterValue;
    }

    final public void setKeywordFilterValue(String keywordFilterValue) {
        this.keywordFilterValue = keywordFilterValue;
    }

    static private class TableNameComparator implements Comparator<PluginComponent> {
        public int compare(PluginComponent row1, PluginComponent row2) {
            String name1 = row1.getName().toLowerCase();
            String name2 = row2.getName().toLowerCase();
            return name1.compareTo(name2);
        }
    }

}