org.deegree.igeo.views.swing.style.RuleDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.deegree.igeo.views.swing.style.RuleDialog.java

Source

/*----------------    FILE HEADER  ------------------------------------------
 This file is part of deegree.
 Copyright (C) 2001-2007 by:
 Department of Geography, University of Bonn
 http://www.giub.uni-bonn.de/deegree/
 lat/lon GmbH
 http://www.lat-lon.de
    
 This library 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 library 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 library; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 Contact:
    
 Andreas Poth
 lat/lon GmbH
 Aennchenstr. 19
 53177 Bonn
 Germany
 E-Mail: poth@lat-lon.de
    
 Prof. Dr. Klaus Greve
 Department of Geography
 University of Bonn
 Meckenheimer Allee 166
 53115 Bonn
 Germany
 E-Mail: greve@giub.uni-bonn.de
 ---------------------------------------------------------------------------*/

package org.deegree.igeo.views.swing.style;

import static org.deegree.igeo.i18n.Messages.get;
import static org.deegree.igeo.views.DialogFactory.openErrorDialog;
import static org.deegree.igeo.views.swing.util.IconRegistry.getIcon;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.io.File;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;

import org.deegree.datatypes.QualifiedName;
import org.deegree.framework.log.ILogger;
import org.deegree.framework.log.LoggerFactory;
import org.deegree.framework.xml.XMLParsingException;
import org.deegree.graphics.sld.AbstractLayer;
import org.deegree.graphics.sld.AbstractStyle;
import org.deegree.graphics.sld.FeatureTypeStyle;
import org.deegree.graphics.sld.NamedLayer;
import org.deegree.graphics.sld.SLDFactory;
import org.deegree.graphics.sld.StyleFactory;
import org.deegree.graphics.sld.StyledLayerDescriptor;
import org.deegree.graphics.sld.UserStyle;
import org.deegree.igeo.ApplicationContainer;
import org.deegree.igeo.ChangeListener;
import org.deegree.igeo.commands.ChangeLayerStyleCommand;
import org.deegree.igeo.config.DirectStyleType;
import org.deegree.igeo.config.ViewFormType;
import org.deegree.igeo.i18n.Messages;
import org.deegree.igeo.mapmodel.DefinedStyle;
import org.deegree.igeo.mapmodel.DirectStyle;
import org.deegree.igeo.mapmodel.Layer;
import org.deegree.igeo.mapmodel.NamedStyle;
import org.deegree.igeo.settings.Settings;
import org.deegree.igeo.style.LayerCache;
import org.deegree.igeo.style.LayerCache.CachedLayer;
import org.deegree.igeo.style.perform.SldIO;
import org.deegree.igeo.views.DialogFactory;
import org.deegree.igeo.views.HelpManager;
import org.deegree.igeo.views.swing.DefaultFrame;
import org.deegree.igeo.views.swing.HelpFrame;
import org.deegree.igeo.views.swing.util.IconRegistry;
import org.deegree.igeo.views.swing.util.panels.PanelDialog;
import org.deegree.kernel.Command;
import org.deegree.model.filterencoding.ComplexFilter;
import org.deegree.model.filterencoding.Filter;
import org.deegree.model.filterencoding.Operation;
import org.deegree.model.filterencoding.PropertyIsCOMPOperation;
import org.deegree.model.filterencoding.PropertyName;

import com.jgoodies.forms.builder.ButtonBarBuilder;
import com.jgoodies.forms.builder.DefaultFormBuilder;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

/**
 * The <code>RuleDialog</code> handles the definition of rules.
 * 
 * @author <a href="mailto:buesching@lat-lon.de">Lyn Buesching</a>
 * @author last edited by: $Author$
 * 
 * @version $Revision$, $Date$
 * 
 */
public class RuleDialog extends DefaultFrame implements ActionListener {

    private static final long serialVersionUID = -4152608665359578717L;

    private static final ILogger LOG = LoggerFactory.getLogger(RuleDialog.class);

