All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gate.gui.persistence.XgappUpgradeSelector Maven / Gradle / Ivy

Go to download

GATE - general achitecture for text engineering - is open source software capable of solving almost any text processing problem. This artifact enables you to embed the core GATE Embedded with its essential dependencies. You will able to use the GATE Embedded API and load and store GATE XML documents. This artifact is the perfect dependency for CREOLE plugins or for applications that need to customize the GATE dependencies due to confict with their own dependencies or for lower footprint.

The newest version!
/*
 *  Copyright (c) 1995-2013, The University of Sheffield. See the file
 *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
 *
 *  This file is part of GATE (see http://gate.ac.uk/), and is free
 *  software, licenced under the GNU Library General Public License,
 *  Version 2, June 1991 (in the distribution as file licence.html,
 *  and also available at http://gate.ac.uk/gate/licence.html).
 *
 *  Valentin Tablan 23/01/2001
 *
 *  $Id: XgappUpgradeSelector.java 1 2018-05-04 14:36:21Z ian_roberts $
 *
 */
package gate.gui.persistence;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.EventObject;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import javax.swing.AbstractCellEditor;
import javax.swing.Box;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

import org.eclipse.aether.resolution.VersionRangeResult;
import org.eclipse.aether.version.Version;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import gate.gui.AlternatingTableCellEditor;
import gate.gui.MainFrame;
import gate.persist.PersistenceException;
import gate.resources.img.svg.GreenBallIcon;
import gate.resources.img.svg.InvalidIcon;
import gate.resources.img.svg.OpenFileIcon;
import gate.resources.img.svg.RedBallIcon;
import gate.resources.img.svg.SaveIcon;
import gate.resources.img.svg.YellowBallIcon;
import gate.swing.XJFileChooser;
import gate.swing.XJTable;
import gate.util.ExtensionFileFilter;
import gate.util.persistence.PersistenceManager;
import gate.util.persistence.UpgradeXGAPP;

public class XgappUpgradeSelector implements ActionListener {

  private static final Logger log = LoggerFactory.getLogger(XgappUpgradeSelector.class);

  private List upgrades;

  private URI gappUri;

  private EnumMap strategyIcons;

  private Icon disabledStrategyIcon;

  private JLabel statusLabel;

  private JPanel mainPanel;

  private Icon warningIcon = new InvalidIcon(16, 16);

  private UpgradePathTableModel model;


