Package jsynoptic.data

Source Code of jsynoptic.data.ExpressionDataSourceProvider$ConflictListCellRenderer

/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info:  http://jsynoptic.sourceforge.net/index.html
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2003, by :
*     Corporate:
*         Astrium SAS
*         EADS CRC
*     Individual:
*         Nicolas Brodu
*
* $Id: ExpressionDataSourceProvider.java,v 1.6 2007/09/04 13:57:19 ogor Exp $
*
* Changes
* -------
* 27-Jan-2004 : Creation date (NB);
*
*/
package jsynoptic.data;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Iterator;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.Vector;

import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;

import jsynoptic.parser.ExpressionNode;
import jsynoptic.parser.ExpressionParser;
import jsynoptic.parser.ParseException;
import jsynoptic.ui.JSynoptic;
import jsynoptic.ui.Run;
import simtools.data.DataInfo;
import simtools.data.DataSource;
import simtools.data.DataSourceCollection;
import simtools.data.DataSourcePool;
import simtools.data.DataSourceProvider;
import simtools.data.DuplicateIdException;
import simtools.ui.ResourceFinder;
import simtools.ui.SourceTree;

/**
* Used in serializing/deserializing expression data sources
*/
public class ExpressionDataSourceProvider implements DataSourceProvider {
    public static ResourceBundle resources = ResourceFinder.get(ExpressionDataSourceProvider.class);

    private boolean conflictsOK = false; // need to be put as a field

    /*
     * (non-Javadoc)
     *
     * @see simtools.data.DataSourceProvider#getOptionalInformation(simtools.data.DataSource,
     *      simtools.data.DataSourceCollection)
     */
    public Object getOptionalInformation(DataSource ds, DataSourceCollection dsc) {
        // Only care for expression sources
        if (!(ds instanceof ExpressionDataSource)) {
            return null;
        }
        ExpressionDataSource eds = (ExpressionDataSource) ds;
        Vector info = new Vector();
        info.add(DataInfo.getLabel(ds)); // Name already included in the id
        info.add(DataInfo.getComment(ds)); // Expression
        Set variables = eds.getVariables();
        info.add(new Integer(variables.size()));
        for (Iterator it = eds.getVariables().iterator(); it.hasNext();) {
            VariableAssociation va = (VariableAssociation) it.next();
            // Store source Id => can find it back at reload thanks to
            // dependencies mecanism
            // And also this takes in account possible Id translation done by
            // the source pool
            info.add(DataInfo.getId(va.ds));
            // Store the name or alias for this source
            info.add(va.var);
        }
        return info;
    }