    private Layer layer;

    private ApplicationContainer<?> appContainer;

    private Settings settings;

    private List<RuleDefinitionPanel> ruleDefinitionPanels = new ArrayList<RuleDefinitionPanel>();

    private JTabbedPane rules;

    private JButton okBt;

    private JButton applyBt;

    private JButton cancelBt;

    private JButton helpBt;

    private JMenuBar menuBar;

    private JMenuItem addRuleItem;

    private JMenuItem removeRuleItem;

    private JMenuItem renameRuleItem;

    private JMenuItem duplicateRuleItem;

    private JMenuItem importStyleItem;

    private JMenuItem exportStyleItem;

    private JMenuItem settingsItem;

    private JMenuItem editSymbolItem;

    private SettingsPanel settingsPanel = new SettingsPanel();

    private List<ChangeListener> uomChangedListener = new ArrayList<ChangeListener>();

    private StyledLayerDescriptor importedSls = null;

    private boolean styleChanged = false;

    static {
        StyleDialogUtils.prepareFormConstants();
    }

    /**
     * default constructor
     */
    public RuleDialog() {
    }

    /**
     * Sets the layer and updates the RuleDefinitionPanels.
     * 
     * @param layer
     *            the layer
     */
    public void setLayer(Layer layer) {
        this.layer = layer;
        LayerCache.getInstance().addLayer(layer);
        AbstractStyle abstractStyle = layer.getCurrentStyle().getStyle();
        settingsPanel.setUom(getUom());
        setStyle(abstractStyle);
    }

    private void setStyle(AbstractStyle abstractStyle) {
        if (abstractStyle instanceof UserStyle) {
            FeatureTypeStyle[] featureStyles = ((UserStyle) abstractStyle).getFeatureTypeStyles();
            for (int i = 0; i < featureStyles.length; i++) {
                String name;
                if (featureStyles[i].getTitle() != null) {
                    name = featureStyles[i].getTitle();
                } else if (featureStyles[i].getName() != null) {
                    name = featureStyles[i].getName();
                } else {
                    name = get("$MD10591", ruleDefinitionPanels.size());
                }
                addRuleDefinitionPanel(name, featureStyles[i]);
            }
        }
        // no ruleDefinitionPanels defined, so create a default one
        if (ruleDefinitionPanels.size() == 0) {
            String name = get("$MD10591", 1);
            addRuleDefinitionPanel(name, null);
        }
    }