  public XgappUpgradeSelector(URI gappUri, List upgrades) {
    this.gappUri = gappUri;
    this.upgrades = upgrades;
    model = new UpgradePathTableModel(upgrades);

    strategyIcons = new EnumMap(UpgradeXGAPP.UpgradePath.UpgradeStrategy.class);
    strategyIcons.put(UpgradeXGAPP.UpgradePath.UpgradeStrategy.UPGRADE, new GreenBallIcon(16, 16));
    strategyIcons.put(UpgradeXGAPP.UpgradePath.UpgradeStrategy.PLUGIN_ONLY, new YellowBallIcon(16, 16));
    strategyIcons.put(UpgradeXGAPP.UpgradePath.UpgradeStrategy.SKIP, new RedBallIcon(16, 16));
    disabledStrategyIcon = new RedBallIcon(16, 16, true);

    XJTable pluginTable = new XJTable(model);
    pluginTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
    JScrollPane scroller = new JScrollPane(pluginTable);
    statusLabel = new JLabel("Select plugin versions to upgrade to");
    JPanel topPanel = new JPanel(new BorderLayout());
    topPanel.add(statusLabel, BorderLayout.CENTER);

    Box buttonBox = Box.createHorizontalBox();
    JButton loadButton = new JButton();
    loadButton.setIcon(new OpenFileIcon(24, 24));
    loadButton.setToolTipText("Load a saved upgrade script");
    loadButton.setActionCommand("LOADSCRIPT");
    loadButton.addActionListener(this);
    buttonBox.add(loadButton);
    buttonBox.add(Box.createHorizontalStrut(5));

    JButton saveButton = new JButton();
    saveButton.setIcon(new SaveIcon(24, 24));
    saveButton.setToolTipText("Save selected upgrades as a script");
    saveButton.setActionCommand("SAVESCRIPT");
    saveButton.addActionListener(this);
    buttonBox.add(saveButton);
    topPanel.add(buttonBox, BorderLayout.SOUTH);

    mainPanel = new JPanel(new BorderLayout());
    mainPanel.add(topPanel, BorderLayout.NORTH);
    mainPanel.add(scroller, BorderLayout.CENTER);

    DefaultTableCellRenderer newPluginRenderer = new DefaultTableCellRenderer();
    newPluginRenderer.setToolTipText("Double-click or press the space key to change");
    pluginTable.getColumnModel().getColumn(1).setCellRenderer(newPluginRenderer);
    pluginTable.getColumnModel().getColumn(2).setCellRenderer(new UpgradeStrategyRenderer());
    pluginTable.getColumnModel().getColumn(3).setCellRenderer(new DefaultTableCellRenderer() {
      @Override
      public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        JLabel label = (JLabel)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        label.setEnabled(((UpgradeXGAPP.UpgradePath.UpgradeStrategy)table.getValueAt(row, 2)).upgradePlugin);
        return label;
      }
    });
    pluginTable.getColumnModel().getColumn(1).setCellEditor(new PluginCoordinatesEditor());
    // Alternate between two different cell editor components to avoid combo box rendering weirdness
    pluginTable.getColumnModel().getColumn(2).setCellEditor(
            new AlternatingTableCellEditor(new UpgradeStrategyEditor(), new UpgradeStrategyEditor()));
    pluginTable.getColumnModel().getColumn(3).setCellEditor(
            new AlternatingTableCellEditor(new UpgradeVersionEditor(), new UpgradeVersionEditor()));