    /*
     * (non-Javadoc)
     *
     * @see simtools.data.DataSourceProvider#provide(java.lang.String,
     *      java.lang.String, java.lang.Object, simtools.data.DataSourcePool)
     */
    public DataSource provide(String id, String dscId, Object optionalInformation, DataSourcePool pool) {
        // First make sure this provider minds its own business
        if (id == null) {
            return null;
        }
        if (!id.startsWith(ExpressionDataSource.EXPRESSION_DATA_SOURCE_MARKER)) {
            return null;
        }
        // Now use the options
        if (optionalInformation == null) {
            return null; // this class didn't serialize that!
        }
        if (!(optionalInformation instanceof Vector)) {
            return null; // this class didn't serialize that!
        }
        Vector info = (Vector) optionalInformation;
        String name = (String) info.get(0);
        String expression = (String) info.get(1);
        int numvar = ((Integer) info.get(2)).intValue();
        final ConflictListModel clm = new ConflictListModel();
        // Thanks to the source dependencies mecanism, these ids should exist in
        // the pool
        // if pool is null don't know what to do => will try to parse the
        // expression nonetheless
        if (pool != null) {
            for (int i = 0; i < numvar; ++i) {
                DataSource ds;
                try {
                    ds = pool.getDataSourceWithId((String) info.get(i * 2 + 3));
                } catch (DuplicateIdException e) {
                    ds = null;
                }
                // and if the source does not exist, the conflict resolvng
                // mecanism will take care of that too
                String var = (String) info.get(i * 2 + 4);
                // source and var may mismatch => build a list of potential
                // conflicts to resolve after this loop
                clm.addElement(new VariableConflict(ds, var));
            }
        }
        // If there are conflicts, solve them...
        if (!clm.resolved()) {
            if (JSynoptic.gui != null) {
                conflictsOK = false;
                final JList list = new JList(clm);
                list.setCellRenderer(new ConflictListCellRenderer());
                JButton changeSourceAlias;
                JPanel treePane = new JPanel(new BorderLayout());
                final SourceTree st = SourceTree.getFromPool("PropertiesPanel0");
                treePane.add(new JScrollPane(st), BorderLayout.CENTER);
                JPanel bpanel = new JPanel(new GridLayout(1, 1));
                bpanel.add(changeSourceAlias = new JButton(resources.getString("changeSourceAlias")));
                treePane.add(bpanel, BorderLayout.SOUTH);
                JSplitPane pane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JScrollPane(list), treePane);
                list.setVisibleRowCount(10);
                JPanel bbox = new JPanel(new FlowLayout());
                final JButton bok;
                bbox.add(bok = new JButton("OK"));
                // bbox.add(bcancel = new JButton("Cancel"));
                final JDialog dialog = new JDialog(JSynoptic.gui.getOwner(), resources
                        .getString("conflictResolutionDialog"), true);
                dialog.getContentPane().add(pane, BorderLayout.CENTER);
                dialog.getContentPane().add(bbox, BorderLayout.SOUTH);
                bok.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        conflictsOK = true;
                        dialog.setVisible(false);
                    }
                });
                /*
                 * bcancel.addActionListener(new ActionListener() { public void
                 * actionPerformed(ActionEvent e) { conflictsOK = false;
                 * dialog.hide(); } });
                 */
                changeSourceAlias.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        Object o = st.getSelectedSourceOrCollection();
                        if (!(o instanceof DataSource)) {
                            return;
                        }
                        VariableConflict vc = (VariableConflict) list.getSelectedValue();
                        ((DataSource) o).getInformation().alias = vc.var;
                        list.repaint();
                        if (clm.resolved()) {
                            bok.setEnabled(true);
                        }
                        TreeNode tn = (TreeNode) (st.getSelectionPath().getLastPathComponent());
                        ((DefaultTreeModel) (st.getModel())).nodeChanged(tn);
                    }
                });
                st.addTreeSelectionListener(new TreeSelectionListener() {
                    public void valueChanged(TreeSelectionEvent e) {
                        Object o = st.getSelectedSourceOrCollection();
                        if ((o instanceof DataSource) && e.isAddedPath()) {
                            VariableConflict vc = (VariableConflict) list.getSelectedValue();
                            vc.ds = (DataSource) o;
                            list.repaint();
                            if (clm.resolved()) {
                                bok.setEnabled(true);
                            }
                            TreeNode tn = (TreeNode) (st.getSelectionPath().getLastPathComponent());
                            ((DefaultTreeModel) (st.getModel())).nodeChanged(tn);
                        }
                    }
                });
                list.addListSelectionListener(new ListSelectionListener() {
                    public void valueChanged(ListSelectionEvent e) {
                        Object sel = list.getSelectedValue();
                        if (sel == null) {
                            return;
                        }
                        st.setSelectedValue(((VariableConflict) sel).ds); // call
                        // the
                        // tree
                        // selection
                        // listener
                        // in
                        // turn
                    }
                });
                list.setSelectedIndex(0);
                bok.setEnabled(false);
                dialog.pack();
                dialog.setVisible(true);
                if (!conflictsOK) {
                    return null; // cancel => do not create the source
                }
            }
        }
        ExpressionNode node = null;
        try {
            ExpressionParser ep = new ExpressionParser(expression);
            // Add the data sources as variables, once conflicts are resolved
            for (int i = 0; i < clm.size(); ++i) {
                VariableConflict vc = (VariableConflict) clm.get(i);
                ep.addVariable(new VariableAssociation(vc.ds, vc.var));
            }
            // Add known plugins => may bring in more mathematical functions
            for (Iterator it = Run.plugins.iterator(); it.hasNext();) {
                ep.addClass(it.next().getClass());
            }
            node = ep.parse();
        } catch (ParseException pe) {
            // Also catches duplicate variable names
            JOptionPane.showMessageDialog(JSynoptic.gui.getOwner(), pe.getLocalizedMessage(), resources
                    .getString("CantRestoreExpression")
                    + expression, JOptionPane.ERROR_MESSAGE);
            return null;
        } catch (Error err) {
            JOptionPane.showMessageDialog(JSynoptic.gui.getOwner(), err.getLocalizedMessage(), resources
                    .getString("CantRestoreExpression")
                    + expression, JOptionPane.ERROR_MESSAGE);
            return null;
        }
        // Finally provide the source
        ExpressionDataSource eds = new ExpressionDataSource(new DataInfo(name, name, expression), node);
        if (pool != null) {
            pool.addDataSource(eds);
        }
        return eds;
    }

    protected static class VariableConflict {
        public DataSource ds;

        public String var;

        public VariableConflict(DataSource ds, String var) {
            this.ds = ds;
            this.var = var;
        }

        public String toString() {
            String ret = var;
            for (int i = var.length(); i < 20; ++i) {
                ret += " ";
            }
            return ret;
        }

        public boolean resolved() {
            String alias = DataInfo.getAlias(ds);
            if ((alias == null) && var.equals(DataInfo.getLabel(ds))) {
                return true;
            }
            if (var.equals(alias)) {
                return true;
            }
            if (ds != null) {
                ds.getInformation().alias = var;
                return true;
            }
            return false;
        }
    }

    protected static class ConflictListModel extends DefaultListModel {
        public boolean resolved() {
            boolean ret = true;
            // all conflicts must be resolved to return true
            for (int i = 0; i < size(); ++i) {
                ret &= ((VariableConflict) this.get(i)).resolved();
            }
            return ret;
        }
    }

    public static class ConflictListCellRenderer extends DefaultListCellRenderer {
        /*
         * (non-Javadoc)
         *
         * @see javax.swing.ListCellRenderer#getListCellRendererComponent(javax.swing.JList,
         *      java.lang.Object, int, boolean, boolean)
         */
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
                boolean cellHasFocus) {
            super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            boolean resolved = ((VariableConflict) list.getModel().getElementAt(index)).resolved();
            if (isSelected) {
                if (resolved) {
                    setBackground(new Color(0x88FF88));
                } else {
                    setBackground(new Color(0xFF8888));
                }
            } else {
                if (resolved) {
                    setBackground(Color.green);
                } else {
                    setBackground(Color.red);
                }
            }
            return this;
        }
    }
}
TOP

Related Classes of jsynoptic.data.ExpressionDataSourceProvider$ConflictListCellRenderer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.