/*
* Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de)
*
* 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 com.bc.ceres.swing.update;
import com.bc.ceres.core.Assert;
import com.bc.ceres.core.CanceledException;
import com.bc.ceres.core.CoreException;
import com.bc.ceres.core.SubProgressMonitor;
import com.bc.ceres.core.runtime.Dependency;
import com.bc.ceres.core.runtime.Module;
import com.bc.ceres.core.runtime.ModuleState;
import com.bc.ceres.swing.SwingHelper;
import com.bc.ceres.swing.progress.ProgressMonitorSwingWorker;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
import javax.swing.plaf.basic.BasicSplitPaneUI;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
public class ModuleManagerPane extends JPanel {
public static final Runnable NO_DONE_HANDLER = new Runnable() {
public void run() {
}
};
static final String TITLE = "Module Manager";
private ModuleManager moduleManager;
private SyncAction syncAction;
private ClearAction clearAction;
private InstallAction installAction;
private UpdateAction updateAction;
private UninstallAction uninstallAction;
private JTable[] modulesTables;
private ModuleTableModel installedModulesTableModel;
private ModuleTableModel updatableModulesTableModel;
private ModuleTableModel availableModulesTableModel;
private boolean syncPerformed;
private JComboBox<CaselessKey> categories;
private Set<CaselessKey> categoriesSet;
private InfoPane infoPane;
private JTabbedPane tabbedPane;
private boolean confirmed;
private String repositoryTroubleShootingMessage;
private SelectAllAction selectAllAction;
public ModuleManagerPane() {
this(new DefaultModuleManager());
}
public ModuleManagerPane(ModuleManager moduleManager) {
super(new BorderLayout(2, 2));
Assert.notNull(moduleManager, "moduleManager");
this.moduleManager = moduleManager;
this.syncAction = new SyncAction();
this.clearAction = new ClearAction();
this.installAction = new InstallAction();
this.updateAction = new UpdateAction();
this.uninstallAction = new UninstallAction();
this.selectAllAction = new SelectAllAction();
this.categoriesSet = new HashSet<>(20);
repositoryTroubleShootingMessage = "";
initUi();
}
public boolean isConfirmed() {
return confirmed;
}
public void setConfirmed(boolean confirmed) {
this.confirmed = confirmed;
}
public String getRepositoryTroubleShootingMessage() {
return repositoryTroubleShootingMessage;
}
public void setRepositoryTroubleShootingMessage(String repositoryTroubleShootingMessage) {
Assert.notNull(repositoryTroubleShootingMessage);
this.repositoryTroubleShootingMessage = repositoryTroubleShootingMessage;
}
public boolean showDialog(final Window parent,
final String title,
final Runnable doneHandler,
final HelpHandler helpHandler) {
Assert.notNull(parent, "parent");
Assert.notNull(title, "title");
final JDialog dialog = createDialog(parent, title, doneHandler, helpHandler);
dialog.setSize(640, 512);
SwingHelper.centerComponent(dialog, parent);
dialog.setVisible(true);
dialog.dispose();
return isConfirmed();
}
public JDialog createDialog(final Window parent,
final String title,
final Runnable doneHandler,
final HelpHandler helpHandler) {
Assert.notNull(parent, "parent");
Assert.notNull(title, "title");
final JDialog dialog = new JDialog(parent, title, Dialog.ModalityType.APPLICATION_MODAL);
JPanel buttonPane = new JPanel(new FlowLayout(FlowLayout.RIGHT));
JButton okButton = new JButton("OK");
okButton.setName("okButton");
okButton.setMnemonic('O');
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
onOk(dialog, doneHandler);
}
});
buttonPane.add(okButton);
JButton cancelButton = new JButton("Cancel");
cancelButton.setName("cancelButton");
cancelButton.setMnemonic('C');
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
onCancel(dialog, doneHandler);
}
});
buttonPane.add(cancelButton);
if (helpHandler != null) {
JButton helpButton = new JButton("Help");
helpButton.setMnemonic('H');
helpHandler.configureHelpButton(helpButton);
helpButton.setName("helpButton");
buttonPane.add(helpButton);
}
JPanel contentPane = new JPanel(new BorderLayout(4, 4));
contentPane.add(this, BorderLayout.CENTER);
contentPane.add(buttonPane, BorderLayout.SOUTH);
contentPane.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
okButton.setDefaultCapable(true);
//dialog.getRootPane().setDefaultButton(okButton);
dialog.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
onCancel(dialog, doneHandler);
}
});
dialog.setContentPane(contentPane);
setConfirmed(false);
return dialog;
}
private void onOk(JDialog dialog, Runnable doneHandler) {
if (performUpdateActions(doneHandler)) {
setConfirmed(true);
dialog.setVisible(false);
} else {
setConfirmed(false);
doneHandler.run();
}
}
private void onCancel(JDialog dialog, Runnable doneHandler) {
setConfirmed(false);
dialog.setVisible(false);
doneHandler.run();
}
private void initUi() {
// todo - discuss with Luis V., why "Funding" ("Agency") is needed - nf- 2012-05-09
installedModulesTableModel = new ModuleTableModel(moduleManager.getInstalledModuleItems(),
new String[]{
"Name",
// "Funding",
"Version",
"State",
"Action"
}
);
updatableModulesTableModel = new ModuleTableModel(moduleManager.getUpdatableModuleItems(),
new String[]{
"Name",
// "Funding",
"Version",
"New Version",
"Date",
"Size",
"Action"
}
);
availableModulesTableModel = new ModuleTableModel(moduleManager.getAvailableModuleItems(),
new String[]{
"Name",
// "Funding",
"Version",
"Date",
"Size",
"Action"
}
);
JTable installedModulesTable = createModuleTable(installedModulesTableModel);
installedModulesTable.setName("installedModulesTable");
JTable updatableModulesTable = createModuleTable(updatableModulesTableModel);
updatableModulesTable.setName("updatableModulesTable");
JTable availableModulesTable = createModuleTable(availableModulesTableModel);
availableModulesTable.setName("availableModulesTable");
modulesTables = new JTable[]{
installedModulesTable,
updatableModulesTable,
availableModulesTable
};
tabbedPane = new JTabbedPane();
tabbedPane.setName("tabbedPane");
Component installTab = tabbedPane.add("Installed Modules", new JScrollPane(installedModulesTable));
installTab.setName("InstallTab");
Component updateTab = tabbedPane.add("Module Updates", new JScrollPane(updatableModulesTable));
updateTab.setName("UpdateTab");
Component availableTab = tabbedPane.add("Available Modules", new JScrollPane(availableModulesTable));
availableTab.setName("AvailableTab");
tabbedPane.setSelectedIndex(0);
tabbedPane.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
onTabChanged();
}
});
JToolBar actionBar = new JToolBar();
actionBar.setName("actionBar");
actionBar.setRollover(true);
actionBar.setFloatable(false);
JButton installButton = new JButton(installAction);
installButton.setName("installButton");
actionBar.add(installButton);
JButton updateButton = new JButton(updateAction);
updateButton.setName("updateButton");
actionBar.add(updateButton);
JButton uninstallButton = new JButton(uninstallAction);
uninstallButton.setName("uninstallButton");
actionBar.add(uninstallButton);
JButton clearButton = new JButton(clearAction);
clearButton.setName("clearButton");
actionBar.add(clearButton);
categories = new JComboBox<CaselessKey>();
categories.setName("categoriesComboBox");
categories.setEditable(true);
categories.setSelectedItem("");
categories.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
updateModuleTable();
updateUiState();
}
});
JPanel categoriesBar = new JPanel(new FlowLayout(FlowLayout.LEFT));
categoriesBar.add(new JLabel("Filter category:"));
categoriesBar.add(categories);
final JPanel tableActionBar = new JPanel(new BorderLayout(4, 4));
tableActionBar.add(actionBar, BorderLayout.WEST);
tableActionBar.add(categoriesBar, BorderLayout.EAST);
infoPane = new InfoPane();
JPanel tablePane = new JPanel(new BorderLayout(2, 2));
tablePane.add(tableActionBar, BorderLayout.NORTH);
tablePane.add(tabbedPane, BorderLayout.CENTER);
JSplitPane contentPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
contentPane.setContinuousLayout(true);
contentPane.setResizeWeight(0.6);
contentPane.setTopComponent(tablePane);
contentPane.setBottomComponent(infoPane);
contentPane.setBorder(BorderFactory.createEmptyBorder());
contentPane.setUI(createPlainDividerSplitPaneUI());
add(contentPane, BorderLayout.CENTER);
setPreferredSize(new Dimension(400, 400));
registerCategories(moduleManager.getInstalledModuleItems());
updateCategories();
updateUiState();
}
private void onTabChanged() {
int selectedIndex = tabbedPane.getSelectedIndex();
if (selectedIndex != 0) {
if (!syncPerformed) {
syncAction.run();
syncPerformed = true;
}
}
updateUiState();
}
private boolean performUpdateActions(final Runnable doneHandler) {
final ArrayList<ModuleItem> actionList = createActionList();
if (actionList.isEmpty()) {
doneHandler.run();
return true;
}
MissingDependencyInfo[] missingModuleDependencies = getMissingModuleDependencies();
if (missingModuleDependencies.length > 0) {
String missingModuleDependenciesMessage = createMissingModuleDependenciesMessage(missingModuleDependencies);
showErrorDialog(missingModuleDependenciesMessage);
return false;
}
String m = ModuleTextFactory.getActionListText(actionList);
int a = showOkCancelDialog(m);
if (a != JOptionPane.OK_OPTION) {
return false;
}
ActionPerformer performer = new ActionPerformer(actionList) {
@Override
protected void done() {
boolean success;
try {
try {
success = get();
} catch (InterruptedException e) {
showErrorDialog("Update action(s) failed:\n" + e.getMessage() + "\n" +
"No changes will be performed.\n" +
"Try running the software as administrator.");
return;
} catch (ExecutionException e) {
showErrorDialog("Update action(s) failed:\n" + e.getCause().getMessage() + "\n" +
"No changes will be performed.\n" +
"Try running the software as administrator.");
return;
}
if (success) {
showInfoDialog("Changes will be effective after restart.");
} else {
showErrorDialog("Update action(s) canceled.\n" +
"No changes will be performed.");
}
} finally {
doneHandler.run();
}
}
};
performer.execute();
return true;
}
private ArrayList<ModuleItem> createActionList() {
final ArrayList<ModuleItem> actionList = new ArrayList<>(10);
for (ModuleItem moduleItem : moduleManager.getInstalledModuleItems()) {
if (moduleItem.getAction() == ModuleItem.Action.UNINSTALL) {
actionList.add(moduleItem);
}
}
for (ModuleItem moduleItem : moduleManager.getUpdatableModuleItems()) {
if (moduleItem.getAction() == ModuleItem.Action.UPDATE) {
actionList.add(moduleItem);
}
}
for (ModuleItem moduleItem : moduleManager.getAvailableModuleItems()) {
if (moduleItem.getAction() == ModuleItem.Action.INSTALL) {
actionList.add(moduleItem);
}
}
return actionList;
}
private BasicSplitPaneUI createPlainDividerSplitPaneUI() {
return new BasicSplitPaneUI() {
@Override
public BasicSplitPaneDivider createDefaultDivider() {
return new BasicSplitPaneDivider(this) {
/**
* Overridden in order to do nothing (instead of painting an ugly default divider)
*
* @param g the graphics object
*/
@Override
public void paint(Graphics g) {
// do nothing
}
};
}
};
}
private JTable createModuleTable(ModuleTableModel dm) {
final JTable table = new JTable(dm);
table.getTableHeader().setReorderingAllowed(false);
table.getTableHeader().setResizingAllowed(true);
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
updateUiState();
}
}
});
table.addMouseListener(new MouseAdapter() {
private JPopupMenu popupMenu;
@Override
public void mouseClicked(MouseEvent e) {
checkPopup(e);
}
@Override
public void mousePressed(MouseEvent e) {
checkPopup(e);
}
@Override
public void mouseReleased(MouseEvent e) {
checkPopup(e);
}
private void checkPopup(final MouseEvent me) {
if (me.isPopupTrigger()) {
popupMenu = new JPopupMenu();
if (installAction.isEnabled()) {
popupMenu.add(installAction);
} else if (updateAction.isEnabled()) {
popupMenu.add(updateAction);
} else if (uninstallAction.isEnabled()) {
popupMenu.add(uninstallAction);
} else if (clearAction.isEnabled()) {
popupMenu.add(clearAction);
}
if (popupMenu.getComponentCount() > 0) {
popupMenu.addSeparator();
}
popupMenu.add(selectAllAction);
popupMenu.show(me.getComponent(), me.getX(), me.getY());
}
}
});
return table;
}
private void updateModuleTable() {
String filter = categories.getSelectedItem().toString();
installedModulesTableModel.setModuleItems(filterModuleItems(moduleManager.getInstalledModuleItems(), filter));
updatableModulesTableModel.setModuleItems(filterModuleItems(moduleManager.getUpdatableModuleItems(), filter));
availableModulesTableModel.setModuleItems(filterModuleItems(moduleManager.getAvailableModuleItems(), filter));
registerCategories(moduleManager.getAvailableModuleItems());
updateCategories();
}
static ModuleItem[] filterModuleItems(ModuleItem[] moduleItems, String filter) {
if (!filter.isEmpty()) {
ArrayList<ModuleItem> filteredModuleItems = new ArrayList<>(moduleItems.length);
for (ModuleItem moduleItem : moduleItems) {
if (matchesCategory(moduleItem, filter)) {
filteredModuleItems.add(moduleItem);
}
}
moduleItems = filteredModuleItems.toArray(new ModuleItem[filteredModuleItems.size()]);
}
Arrays.sort(moduleItems);
return moduleItems;
}
private static boolean matchesCategory(ModuleItem moduleItem, String filter) {
boolean found = false;
String filterLC = filter.toLowerCase();
String[] categories = moduleItem.getModule().getCategories();
for (String category : categories) {
if (category.toLowerCase().startsWith(filterLC)) {
found = true;
break;
}
}
return found;
}
protected static boolean isCategory(Module module, String category) {
String categoryLC = category.toLowerCase();
String[] categories = module.getCategories();
for (String someCategory : categories) {
if (someCategory.toLowerCase().contains(categoryLC)) {
return true;
}
}
return false;
}
private void updateCategories() {
categoriesSet.add(new CaselessKey(""));
CaselessKey[] keys = categoriesSet.toArray(new CaselessKey[categoriesSet.size()]);
Arrays.sort(keys);
Object selectedItem = categories.getSelectedItem().toString();
categories.setModel(new DefaultComboBoxModel<>(keys));
categories.setSelectedItem(selectedItem);
}
private void registerCategories(ModuleItem[] moduleItems) {
for (ModuleItem moduleItem : moduleItems) {
String[] categories = moduleItem.getModule().getCategories();
for (String category : categories) {
categoriesSet.add(new CaselessKey(category));
}
}
}
private int showOkCancelDialog(String m) {
return JOptionPane.showConfirmDialog(this, m, TITLE, JOptionPane.OK_CANCEL_OPTION,
JOptionPane.INFORMATION_MESSAGE);
}
private void showErrorDialog(String m) {
JOptionPane.showMessageDialog(this, m, TITLE, JOptionPane.ERROR_MESSAGE);
}
private void showInfoDialog(String m) {
JOptionPane.showMessageDialog(this, m, TITLE, JOptionPane.INFORMATION_MESSAGE);
}
private void updateUiState() {
boolean clearEnabled = false;
boolean installEnabled = false;
boolean updateEnabled = false;
boolean uninstallEnabled = false;
ModuleItem[] selectedModuleItems = getSelectedModuleItems();
if (selectedModuleItems.length != 0) {
installEnabled = true;
updateEnabled = true;
uninstallEnabled = true;
for (ModuleItem selectedModuleItem : selectedModuleItems) {
if (!selectedModuleItem.getAction().equals(ModuleItem.Action.NONE)) {
clearEnabled = true;
}
if (!isAvailableModule(selectedModuleItem)) {
installEnabled = false;
}
if (!isModuleUpdate(selectedModuleItem)) {
updateEnabled = false;
}
if (isAvailableModule(selectedModuleItem)
|| selectedModuleItem.getModule().getState().equals(ModuleState.UNINSTALLED)
|| isCategory(selectedModuleItem.getModule(), "System")) {
uninstallEnabled = false;
}
}
installEnabled = confirmActionEnabled(ModuleItem.Action.INSTALL, installEnabled);
updateEnabled = confirmActionEnabled(ModuleItem.Action.UPDATE, updateEnabled);
uninstallEnabled = confirmActionEnabled(ModuleItem.Action.UNINSTALL, uninstallEnabled);
}
clearAction.setEnabled(clearEnabled);
installAction.setEnabled(installEnabled);
updateAction.setEnabled(updateEnabled);
uninstallAction.setEnabled(uninstallEnabled);
syncAction.setEnabled(true);
infoPane.setSelectedModuleItems(getSelectedModuleItems());
}
private boolean confirmActionEnabled(ModuleItem.Action action, boolean enabled) {
if (enabled) {
enabled = false;
ModuleItem[] selectedModuleItems = getSelectedModuleItems();
for (ModuleItem moduleItem : selectedModuleItems) {
if (!moduleItem.getAction().equals(action)) {
return true;
}
}
}
return enabled;
}
private static boolean isAvailableModule(ModuleItem selectedModuleItem) {
return selectedModuleItem.getRepositoryModule() != null &&
selectedModuleItem.getModule() == selectedModuleItem.getRepositoryModule();
}
private static boolean isModuleUpdate(ModuleItem selectedModuleItem) {
return selectedModuleItem.getRepositoryModule() != null &&
selectedModuleItem.getModule() != selectedModuleItem.getRepositoryModule();
}
private ModuleItem[] getSelectedModuleItems() {
return getSelectedModuleItems(getSelectedTable());
}
private JTable getSelectedTable() {
int selectedIndex = tabbedPane.getSelectedIndex();
return modulesTables[selectedIndex];
}
private static ModuleItem[] getSelectedModuleItems(JTable table) {
final int[] rows = table.getSelectedRows();
ModuleItem[] moduleItems = new ModuleItem[rows.length];
for (int i = 0; i < rows.length; i++) {
int row = rows[i];
moduleItems[i] = ((ModuleTableModel) table.getModel()).getModuleItem(row);
}
return moduleItems;
}
private MissingDependencyInfo[] getMissingModuleDependencies() {
ConsistencyChecker consistencyChecker = new ConsistencyChecker(moduleManager);
consistencyChecker.check();
return consistencyChecker.getMissingDependencies();
}
private static String createMissingModuleDependenciesMessage(MissingDependencyInfo[] missingModuleDependencieses) {
StringBuilder sb = new StringBuilder(256);
sb.append("Inconsistent module set detected.\n\n");
int lineCount = 0;
for (MissingDependencyInfo missingModuleDependency : missingModuleDependencieses) {
Dependency dependency = missingModuleDependency.getDependency();
Module[] missingDependencyList = missingModuleDependency.getDependentModules();
sb.append(MessageFormat.format(
"Unresolved module [{0}], version {1} required by module(s)\n",
ModuleTextFactory.getText(dependency.getModuleSymbolicName()),
ModuleTextFactory.getText(dependency.getVersion())));
lineCount++;
for (Module module : missingDependencyList) {
sb.append("- ");
if (lineCount <= 8) {
sb.append(MessageFormat.format("{0} [{1}], version {2}\n",
ModuleTextFactory.getNameText(module),
ModuleTextFactory.getText(module.getSymbolicName()),
ModuleTextFactory.getVersionText(module)));
lineCount++;
} else {
sb.append("more...\n");
break;
}
}
}
sb.append("\n");
sb.append("Please check related install, update and uninstall actions.");
return sb.toString();
}
private void setActionId(ModuleItem.Action action) {
ModuleItem[] moduleItems = getSelectedModuleItems();
for (ModuleItem moduleItem : moduleItems) {
moduleItem.setAction(action);
}
onActionChanged();
}
private void onActionChanged() {
installedModulesTableModel.fireTableDataChanged();
updatableModulesTableModel.fireTableDataChanged();
availableModulesTableModel.fireTableDataChanged();
updateUiState();
}
private class SyncAction extends AbstractAction {
public SyncAction() {
putValue(ACTION_COMMAND_KEY, getClass().getName());
putValue(NAME, "Synchronize");
putValue(SHORT_DESCRIPTION, "Synchronize with remote repository");
putValue(LARGE_ICON_KEY, new ImageIcon(getClass().getResource("icons/system-software-update.png")));
}
public void actionPerformed(ActionEvent event) {
run();
}
public void run() {
new ModuleListDownloader().execute();
}
}
private class ClearAction extends AbstractAction {
public ClearAction() {
putValue(ACTION_COMMAND_KEY, getClass().getName());
putValue(NAME, "Clear");
putValue(MNEMONIC_KEY, (int) 'C');
putValue(SHORT_DESCRIPTION, "Clear a previous install, update or uninstall action");
putValue(SMALL_ICON, new ImageIcon(getClass().getResource("icons/edit-clear.png")));
putValue(LARGE_ICON_KEY, getValue(SMALL_ICON));
}
public void actionPerformed(ActionEvent e) {
setActionId(ModuleItem.Action.NONE);
}
}
private class InstallAction extends AbstractAction {
public InstallAction() {
putValue(ACTION_COMMAND_KEY, getClass().getName());
putValue(NAME, "Install");
putValue(MNEMONIC_KEY, (int) 'I');
putValue(SHORT_DESCRIPTION, "Install the selected modules");
putValue(SMALL_ICON, new ImageIcon(getClass().getResource("icons/list-add.png")));
putValue(LARGE_ICON_KEY, getValue(SMALL_ICON));
}
public void actionPerformed(ActionEvent e) {
setActionId(ModuleItem.Action.INSTALL);
}
}
private class UpdateAction extends AbstractAction {
public UpdateAction() {
putValue(ACTION_COMMAND_KEY, getClass().getName());
putValue(NAME, "Update");
putValue(MNEMONIC_KEY, (int) 'U');
putValue(SHORT_DESCRIPTION, "Update selected modules");
putValue(SMALL_ICON, new ImageIcon(getClass().getResource("icons/view-refresh.png")));
putValue(LARGE_ICON_KEY, getValue(SMALL_ICON));
}
public void actionPerformed(ActionEvent e) {
setActionId(ModuleItem.Action.UPDATE);
}
}
private class UninstallAction extends AbstractAction {
public UninstallAction() {
putValue(ACTION_COMMAND_KEY, getClass().getName());
putValue(NAME, "Uninstall");
putValue(MNEMONIC_KEY, (int) 'N');
putValue(SHORT_DESCRIPTION, "Uninstall selected modules");
putValue(SMALL_ICON, new ImageIcon(getClass().getResource("icons/list-remove.png")));
putValue(LARGE_ICON_KEY, getValue(SMALL_ICON));
}
public void actionPerformed(ActionEvent e) {
setActionId(ModuleItem.Action.UNINSTALL);
}
}
private class SelectAllAction extends AbstractAction {
public SelectAllAction() {
putValue(ACTION_COMMAND_KEY, getClass().getName());
putValue(NAME, "Select All");
putValue(MNEMONIC_KEY, (int) 'A');
putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl A"));
putValue(SHORT_DESCRIPTION, "Select all items in table");
putValue(SMALL_ICON, new ImageIcon(getClass().getResource("icons/edit-select-all.png")));
putValue(LARGE_ICON_KEY, getValue(SMALL_ICON));
}
public void actionPerformed(ActionEvent ae) {
getSelectedTable().selectAll();
}
}
private class ModuleListDownloader extends ProgressMonitorSwingWorker<Void, Void> {
public ModuleListDownloader() {
super(ModuleManagerPane.this, TITLE);
}
@Override
protected Void doInBackground(com.bc.ceres.core.ProgressMonitor pm) throws Exception {
moduleManager.synchronizeWithRepository(pm);
return null;
}
@Override
protected void done() {
if (isCancelled()) {
return;
}
try {
get(); // just to know if download succeded
} catch (InterruptedException e) {
handleRepositoryConnectionFailed(e.getMessage());
return;
} catch (ExecutionException e) {
handleRepositoryConnectionFailed(e.getCause().getMessage());
return;
}
updateModuleTable();
updateUiState();
}
}
private void handleRepositoryConnectionFailed(String message) {
String m = MessageFormat.format("Failed to download module list from module repository:\n{0}\n\n{1}",
message,
getRepositoryTroubleShootingMessage());
showErrorDialog(m);
}
static class MissingModuleDependency {
Dependency dependency;
List<Module> modules = new ArrayList<>(10);
public MissingModuleDependency(Dependency dependency) {
this.dependency = dependency;
}
}
private class ActionPerformer extends ProgressMonitorSwingWorker<Boolean, Boolean> {
private final List<ModuleItem> actionListList;
public ActionPerformer(List<ModuleItem> actionListList) {
super(ModuleManagerPane.this, TITLE);
this.actionListList = actionListList;
}
@Override
protected Boolean doInBackground(com.bc.ceres.core.ProgressMonitor pm) throws Exception {
pm.beginTask("Performing update actions", actionListList.size());
try {
moduleManager.startTransaction();
for (ModuleItem actionItem : actionListList) {
String actionText = ModuleTextFactory.getActionItemText(actionItem);
pm.setTaskName(actionText);
if (actionItem.getAction() == ModuleItem.Action.INSTALL) {
moduleManager.installModule(actionItem.getRepositoryModule(),
SubProgressMonitor.create(pm, 1));
} else if (actionItem.getAction() == ModuleItem.Action.UPDATE) {
moduleManager.updateModule(actionItem.getModule(),
actionItem.getRepositoryModule(),
SubProgressMonitor.create(pm, 1));
} else if (actionItem.getAction() == ModuleItem.Action.UNINSTALL) {
moduleManager.uninstallModule(actionItem.getModule(),
SubProgressMonitor.create(pm, 1));
}
if (pm.isCanceled()) {
throw new CanceledException();
}
}
} catch (CoreException e) {
moduleManager.rollbackTransaction();
throw e;
} finally {
pm.done();
}
moduleManager.endTransaction();
return true;
}
}
public static interface HelpHandler {
void configureHelpButton(JButton helpButton);
}
}