org.napile.idea.thermit.config.impl.configuration.AntSetPanel.java Source code

Java tutorial

Introduction

Here is the source code for org.napile.idea.thermit.config.impl.configuration.AntSetPanel.java

Source

/*
 * Copyright 2000-2012 JetBrains s.r.o.
 *
 * 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.
 */
package org.napile.idea.thermit.config.impl.configuration;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.ListModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import org.napile.idea.thermit.ThermitBundle;
import org.napile.idea.thermit.config.impl.AntInstallation;
import org.napile.idea.thermit.config.impl.AntReference;
import org.napile.idea.thermit.config.impl.GlobalThermitConfiguration;
import com.intellij.openapi.fileChooser.FileChooser;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.util.Factory;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.config.AbstractProperty;
import com.intellij.util.config.StorageAccessors;
import com.intellij.util.containers.HashMap;

public class AntSetPanel {
    private final Form myForm;
    private final GlobalThermitConfiguration myAntConfiguration;

    public AntSetPanel() {
        this(GlobalThermitConfiguration.getInstance());
    }

    AntSetPanel(GlobalThermitConfiguration antConfiguration) {
        myAntConfiguration = antConfiguration;
        myForm = new Form(antConfiguration);
    }

    @Nullable
    public AntInstallation showDialog(JComponent parent) {
        final DialogWrapper dialog = new MyDialog(parent);
        dialog.show();
        if (!dialog.isOK()) {
            return null;
        }

        apply();
        return myForm.getSelectedAnt();
    }

    void reset() {
        myForm.setAnts(myAntConfiguration.getConfiguredAnts().values());
    }

    void apply() {
        for (AntInstallation ant : myForm.getRemovedAnts()) {
            myAntConfiguration.removeConfiguration(ant);
        }

        final Map<AntReference, AntInstallation> currentAnts = myAntConfiguration.getConfiguredAnts();
        for (AntInstallation installation : currentAnts.values()) {
            installation.updateClasspath();
        }

        for (AntInstallation ant : myForm.getAddedAnts()) {
            myAntConfiguration.addConfiguration(ant);
        }
        myForm.applyModifications();
    }

    public void setSelection(AntInstallation antInstallation) {
        myForm.selectAnt(antInstallation);
    }

    public JComponent getComponent() {
        return myForm.getComponent();
    }

    private static class Form implements AntUIUtil.PropertiesEditor<AntInstallation> {
        private final Splitter mySplitter = new Splitter(false);
        private final StorageAccessors myAccessors = StorageAccessors.createGlobal("antConfigurations");
        private final RightPanel myRightPanel;
        private final AnActionListEditor<AntInstallation> myAnts = new AnActionListEditor<AntInstallation>();
        private final UIPropertyBinding.Composite myBinding = new UIPropertyBinding.Composite();
        private final EditPropertyContainer myGlobalWorkingProperties;
        private final Map<AntInstallation, EditPropertyContainer> myWorkingProperties = new HashMap<AntInstallation, EditPropertyContainer>();

        private AntInstallation myCurrent;
        private final PropertyChangeListener myImmediateUpdater = new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
                myBinding.apply(getProperties(myCurrent));
                myAnts.updateItem(myCurrent);
            }
        };

        public Form(final GlobalThermitConfiguration antInstallation) {
            mySplitter.setProportion(myAccessors.getFloat("splitter", 0.3f));
            mySplitter.setShowDividerControls(true);
            mySplitter.setFirstComponent(myAnts);
            myGlobalWorkingProperties = new EditPropertyContainer(antInstallation.getProperties());
            myRightPanel = new RightPanel(myBinding, myImmediateUpdater);
            mySplitter.setSecondComponent(myRightPanel.myWholePanel);
            myAnts.addAddAction(new NewAntFactory(myAnts));
            myAnts.addRemoveButtonForAnt(antInstallation.IS_USER_ANT, ThermitBundle.message("remove.action.name"));
            myAnts.actionsBuilt();
            JList list = myAnts.getList();
            list.setCellRenderer(new AntUIUtil.AntInstallationRenderer(this));
            list.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
                public void valueChanged(ListSelectionEvent e) {
                    if (myCurrent != null)
                        myBinding.apply(getProperties(myCurrent));
                    myCurrent = myAnts.getSelectedItem();
                    if (myCurrent == null) {
                        myBinding.loadValues(AbstractProperty.AbstractPropertyContainer.EMPTY);
                        myBinding.beDisabled();
                    } else {
                        if (antInstallation.IS_USER_ANT.value(myCurrent)) {
                            myBinding.beEnabled();
                        } else {
                            myBinding.beDisabled();
                        }
                        myBinding.loadValues(getProperties(myCurrent));
                    }
                }
            });
        }

        public JList getAntsList() {
            return myAnts.getList();
        }

        public JComponent getComponent() {
            return mySplitter;
        }

        public AntInstallation getSelectedAnt() {
            return myAnts.getSelectedItem();
        }

        public void setAnts(Collection<AntInstallation> antInstallations) {
            myAnts.setItems(antInstallations);
        }

        public void applyModifications() {
            if (myCurrent != null)
                myBinding.apply(getProperties(myCurrent));
            ArrayList<AbstractProperty> properties = new ArrayList<AbstractProperty>();
            myBinding.addAllPropertiesTo(properties);
            for (AntInstallation ant : myWorkingProperties.keySet()) {
                EditPropertyContainer container = myWorkingProperties.get(ant);
                container.apply();
            }
            myGlobalWorkingProperties.apply();
        }

        public void selectAnt(AntInstallation antInstallation) {
            myAnts.setSelection(antInstallation);
        }

        public ArrayList<AntInstallation> getAddedAnts() {
            return myAnts.getAdded();
        }

        public ArrayList<AntInstallation> getRemovedAnts() {
            return myAnts.getRemoved();
        }

        public EditPropertyContainer getProperties(AntInstallation ant) {
            EditPropertyContainer properties = myWorkingProperties.get(ant);
            if (properties != null)
                return properties;
            properties = new EditPropertyContainer(myGlobalWorkingProperties, ant.getProperties());

            myWorkingProperties.put(ant, properties);
            return properties;
        }

        private static class RightPanel {
            private JLabel myNameLabel;
            private JLabel myHome;
            private JTextField myName;
            private AntClasspathEditorPanel myClasspath;
            private JPanel myWholePanel;

            public RightPanel(UIPropertyBinding.Composite binding, PropertyChangeListener immediateUpdater) {
                myNameLabel.setLabelFor(myName);
                binding.addBinding(myClasspath.setClasspathProperty(AntInstallation.CLASS_PATH));
                binding.bindString(myHome, AntInstallation.HOME_DIR);
                binding.bindString(myName, AntInstallation.NAME).addChangeListener(immediateUpdater);
            }
        }
    }

    private static class NewAntFactory implements Factory<AntInstallation> {
        private final AnActionListEditor<AntInstallation> myParent;

        public NewAntFactory(AnActionListEditor<AntInstallation> parent) {
            myParent = parent;
        }

        public AntInstallation create() {
            FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
            VirtualFile file = FileChooser.chooseFile(descriptor, myParent, null, null);
            if (file == null)
                return null;
            try {
                final AntInstallation inst = AntInstallation.fromHome(file.getPresentableUrl());
                adjustName(inst);
                return inst;
            } catch (AntInstallation.ConfigurationException e) {
                Messages.showErrorDialog(myParent, e.getMessage(), ThermitBundle.message("ant.setup.dialog.title"));
                return null;
            }
        }

        private void adjustName(final AntInstallation justCreated) {
            int nameIndex = 0;
            String adjustedName = justCreated.getName();
            final ListModel model = myParent.getList().getModel();

            int idx = 0;
            while (idx < model.getSize()) {
                final AntInstallation inst = (AntInstallation) model.getElementAt(idx++);
                if (adjustedName.equals(inst.getName())) {
                    adjustedName = justCreated.getName() + " (" + (++nameIndex) + ")";
                    idx = 0; // search from beginning
                }
            }

            if (!adjustedName.equals(justCreated.getName())) {
                justCreated.setName(adjustedName);
            }
        }
    }

    private class MyDialog extends DialogWrapper {
        public MyDialog(final JComponent parent) {
            super(parent, true);
            setTitle(ThermitBundle.message("configure.ant.dialog.title"));
            init();
        }

        @Nullable
        protected JComponent createCenterPanel() {
            return myForm.getComponent();
        }

        @NonNls
        protected String getDimensionServiceKey() {
            return "antSetDialogDimensionKey";
        }

        public JComponent getPreferredFocusedComponent() {
            return myForm.getAntsList();
        }

        protected void doOKAction() {
            final Set<String> names = new HashSet<String>();
            final ListModel model = myForm.getAntsList().getModel();
            for (int idx = 0; idx < model.getSize(); idx++) {
                final AntInstallation inst = (AntInstallation) model.getElementAt(idx);
                final String name = AntInstallation.NAME.get(myForm.getProperties(inst));
                if (names.contains(name)) {
                    Messages.showErrorDialog("Duplicate thermit installation name: \"" + name + "\"", getTitle());
                    return;
                }
                names.add(name);
            }

            super.doOKAction();
        }
    }
}