    // initial sort
    model.fireTableDataChanged();
  }

  public boolean showDialog(Window parent) {
    JOptionPane optionPane = new JOptionPane(mainPanel, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
    JDialog dialog = optionPane.createDialog(parent, "Select plugin versions");
    dialog.setResizable(true);
    dialog.setVisible(true);
    return (((Integer)optionPane.getValue()).intValue() == JOptionPane.OK_OPTION);
  }

  public void actionPerformed(ActionEvent event) {
    XJFileChooser fileChooser = MainFrame.getFileChooser();
    fileChooser.setResource("xgappUpgradeScript");
    fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
    ExtensionFileFilter filter = new ExtensionFileFilter("Tab-separated values", ".tsv");
    fileChooser.resetChoosableFileFilters();
    fileChooser.addChoosableFileFilter(filter);
    fileChooser.setFileFilter(filter);
    if("SAVESCRIPT".equals(event.getActionCommand())) {
      fileChooser.setDialogTitle("Save upgrade script");
      int result = fileChooser.showSaveDialog(mainPanel);
      if(result == JFileChooser.APPROVE_OPTION) {
        try {
          UpgradeXGAPP.saveUpgradePaths(model.upgrades, gappUri, fileChooser.getSelectedFile());
        } catch(IOException e) {
          log.error("Error writing upgrade script", e);
          statusLabel.setIcon(warningIcon);
          statusLabel.setText("Couldn't save upgrade script, see messages pane for details");
        }
      }
    } else if("LOADSCRIPT".equals(event.getActionCommand())) {
      fileChooser.setDialogTitle("Select upgrade script to load");
      int result = fileChooser.showOpenDialog(mainPanel);
      if(result == JFileChooser.APPROVE_OPTION) {
        try {
          UpgradeXGAPP.loadUpgradePaths(model.upgrades, gappUri, fileChooser.getSelectedFile());
          model.fireTableDataChanged();
        } catch(IOException e) {
          log.error("Error reading upgrade script", e);
          statusLabel.setIcon(warningIcon);
          statusLabel.setText("Couldn't load upgrade script, see messages pane for details");
        }
      }
    }
  }

  protected class UpgradePathTableModel extends AbstractTableModel {
    private List upgrades;

    private int[] namedepths;

    UpgradePathTableModel(List upgrades) {
      this.upgrades = upgrades;
      this.namedepths = new int[upgrades.size()];
      Arrays.fill(this.namedepths, 0);
      refreshDepths();
    }

    private void refreshDepths() {
      boolean finished = false;
      while(!finished) {
        finished = true;
        Map> grouped = IntStream.range(0, namedepths.length).boxed()
                .collect(Collectors.groupingBy((i) -> (String)getValueAt(i, 0)));
        for(Map.Entry> e : grouped.entrySet()) {
          if(e.getValue().size() > 1) {
            // two or more rows have the same name in the first column - increment all their
            // namedepth values unless they're already as detailed as can be
            for(Integer i : e.getValue()) {
              if(namedepths[i] < 2) {
                namedepths[i]++;
                finished = false;
              }
            }
          }
        }
        // by the time we get to here either (a) all the rows have distinct names or
        // (b) those that don't are already showing as much detail as we know and we
        // simply can't disambiguate them fully.
      }
    }

    @Override
    public int getRowCount() {
      return upgrades.size();
    }

    @Override
    public int getColumnCount() {
      return 4;
    }

    @Override
    public String getColumnName(int column) {
      switch(column) {
        case 0:
          return "Old plugin";
        case 1:
          return "New plugin";
        case 2:
          return "Upgrade?";
        case 3:
          return "Target version";
        default:
          return "UNKNOWN";
      }
    }

    @Override
    public Class getColumnClass(int columnIndex) {
      switch(columnIndex) {
        case 0:
          return String.class;
        case 1:
          return PluginCoordinates.class;
        case 2:
          return UpgradeXGAPP.UpgradePath.UpgradeStrategy.class;
        case 3:
          return Version.class;
        default:
          return null;
      }
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
      UpgradeXGAPP.UpgradePath path = upgrades.get(rowIndex);
      return (columnIndex == 1) ||
              (columnIndex == 2 && path.getGroupID() != null) ||
              (columnIndex == 3 && path.getUpgradeStrategy().upgradePlugin);
    }

    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
      UpgradeXGAPP.UpgradePath path = upgrades.get(rowIndex);
      if(columnIndex == 1) {
        PluginCoordinates coords = (PluginCoordinates)aValue;
        VersionRangeResult vrr = UpgradeXGAPP.getPluginVersions(coords.groupId, coords.artifactId);
        List versions = (vrr == null ? null : vrr.getVersions());
        if(versions != null && !versions.isEmpty()) {
          path.setGroupID(coords.groupId);
          path.setArtifactID(coords.artifactId);
          path.setVersionRangeResult(vrr);
          path.setUpgradeStrategy(UpgradeXGAPP.UpgradePath.UpgradeStrategy.UPGRADE);
          fireTableCellUpdated(rowIndex, 2);
          if(!versions.contains(path.getSelectedVersion())) {
            path.setSelectedVersion(UpgradeXGAPP.getDefaultSelection(vrr));
            fireTableCellUpdated(rowIndex, 3);
          }
        } else {
          statusLabel.setIcon(warningIcon);
          statusLabel.setText(coords + " is not a valid GATE plugin");
        }
      } else if(columnIndex == 2) {
        path.setUpgradeStrategy((UpgradeXGAPP.UpgradePath.UpgradeStrategy) aValue);
        // may need to re-render the version column
        fireTableCellUpdated(rowIndex, 3);
      } else if(columnIndex == 3) {
        path.setSelectedVersion((Version) aValue);
      }
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
      UpgradeXGAPP.UpgradePath path = upgrades.get(rowIndex);
      if(columnIndex == 0) {
        if(path.getOldPath().startsWith("$gate")) {
          // pre-8.5 GATE_HOME/plugins/Something
          int startOffset = 18; // for $gatehome$plugins/Foo/
          if(path.getOldPath().startsWith("$gateplugins$")) {
            startOffset = 13;
          }
          return "Pre-8.5 " + path.getOldPath().substring(startOffset, path.getOldPath().length() - 1) + " (built-in)";
        } else if(path.getOldPath().startsWith("creole:")) {
          // an existing Maven plugin
          String[] gav = path.getOldPath().substring(9).split(";", 3);
          if(namedepths[rowIndex] == 0) {
            return gav[1]; // just artifact ID
          } else if(namedepths[rowIndex] == 1) {
            return gav[1] + ":" + gav[2]; // artifact:version
          } else {
            return gav[0] + ":" + gav[1] + ":" + gav[2]; // group:artifact:version
          }
        } else {
          // a path to something that isn't gatehome
          try {
            URI oldURI = PersistenceManager.URLHolder.unpackPersistentRepresentation(gappUri, path.getOldPath());
            String[] parts = oldURI.toString().split("/");
            return "Directory plugin \"" + parts[parts.length - 1]
                    + "\"
" + oldURI + ""; } catch(PersistenceException e) { return path.getOldPath(); } } } else if(columnIndex == 1) { return new PluginCoordinates(path.getGroupID(), path.getArtifactID()); } else if(columnIndex == 2) { return path.getUpgradeStrategy(); } else if(columnIndex == 3) { // column 3 return path.getSelectedVersion(); } else { // if we ask for an unknown column (including a negative number) // return the upgrade path itself. This is used as a way to // get the UpgradePath for a row by visible row number unpacking // the XJTable sorting mechanism. return path; } } } protected class UpgradeVersionEditor extends DefaultCellEditor { @SuppressWarnings("unchecked") protected UpgradeVersionEditor() { super(new JComboBox()); JComboBox combo = (JComboBox)getComponent(); combo.setModel(new DefaultComboBoxModel<>()); } @Override @SuppressWarnings("unchecked") public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { JComboBox combo = (JComboBox)super.getTableCellEditorComponent(table, value, isSelected, row, column); DefaultComboBoxModel model = (DefaultComboBoxModel)combo.getModel(); model.removeAllElements(); UpgradeXGAPP.UpgradePath path = (UpgradeXGAPP.UpgradePath)table.getValueAt(row, -1); for(Version v : path.getVersions()) { model.addElement(v); } combo.setSelectedItem(value); // which must be one of the available ones return combo; } } protected class UpgradeStrategyRenderer extends DefaultTableCellRenderer { private JLabel prototype = new DefaultTableCellRenderer(); { prototype.setText(UpgradeXGAPP.UpgradePath.UpgradeStrategy.PLUGIN_ONLY.label); prototype.setIcon(strategyIcons.get(UpgradeXGAPP.UpgradePath.UpgradeStrategy.PLUGIN_ONLY)); } @Override public Dimension getMinimumSize() { return prototype.getMinimumSize(); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { JLabel renderer = (JLabel)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); renderer.setText(((UpgradeXGAPP.UpgradePath.UpgradeStrategy)value).label); renderer.setToolTipText(((UpgradeXGAPP.UpgradePath.UpgradeStrategy)value).tooltip); renderer.setIcon(strategyIcons.get(value)); renderer.setDisabledIcon(disabledStrategyIcon); renderer.setEnabled(((PluginCoordinates)table.getValueAt(row, 1)).groupId != null); return renderer; } } protected class UpgradeStrategyEditor extends DefaultCellEditor { @SuppressWarnings("unchecked") protected UpgradeStrategyEditor() { super(new JComboBox()); JComboBox combo = (JComboBox)getComponent(); combo.setRenderer(new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel renderer = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); renderer.setText(((UpgradeXGAPP.UpgradePath.UpgradeStrategy)value).label); renderer.setToolTipText(((UpgradeXGAPP.UpgradePath.UpgradeStrategy)value).tooltip); renderer.setIcon(strategyIcons.get(value)); renderer.setDisabledIcon(disabledStrategyIcon); return renderer; } }); combo.setModel(new DefaultComboBoxModel<>()); } @Override @SuppressWarnings("unchecked") public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { JComboBox combo = (JComboBox)super.getTableCellEditorComponent(table, value, isSelected, row, column); DefaultComboBoxModel model = (DefaultComboBoxModel)combo.getModel(); model.removeAllElements(); if(((String)table.getValueAt(row, 0)).startsWith("")) { // directory plugin model.addElement(UpgradeXGAPP.UpgradePath.UpgradeStrategy.UPGRADE); model.addElement(UpgradeXGAPP.UpgradePath.UpgradeStrategy.PLUGIN_ONLY); model.addElement(UpgradeXGAPP.UpgradePath.UpgradeStrategy.SKIP); } else { // old $gatehome$ or existing Maven model.addElement(UpgradeXGAPP.UpgradePath.UpgradeStrategy.UPGRADE); model.addElement(UpgradeXGAPP.UpgradePath.UpgradeStrategy.SKIP); } combo.setSelectedItem(value); // which must be one of the available ones return combo; } } protected class PluginCoordinatesEditor extends AbstractCellEditor implements TableCellEditor { TableCellRenderer renderer = new DefaultTableCellRenderer(); JPanel mainPanel; JTextField groupIdField; JTextField artifactIdField; PluginCoordinatesEditor() { GridBagLayout layout = new GridBagLayout(); mainPanel = new JPanel(layout); GridBagConstraints c = new GridBagConstraints(); c.insets = new Insets(5, 5, 5, 5); JLabel label = new JLabel("Please enter Maven co-ordinates of new plugin"); c.gridx = 0; c.gridy = 0; c.anchor = GridBagConstraints.CENTER; c.weightx = 0; c.gridwidth = 2; mainPanel.add(label); layout.setConstraints(label, c); c.anchor = GridBagConstraints.LINE_START; c.gridx = 0; c.gridy = 1; c.gridwidth = 1; label = new JLabel("Group ID"); mainPanel.add(label); layout.setConstraints(label, c); c.gridx = 1; c.weightx = 1; groupIdField = new JTextField(30); mainPanel.add(groupIdField); layout.setConstraints(groupIdField, c); c.gridx = 0; c.gridy = 2; c.weightx = 0; label = new JLabel("Artifact ID"); mainPanel.add(label); layout.setConstraints(label, c); c.gridx = 1; c.weightx = 1; artifactIdField = new JTextField(30); mainPanel.add(artifactIdField); layout.setConstraints(artifactIdField, c); } PluginCoordinates selected = null; @Override public Object getCellEditorValue() { return selected; } @Override public boolean isCellEditable(EventObject anEvent) { if (anEvent instanceof MouseEvent) { return ((MouseEvent)anEvent).getClickCount() >= 2; } else { return true; } } @Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { PluginCoordinates coords = (PluginCoordinates)value; if(coords.groupId != null) { groupIdField.setText(coords.groupId); } else { groupIdField.setText(""); } artifactIdField.setText(coords.artifactId); SwingUtilities.invokeLater(() -> { int retVal = JOptionPane.showConfirmDialog(table, mainPanel, "Select new plugin", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); if(retVal == JOptionPane.CANCEL_OPTION) { selected = null; fireEditingCanceled(); } else { selected = new PluginCoordinates(groupIdField.getText(), artifactIdField.getText()); fireEditingStopped(); } }); return renderer.getTableCellRendererComponent(table, value, isSelected, true, row, column); } } protected static class PluginCoordinates { String groupId; String artifactId; public PluginCoordinates(String groupId, String artifactId) { this.groupId = groupId; this.artifactId = artifactId; } public String toString() { if(groupId == null) { return "<unknown>"; } else if("uk.ac.gate.plugins".equals(groupId)) { return artifactId; } else { return groupId + ":" + artifactId; } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy