Package org.eclim.installer.step

Source Code of org.eclim.installer.step.EclipsePluginsStep$DependencySelectionListener

/**
* Copyright (C) 2005 - 2013  Eric Van Dewoestine
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.eclim.installer.step;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;

import java.awt.event.ActionEvent;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;

import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

import org.apache.commons.io.FilenameUtils;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.SystemUtils;

import org.eclim.installer.step.command.Command;
import org.eclim.installer.step.command.InstallCommand;
import org.eclim.installer.step.command.ListCommand;
import org.eclim.installer.step.command.OutputHandler;

import org.eclim.installer.theme.DesertBlue;

import org.formic.Installer;

import org.formic.util.dialog.gui.GuiDialogs;

import org.formic.wizard.step.gui.InstallStep;

import com.jgoodies.looks.plastic.PlasticTheme;

import foxtrot.Worker;

/**
* Step which installs necessary third party eclipse plugins.
*
* @author Eric Van Dewoestine
*/
public class EclipsePluginsStep
  extends InstallStep
  implements OutputHandler
{
  private static final String BEGIN_TASK = "beginTask";
  private static final String PREPARE_TASK = "prepare";
  private static final String SUB_TASK = "subTask";
  private static final String INTERNAL_WORKED = "worked";
  private static final String SET_TASK_NAME = "setTaskName";

  private static final Color ERROR_COLOR = new Color(255, 201, 201);

  private String taskName = "";

  private JPanel stepPanel;
  private JPanel featuresPanel;
  private JLabel messageLabel;
  private ImageIcon errorIcon;
  private DefaultTableModel tableModel;
  private List<Dependency> dependencies;
  private Map<String,String> availableFeatures;
  private PlasticTheme theme;
  private int overallProgressStep;

  /**
   * Constructs this step.
   */
  public EclipsePluginsStep(String name, Properties properties)
  {
    super(name, properties);
  }

  @Override
  public Component init()
  {
    theme = new DesertBlue();
    stepPanel = (JPanel)super.init();
    stepPanel.setBorder(null);

    JPanel panel = new JPanel();
    panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
    messageLabel = new JLabel();
    messageLabel.setPreferredSize(new Dimension(25, 25));
    panel.add(messageLabel);
    panel.add(stepPanel);
    panel.setBorder(BorderFactory.createEmptyBorder(25, 25, 10, 25));

    return panel;
  }

  private void setMessage(String message)
  {
    if(errorIcon == null){
      errorIcon = new ImageIcon(Installer.getImage("form.error.icon"));
    }
    if(message != null){
      messageLabel.setIcon(errorIcon);
      messageLabel.setText(message);
    }else{
      messageLabel.setIcon(null);
      messageLabel.setText(null);
    }
  }

  @Override
  public void displayed()
  {
    setBusy(true);
    setPreviousEnabled(false);

    try{
      overallLabel.setText("");
      overallProgress.setValue(0);
      taskLabel.setText("");
      taskProgress.setValue(0);
      taskProgress.setIndeterminate(true);

      // handle step re-entry.
      if (featuresPanel != null){
        stepPanel.remove(featuresPanel);
      }

      EclipseInfo info = (EclipseInfo)
        Installer.getContext().getValue("eclipse.info");

      // find chosen features dependencies which need to be installed/upgraded.
      dependencies = unsatisfiedDependencies(info);

      if(dependencies.size() == 0){
        overallProgress.setMaximum(1);
        overallProgress.setValue(1);
        overallLabel.setText("All third party plugins are up to date.");
        taskProgress.setMaximum(1);
        taskProgress.setValue(1);
        taskLabel.setText("");
      }else{
        tableModel = new DefaultTableModel();
        tableModel.addColumn("Feature");
        tableModel.addColumn("Version");
        tableModel.addColumn("Install / Upgrade");
        JTable table = new JTable(tableModel);
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        table.setDefaultRenderer(Object.class, new DependencyCellRenderer());
        table.getSelectionModel().addListSelectionListener(
            new DependencySelectionListener());

        featuresPanel = new JPanel(new BorderLayout());
        featuresPanel.setAlignmentX(0.0f);

        JPanel container = new JPanel(new BorderLayout());
        container.add(table, BorderLayout.CENTER);

        JScrollPane scrollPane = new JScrollPane(container);
        scrollPane.setAlignmentX(0.0f);

        availableFeatures = loadAvailableFeatures();
        for (Dependency dependency : dependencies){
          String version = availableFeatures.get(dependency.getId());
          String manual = "";
          if (version == null){
            manual = " (Manual)";
            version = dependency.getRequiredVersion();
          }
          tableModel.addRow(new Object[]{
            dependency.getId(),
            version,
            (dependency.isUpgrade() ? "Upgrade" : "Install") + manual,
          });
        }

        JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0));
        buttons.setAlignmentX(0.0f);

        JButton skipButton = new JButton(new SkipPluginsAction());
        JButton installButton =
          new JButton(new InstallPluginsAction(skipButton));

        buttons.add(installButton);
        buttons.add(skipButton);

        featuresPanel.add(scrollPane, BorderLayout.CENTER);
        featuresPanel.add(buttons, BorderLayout.SOUTH);

        stepPanel.add(featuresPanel);
        overallProgress.setValue(0);
        overallLabel.setText("");
        taskProgress.setValue(0);
        taskLabel.setText("");
      }
    }catch(Exception e){
      setError(e);
    }finally{
      setValid(dependencies != null && dependencies.size() == 0);
      setBusy(false);
      setPreviousEnabled(true);
      taskProgress.setIndeterminate(false);
    }
  }

  public void process(final String line)
  {
    SwingUtilities.invokeLater(new Runnable(){
      public void run(){
        if (line.startsWith(BEGIN_TASK)){
          String l = line.substring(BEGIN_TASK.length() + 2);
          double work = Double.parseDouble(
              l.substring(l.indexOf('=') + 1, l.indexOf(' ')));
          taskProgress.setIndeterminate(false);
          taskProgress.setMaximum((int)work);
          taskProgress.setValue(0);
        }else if(line.startsWith(PREPARE_TASK)){
          taskLabel.setText(line.substring(PREPARE_TASK.length() + 1).trim());
        }else if(line.startsWith(SUB_TASK)){
          taskLabel.setText(
              taskName + line.substring(SUB_TASK.length() + 1).trim());
        }else if(line.startsWith(INTERNAL_WORKED)){
          double worked = Double.parseDouble(
              line.substring(INTERNAL_WORKED.length() + 2));
          taskProgress.setValue((int)worked);
          overallProgress.setValue(
            overallProgressStep + (int)(taskProgress.getPercentComplete() * 100));
        }else if(line.startsWith(SET_TASK_NAME)){
          taskName = line.substring(SET_TASK_NAME.length() + 1).trim() + ' ';
        }
      }
    });
  }

  private List<Dependency> unsatisfiedDependencies(EclipseInfo info)
  {
    List<Dependency> deps = new ArrayList<Dependency>();
    String[] features = Installer.getContext().getKeysByPrefix("featureList");
    Arrays.sort(features, new FeatureNameComparator());
    for (int ii = 0; ii < features.length; ii++){
      Boolean enabled = (Boolean)Installer.getContext().getValue(features[ii]);
      if (enabled.booleanValue()){
        String name = features[ii].substring(features[ii].indexOf('.') + 1);
        deps.addAll(info.getUnsatisfiedDependencies(name));
      }
    }
    return deps;
  }

  @SuppressWarnings("unchecked")
  private Map<String,String> loadAvailableFeatures()
    throws Exception
  {
    // load up available features from update sites.
    overallProgress.setMaximum(1);
    overallLabel.setText("Loading available features from update sites...");

    return (Map<String,String>)Worker.post(new foxtrot.Task(){
      public Object run()
        throws Exception
      {
        final Map<String,String> availableFeatures = new HashMap<String,String>();

        ArrayList<String> sites = new ArrayList<String>();
        for (Dependency dependency : dependencies){
          String site = dependency.getSite();
          if (site == null){
            availableFeatures.put(
              dependency.getId(), dependency.getRequiredVersion());
          }else if (!sites.contains(site)){
            sites.add(site);
          }
        }

        OutputHandler handler = new OutputHandler(){
          public void process(String line){
            String[] parts = StringUtils.split(line, "=");
            if (parts.length == 2 && parts[0].endsWith(".feature.group")){
              availableFeatures.put(
                parts[0].replace(".feature.group", ""), parts[1]);
            }
          }
        };
        if (sites.size() > 0){
          Command command = new ListCommand(
            handler, sites.toArray(new String[sites.size()]));
          try{
            command.start();
            command.join();
            if(command.getReturnCode() != 0){
              throw new RuntimeException(
                  "error: " + command.getErrorMessage() +
                  " out: " + command.getResult());
            }
          }finally{
            command.destroy();
          }
        }
        return availableFeatures;
      }
    });
  }

  private class InstallPluginsAction
    extends AbstractAction
  {
    private static final long serialVersionUID = 1L;

    private JButton skipButton;

    public InstallPluginsAction(JButton skipButton)
    {
      super("Install Features");
      this.skipButton = skipButton;
    }

    public void actionPerformed(ActionEvent e)
    {
      ((JButton)e.getSource()).setEnabled(false);
      setPreviousEnabled(true);
      try{
        Boolean successful = (Boolean)Worker.post(new foxtrot.Task(){
          public Object run()
            throws Exception
          {
            // check if any of the features cannot be installed.
            for (Dependency dependency : dependencies){
              Feature feature = dependency.getFeature();
              if (feature != null) {
                if (feature.getSite() == null){
                  String installLog = FilenameUtils.concat(
                    SystemUtils.JAVA_IO_TMPDIR, "install.log");
                  GuiDialogs.showWarning(Installer.getString(
                      "eclipsePlugins.install.features.site.not.found", installLog));
                  return Boolean.FALSE;
                }else if (!feature.getSite().canWrite()){
                  GuiDialogs.showWarning(Installer.getString(
                      "eclipsePlugins.install.features.permission.denied"));
                  return Boolean.FALSE;
                }
              }
            }

            int installCount = 0;
            for (Iterator<Dependency> ii = dependencies.iterator(); ii.hasNext();){
              Dependency dependency = ii.next();
              if (dependency.getSite() != null){
                installCount++;
              }
            }

            overallProgress.setMaximum(installCount * 100);
            overallProgress.setValue(0);

            int removeIndex = 0;
            for (Iterator<Dependency> ii = dependencies.iterator(); ii.hasNext();){
              Dependency dependency = ii.next();
              String site = dependency.getSite();
              String version = availableFeatures.get(dependency.getId());
              if (site != null && version != null){
                if(!dependency.isUpgrade()){
                  overallLabel.setText("Installing feature: " +
                      dependency.getId() + '-' + version);
                }else{
                  overallLabel.setText("Updating feature: " +
                      dependency.getId() + '-' + version);
                }

                taskProgress.setValue(0);
                taskProgress.setIndeterminate(true);

                Command command = new InstallCommand(
                    EclipsePluginsStep.this,
                    dependency.getSite(),
                    dependency.getId());
                try{
                  command.start();
                  command.join();
                  if(command.getReturnCode() != 0){
                    if (command.isShutdown()){
                      return Boolean.TRUE;
                    }
                    throw new RuntimeException(
                        "error: " + command.getErrorMessage() +
                        " out: " + command.getResult());
                  }
                }finally{
                  command.destroy();
                }

                ii.remove();
                tableModel.removeRow(removeIndex);
              }else{
                removeIndex++;
              }
              overallProgressStep += 100;
              overallProgress.setValue(overallProgressStep);
            }
            taskLabel.setText("");
            taskProgress.setValue(taskProgress.getMaximum());
            overallProgress.setValue(overallProgress.getMaximum());

            if(dependencies.size() > 0){
              GuiDialogs.showWarning(Installer.getString("eclipsePlugins.manual"));
            }

            return Boolean.TRUE;
          }
        });

        if(successful.booleanValue()){
          overallProgress.setValue(overallProgress.getMaximum());
          overallLabel.setText(Installer.getString("install.done"));

          taskProgress.setValue(taskProgress.getMaximum());
          taskLabel.setText(Installer.getString("install.done"));

          setBusy(false);
          setValid(true);
          taskProgress.setIndeterminate(false);

          skipButton.setEnabled(false);
        }
      }catch(Exception ex){
        setError(ex);
      }
    }
  }

  private class SkipPluginsAction
    extends AbstractAction
  {
    private static final long serialVersionUID = 1L;

    public SkipPluginsAction()
    {
      super("Skip");
    }

    public void actionPerformed(ActionEvent e)
    {
      if(GuiDialogs.showConfirm(Installer.getString("eclipsePlugins.skip"))){
        setValid(true);
      }
    }
  }

  private class DependencyCellRenderer
    extends DefaultTableCellRenderer
  {
    private static final long serialVersionUID = 1L;

    public Component getTableCellRendererComponent(
        JTable table, Object value,
        boolean isSelected, boolean hasFocus,
        int row, int column)
    {
      Component component = super.getTableCellRendererComponent(
          table, value, isSelected, hasFocus, row, column);
      Feature feature = ((Dependency)dependencies.get(row)).getFeature();
      if (feature != null &&
          (feature.getSite() == null || !feature.getSite().canWrite()))
      {
        component.setBackground(isSelected ?
            theme.getMenuItemSelectedBackground() : ERROR_COLOR);
        component.setForeground(isSelected ? ERROR_COLOR : Color.BLACK);
      }else{
        component.setBackground(isSelected ?
            theme.getMenuItemSelectedBackground() : Color.WHITE);
        component.setForeground(isSelected ?
            theme.getMenuItemSelectedForeground() : theme.getMenuForeground());
      }
      return component;
    }
  }

  /**
   * Mouse listener for the feature list.
   */
  private class DependencySelectionListener
    implements ListSelectionListener
  {
    @Override
    public void valueChanged(ListSelectionEvent e)
    {
      ListSelectionModel model = (ListSelectionModel)e.getSource();
      int index = model.getMinSelectionIndex();
      Feature feature = index >= 0 ?
        ((Dependency)dependencies.get(index)).getFeature() : null;

      if (feature != null) {
        if (feature.getSite() == null){
          setMessage(Installer.getString("eclipsePlugins.upgrade.site.not.found"));
        }else if (!feature.getSite().canWrite()){
          setMessage(Installer.getString(
                "eclipsePlugins.upgrade.permission.denied"));
        }
      }else{
        setMessage(null);
      }
    }
  }

  private static class FeatureNameComparator
    implements Comparator<String>
  {
    private static ArrayList<String> NAMES = new ArrayList<String>();
    static{
      NAMES.add("featureList.jdt");
      NAMES.add("featureList.wst");
      NAMES.add("featureList.adt");
      NAMES.add("featureList.cdt");
      NAMES.add("featureList.pdt");
      NAMES.add("featureList.pydev");
      NAMES.add("featureList.sdt210");
      NAMES.add("featureList.groovy");
    }

    public int compare(String ob1, String ob2)
    {
      return NAMES.indexOf(ob1) - NAMES.indexOf(ob2);
    }
  }
}
TOP

Related Classes of org.eclim.installer.step.EclipsePluginsStep$DependencySelectionListener

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.