    /**
     * 
     * @param appContainer
     */
    public void setApplicationContainer(ApplicationContainer<?> appContainer) {
        this.appContainer = appContainer;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.deegree.igeo.views.IView#init(org.deegree.igeo.config.ViewFormType)
     */
    @Override
    public void init(ViewFormType viewForm) throws Exception {
        super.init(viewForm);
        settings = owner.getApplicationContainer().getSettings();
        initComponents();
        initRuleDialog();
    }

    /**
     * sets the ruleDialog in the initial state
     */
    public void reset() {
        ruleDefinitionPanels.clear();
        rules.removeAll();
    }

    private void initComponents() {

        // TODO: mnemonics(!-i18n?)/shortcuts(?)
        menuBar = new JMenuBar();
        JMenu menuRules = new JMenu(get("$MD11069"));

        addRuleItem = new JMenuItem(get("$MD10592"), getIcon("rule_add.png"));
        addRuleItem.addActionListener(this);
        removeRuleItem = new JMenuItem(get("$MD10593"), getIcon("rule_delete.png"));
        removeRuleItem.addActionListener(this);
        renameRuleItem = new JMenuItem(get("$MD10594"), getIcon("rule_edit.png"));
        renameRuleItem.addActionListener(this);
        duplicateRuleItem = new JMenuItem(get("$MD11605"), getIcon("rule_copy.png"));
        duplicateRuleItem.addActionListener(this);

        menuRules.add(addRuleItem);
        menuRules.add(removeRuleItem);
        menuRules.add(renameRuleItem);
        menuRules.add(duplicateRuleItem);

        JMenu menuStyles = new JMenu(get("$MD11070"));

        importStyleItem = new JMenuItem(get("$MD11067"), getIcon("sld_import.png"));
        importStyleItem.addActionListener(this);
        exportStyleItem = new JMenuItem(get("$MD11068"), getIcon("sld_export.png"));
        exportStyleItem.addActionListener(this);

        menuStyles.add(importStyleItem);
        menuStyles.add(exportStyleItem);

        JMenu menuSettings = new JMenu(get("$MD11615"));
        settingsItem = new JMenuItem(get("$MD11616"));
        settingsItem.addActionListener(this);
        menuSettings.add(settingsItem);

        JMenu menuEdit = new JMenu(get("$MD11833"));
        editSymbolItem = new JMenuItem(get("$MD11834"));
        editSymbolItem.addActionListener(this);
        menuEdit.add(editSymbolItem);

        menuBar.add(menuEdit);
        menuBar.add(menuRules);
        menuBar.add(menuStyles);
        menuBar.add(menuSettings);

        rules = new JTabbedPane();
        rules.setVisible(true);

        okBt = new JButton(get("$DI10001"), IconRegistry.getIcon("accept.png"));
        okBt.addActionListener(this);

        cancelBt = new JButton(get("$DI10002"), IconRegistry.getIcon("cancel.png"));
        cancelBt.addActionListener(this);

        helpBt = new JButton(get("$DI10016"), IconRegistry.getIcon("help.png"));
        helpBt.addActionListener(this);

        applyBt = new JButton(get("$DI10043"), IconRegistry.getIcon("eye.png"));
        applyBt.addActionListener(this);
    }

    private void initRuleDialog() {
        FormLayout fl = new FormLayout("left:default:grow(0.5), right:default:grow(0.5)",
                "top:default, $btheight:grow(1.0), $btheight:grow(1.0)");

        DefaultFormBuilder builder = new DefaultFormBuilder(fl);
        builder.setDefaultDialogBorder();

        CellConstraints cc = new CellConstraints();

        builder.add(rules, cc.xyw(1, 1, 2));
        builder.add(helpBt, cc.xy(1, 2));
        builder.add(applyBt, cc.xy(2, 2));
        builder.add(buildMainButtonBar(), cc.xywh(1, 3, 2, 1, CellConstraints.RIGHT, CellConstraints.BOTTOM));

        setJMenuBar(menuBar);
        getContentPane().add(builder.getPanel());
    }

    private JPanel buildMainButtonBar() {
        ButtonBarBuilder bbBuilder = new ButtonBarBuilder();
        bbBuilder.addRelatedGap();
        bbBuilder.addGlue();
        bbBuilder.addGriddedButtons(new JButton[] { okBt, cancelBt });
        return bbBuilder.getPanel();
    }

    private void closeDialog() {
        for (int i = 0; i < rules.getComponentCount(); i++) {
            if (rules.getComponent(i) instanceof RuleDefinitionPanel) {
                RuleDefinitionPanel ruleDefPanel = (RuleDefinitionPanel) rules.getComponent(i);
                ruleDefPanel.closeFrames();
            }
        }
        dispose();
    }

    private NamedStyle getMergedStyle() {
        DirectStyleType dst = new DirectStyleType();
        FeatureTypeStyle[] fts = new FeatureTypeStyle[ruleDefinitionPanels.size()];
        for (int i = 0; i < ruleDefinitionPanels.size(); i++) {
            fts[i] = ruleDefinitionPanels.get(i).getFeatureTypeStyle();
        }
        Filter filter = fts[0].getRules()[0].getFilter();
        String s = "";
        if (filter != null) {
            // find name of the property used for classification
            Operation op = ((ComplexFilter) filter).getOperation();
            if (op instanceof PropertyIsCOMPOperation) {
                PropertyName pn = (PropertyName) ((PropertyIsCOMPOperation) op).getFirstExpression();
                s = " (" + pn.getValue().getAsString() + ')';
            }
        }
        UserStyle us = (UserStyle) StyleFactory.createStyle("default1", layer.getTitle() + s, "default3", fts);
        dst.setName(us.getName());
        dst.setTitle(us.getTitle());
        dst.setAbstract(us.getAbstract());
        dst.setCurrent(true);
        dst.setUom(getUom().toString().toLowerCase());
        return new DirectStyle(dst, us, layer);
    }

    private RuleDefinitionPanel addRuleDefinitionPanel(String name, FeatureTypeStyle rules) {
        RuleDefinitionPanel newRuleDefPanel = new RuleDefinitionPanel(this, name, layer.getIdentifier(), settings,
                rules, appContainer);
        ruleDefinitionPanels.add(newRuleDefPanel);
        this.rules.addTab(name, newRuleDefPanel);
        this.rules.setSelectedComponent(newRuleDefPanel);
        return newRuleDefPanel;
    }

    private void removeAllRuleDefinitionPanels() {
        ruleDefinitionPanels.clear();
        rules.removeAll();
    }

    private void removeSelectedRuleDefinitionPanel() {
        ruleDefinitionPanels.remove(rules.getSelectedComponent());
        rules.remove(rules.getSelectedIndex());
    }

    // //////////////////////////////////////////////////////////////////////////////
    // ACTIONLISTENER
    // //////////////////////////////////////////////////////////////////////////////

    /*
     * (non-Javadoc)
     * 
     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
     */
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() instanceof JButton) {
            JButton srcBt = (JButton) e.getSource();
            if (srcBt == cancelBt) {
                closeDialog();
            } else if (srcBt == okBt) {
                applyStyle();
                closeDialog();
            } else if (srcBt == helpBt && appContainer != null) {
                HelpFrame hf = HelpFrame.getInstance(new HelpManager(appContainer));
                hf.setVisible(true);
                hf.gotoKeyword("rule:EditStyle");
            } else if (srcBt == applyBt) {
                applyStyle();
            }
        } else if (e.getSource() instanceof JMenuItem) {
            JMenuItem srcItem = (JMenuItem) e.getSource();
            if (srcItem == addRuleItem) {
                int noOfNewRules = rules.getComponentCount() + 1;
                String s = (String) JOptionPane.showInputDialog(this, get("$MD10595"), get("$MD10596"),
                        JOptionPane.PLAIN_MESSAGE, null, null, get("$MD10591", noOfNewRules));
                if (s != null) {
                    if (s.length() == 0) {
                        s = get("$MD10591", noOfNewRules);
                    }
                    addRuleDefinitionPanel(s, null);
                }

            } else if (srcItem == removeRuleItem) {
                if (rules.getSelectedIndex() > -1 && rules.getComponentCount() > 1) {
                    removeSelectedRuleDefinitionPanel();
                }
            } else if (srcItem == renameRuleItem) {
                int selectedIndex = rules.getSelectedIndex();
                if (rules.getSelectedComponent() instanceof RuleDefinitionPanel && selectedIndex > -1) {
                    String tabTitle = rules.getTitleAt(selectedIndex);
                    String s = (String) JOptionPane.showInputDialog(this, get("$MD10597"),
                            get("$MD10598", tabTitle), JOptionPane.PLAIN_MESSAGE, null, null, tabTitle);
                    if (s != null && s.length() > 0) {
                        rules.setTitleAt(selectedIndex, s);
                        RuleDefinitionPanel selectedPanel = (RuleDefinitionPanel) rules.getSelectedComponent();
                        selectedPanel.setRuleName(s);
                    }
                }
            } else if (srcItem == duplicateRuleItem) {

                int noOfNewRules = rules.getComponentCount() + 1;
                String s = (String) JOptionPane.showInputDialog(this, get("$MD10595"), get("$MD10596"),
                        JOptionPane.PLAIN_MESSAGE, null, null, get("$MD10591", noOfNewRules));
                if (s != null) {
                    if (s.length() == 0) {
                        s = get("$MD10591", noOfNewRules);
                    }
                    RuleDefinitionPanel selectedPanel = (RuleDefinitionPanel) this.rules.getSelectedComponent();
                    RuleDefinitionPanel newPanel = addRuleDefinitionPanel(s, selectedPanel.getFeatureTypeStyle());
                    newPanel.setSettings(selectedPanel.getSelectedFeatureTypeIndex(),
                            selectedPanel.getSelectedGeomPropertyIndex(), selectedPanel.getMinScale(),
                            selectedPanel.getMaxScale(), selectedPanel.getSemanticTypeId());
                }

            } else if (srcItem == importStyleItem) {
                File file = SldIO.importSld(appContainer, this);
                if (file != null) {
                    try {
                        importedSls = SLDFactory.createSLD(file.toURI().toURL());
                        if (importedSls != null) {
                            NamedLayer[] namedLayers = importedSls.getNamedLayers();
                            if (namedLayers.length > 0) {
                                AbstractStyle[] styles = namedLayers[0].getStyles();
                                for (int i = 0; i < styles.length; i++) {
                                    if (styles[i] instanceof UserStyle) {
                                        removeAllRuleDefinitionPanels();
                                        setStyle(styles[i]);
                                        break;
                                    }
                                }
                            }
                        }
                        styleChanged = false;
                    } catch (MalformedURLException e1) {
                        LOG.logError(get("$DG10099", file.getPath(), e1.getMessage()));
                    } catch (XMLParsingException e2) {
                        LOG.logError(get("$DG10100", file.getName(), e2.getMessage()));
                        openErrorDialog(appContainer.getViewPlatform(), this, get("$MD11073"), get("$DI10017"), e2);
                    }
                }
            } else if (srcItem == exportStyleItem) {
                AbstractLayer al = new NamedLayer(getTitle(), null,
                        new AbstractStyle[] { getMergedStyle().getStyle() });
                StyledLayerDescriptor sld = new StyledLayerDescriptor(new AbstractLayer[] { al }, "1.0.0");
                SldIO.exportSld(sld.exportAsXML(), appContainer, this);
            } else if (srcItem == settingsItem) {
                String old = settingsPanel.getUom();
                PanelDialog dlg = new PanelDialog(settingsPanel, true);
                dlg.setLocationRelativeTo(this);
                dlg.setVisible(true);
                if (dlg.clickedOk) {
                    NamedStyle currentStyle = layer.getCurrentStyle();
                    if (currentStyle instanceof DefinedStyle && !old.equals(settingsPanel.getUom())) {
                        ((DefinedStyle) currentStyle).setUom(settingsPanel.getUom());
                        informUomChangeListener();
                    }
                }
            } else if (srcItem == editSymbolItem) {
                PanelDialog dlg = new PanelDialog(new EditSymbollibraryPanel(settings.getGraphicOptions()), false);
                dlg.setLocationRelativeTo(this);
                dlg.setVisible(true);
            }
        }
    }

    private void applyStyle() {
        NamedStyle style = getStyleFromImportedSld();
        if (style == null) {
            style = getMergedStyle();
        }
        style.setCurrent(true);
        Command cmd = new ChangeLayerStyleCommand(layer, style);
        ApplicationContainer<Container> appContainer = owner.getApplicationContainer();
        try {
            appContainer.getCommandProcessor().executeSychronously(cmd, true);
        } catch (Exception e) {
            LOG.logError(e.getMessage(), e);
            DialogFactory.openErrorDialog(appContainer.getViewPlatform(), this,
                    Messages.getMessage(getLocale(), "$MD11250"), Messages.getMessage(getLocale(), "$MD11251"), e);
        }
    }

    private NamedStyle getStyleFromImportedSld() {
        if (!styleChanged && importedSls != null && importedSls.getNamedLayers().length > 0) {
            AbstractStyle[] styles = importedSls.getNamedLayers()[0].getStyles();
            for (AbstractStyle at : styles) {
                if (at instanceof UserStyle) {
                    UserStyle us = (UserStyle) at;
                    DirectStyleType dst = new DirectStyleType();
                    dst.setName(us.getName());
                    dst.setTitle(us.getTitle());
                    dst.setAbstract(us.getAbstract());
                    dst.setCurrent(true);
                    dst.setUom(getUom().toString().toLowerCase());
                    setFeatureTypeName(us);
                    return new DirectStyle(dst, us, layer);
                }
            }
        }
        return null;
    }

    private void setFeatureTypeName(UserStyle us) {
        FeatureTypeStyle[] featureTypeStyles = us.getFeatureTypeStyles();
        for (FeatureTypeStyle featureTypeStyle : featureTypeStyles) {
            String featureTypeName = getFeatureTypeName(featureTypeStyle.getFeatureTypeName());
            featureTypeStyle.setFeatureTypeName(featureTypeName);
        }
    }

    private String getFeatureTypeName(String featureTypeName) {

        CachedLayer cachedLayer = LayerCache.getInstance().getCachedLayer(layer.getIdentifier());
        Set<QualifiedName> featureTypes = cachedLayer.getFeatureTypes();
        QualifiedName featureType = null;
        for (QualifiedName availableFeatureType : featureTypes) {
            if (featureType == null) {
                featureType = availableFeatureType;
            }
            if (availableFeatureType.equals(new QualifiedName(featureTypeName))) {
                return availableFeatureType.getFormattedString();
            }
        }
        if (featureTypes.size() > 1) {
            return getFeatureTypeSelectedByUser(featureTypes, featureType.getFormattedString());
        } else if (featureTypes.size() == 1) {
            return featureType.getFormattedString();
        }
        return featureTypeName;
    }

    private String getFeatureTypeSelectedByUser(Set<QualifiedName> featureTypes, String defaultFeatureName) {
        JPanel panel = new JPanel() {
            private static final long serialVersionUID = -8531703257413252791L;

            @Override
            public String toString() {
                return get("$MD11869");
            }
        };
        panel.setLayout(new BorderLayout());
        panel.add(new JLabel(get("$MD11870")));
        JComboBox featureTypeNames = new JComboBox();
        for (QualifiedName featureType : featureTypes) {
            featureTypeNames.addItem(featureType);
        }
        panel.add(featureTypeNames);

        PanelDialog panelDialog = PanelDialog.create(this, panel, true);
        if (panelDialog.clickedOk) {
            return ((QualifiedName) featureTypeNames.getSelectedItem()).getFormattedString();
        }
        return defaultFeatureName;
    }

    /**
     * @return the uom defined for the current layer
     */
    public String getUom() {
        NamedStyle currentStyle = layer.getCurrentStyle();
        String uom = DefinedStyle.UOM_PIXEL;
        if (currentStyle instanceof DefinedStyle) {
            uom = ((DefinedStyle) currentStyle).getUom();
        }
        return uom;
    }

    @Override
    public void windowOpened(WindowEvent e) {
        // the state of this component will always be closed because it is not useful to have it
        // opened initially. So it a project will be stored the state will be closed even if the
        // Style editor is opened at this moment
        this.owner.getComponentStateAdapter().setClosed(true);
    }

    /**
     * Register a listener to be informed when the global setting for uom changed.
     * 
     * @param listener
     *            listener to add
     */
    public void addUomChangedListener(ChangeListener uomChangeListener) {
        uomChangedListener.add(uomChangeListener);
    }

    void informUomChangeListener() {
        for (ChangeListener listener : uomChangedListener) {
            listener.valueChanged(new UomChangedEvent(settingsPanel.getUom()));
        }
    }

    void setStyleChanged() {
        this.styleChanged = true;
    }

}