/* * RapidMiner * * Copyright (C) 2001-2014 by RapidMiner and the contributors * * Complete list of developers available at our web site: * * http://rapidminer.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ package com.rapid_i.deployment.update.client; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.logging.Level; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.border.EmptyBorder; import javax.swing.border.EtchedBorder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import com.rapid_i.deployment.update.client.listmodels.AbstractPackageListModel; import com.rapidminer.deployment.client.wsimport.PackageDescriptor; import com.rapidminer.deployment.client.wsimport.UpdateService; import com.rapidminer.gui.RapidMinerGUI; import com.rapidminer.gui.tools.ExtendedJScrollPane; import com.rapidminer.gui.tools.ProgressThread; import com.rapidminer.gui.tools.ResourceAction; import com.rapidminer.gui.tools.SwingTools; import com.rapidminer.gui.tools.dialogs.ButtonDialog; import com.rapidminer.gui.tools.dialogs.ConfirmDialog; import com.rapidminer.io.process.XMLTools; import com.rapidminer.tools.FileSystemService; import com.rapidminer.tools.I18N; import com.rapidminer.tools.LogService; import com.rapidminer.tools.ParameterService; import com.rapidminer.tools.XMLException; /** * The Dialog is eventually shown at the start of RapidMiner, if the user purchased extensions online but haven't installed them yet. * * @author Dominik Halfkann */ public class PendingPurchasesInstallationDialog extends ButtonDialog { private static final long serialVersionUID = 1L; private final PackageDescriptorCache packageDescriptorCache = new PackageDescriptorCache(); private AbstractPackageListModel purchasedModel = new PurchasedNotInstalledModel(packageDescriptorCache); JCheckBox neverAskAgain = new JCheckBox(I18N.getMessage(I18N.getGUIBundle(), "gui.dialog.purchased_not_installed.not_check_on_startup")); private final List<String> packages; private boolean isConfirmed; private LinkedList<PackageDescriptor> installablePackageList; private JButton remindNeverButton; private JButton remindLaterButton; private JButton okButton; private class PurchasedNotInstalledModel extends AbstractPackageListModel { private static final long serialVersionUID = 1L; public PurchasedNotInstalledModel(PackageDescriptorCache cache) { super(cache, "gui.dialog.update.tab.no_packages"); } @Override public List<String> handleFetchPackageNames() { return packages; } } public PendingPurchasesInstallationDialog(List<String> packages) { super("purchased_not_installed"); this.packages = packages; remindNeverButton = remindNeverButton(); remindLaterButton = remindLaterButton(); okButton = makeOkButton("install_purchased"); layoutDefault(makeContentPanel(), NORMAL, okButton, remindNeverButton, remindLaterButton); this.setPreferredSize(new Dimension(404, 430)); this.setMaximumSize(new Dimension(404, 430)); this.setMinimumSize(new Dimension(404, 300)); this.setSize(new Dimension(404, 430)); } private JPanel makeContentPanel() { BorderLayout layout = new BorderLayout(12, 12); JPanel panel = new JPanel(layout); panel.setBorder(new EmptyBorder(0, 12, 8, 12)); panel.add(createExtensionListScrollPane(purchasedModel), BorderLayout.CENTER); purchasedModel.update(); JPanel southPanel = new JPanel(new BorderLayout(0, 7)); JLabel question = new JLabel(I18N.getMessage(I18N.getGUIBundle(), "gui.dialog.purchased_not_installed.should_install")); southPanel.add(question, BorderLayout.CENTER); southPanel.add(neverAskAgain, BorderLayout.SOUTH); panel.add(southPanel, BorderLayout.SOUTH); return panel; } private JScrollPane createExtensionListScrollPane(AbstractPackageListModel model) { final JList updateList = new JList(model); updateList.setCellRenderer(new UpdateListCellRenderer(true)); JScrollPane extensionListScrollPane = new ExtendedJScrollPane(updateList); extensionListScrollPane.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)); return extensionListScrollPane; } private JButton remindLaterButton() { Action Action = new ResourceAction("ask_later") { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { wasConfirmed = false; checkNeverAskAgain(); close(); } }; getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false), "CLOSE"); getRootPane().getActionMap().put("CLOSE", Action); JButton button = new JButton(Action); getRootPane().setDefaultButton(button); return button; } private JButton remindNeverButton() { Action Action = new ResourceAction("ask_never") { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent e) { wasConfirmed = false; checkNeverAskAgain(); neverRemindAgain(); close(); } }; JButton button = new JButton(Action); getRootPane().setDefaultButton(button); return button; } @Override protected void ok() { checkNeverAskAgain(); startUpdate(getPackageDescriptorList()); dispose(); } public List<PackageDescriptor> getPackageDescriptorList() { List<PackageDescriptor> packageList = new ArrayList<PackageDescriptor>(); for (int a = 0; a < purchasedModel.getSize(); a++) { Object listItem = purchasedModel.getElementAt(a); if (listItem instanceof PackageDescriptor) { packageList.add((PackageDescriptor) listItem); } } return packageList; } public void startUpdate(final List<PackageDescriptor> downloadList) { final UpdateService service; try { service = UpdateManager.getService(); } catch (Exception e) { SwingTools.showSimpleErrorMessage("failed_update_server", e, UpdateManager.getBaseUrl()); return; } new ProgressThread("resolving_dependencies", true) { @Override public void run() { try { getProgressListener().setTotal(100); remindLaterButton.setEnabled(false); remindNeverButton.setEnabled(false); final HashMap<PackageDescriptor, HashSet<PackageDescriptor>> dependency = UpdateDialog.resolveDependency(downloadList, packageDescriptorCache); getProgressListener().setCompleted(30); installablePackageList = UpdateDialog.getPackagesforInstallation(dependency); final HashMap<String, String> licenseNameToLicenseTextMap = UpdateDialog.collectLicenses(installablePackageList,getProgressListener(),100,30,100); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { isConfirmed = ConfirmLicensesDialog.confirm(dependency, licenseNameToLicenseTextMap); new ProgressThread("installing_updates", true) { @Override public void run() { try { if (isConfirmed) { getProgressListener().setTotal(100); getProgressListener().setCompleted(20); UpdateService service = UpdateManager.getService(); UpdateManager um = new UpdateManager(service); List<PackageDescriptor> installedPackages = um.performUpdates(installablePackageList, getProgressListener()); getProgressListener().setCompleted(40); if (installedPackages.size() > 0) { int confirmation = SwingTools.showConfirmDialog((installedPackages.size() == 1 ? "update.complete_restart" : "update.complete_restart1"), ConfirmDialog.YES_NO_OPTION, installedPackages.size()); if (confirmation == ConfirmDialog.YES_OPTION) { RapidMinerGUI.getMainFrame().exit(true); } else if (confirmation == ConfirmDialog.NO_OPTION) { if (installedPackages.size() == installablePackageList.size()) { dispose(); } } } getProgressListener().complete(); } } catch (Exception e) { SwingTools.showSimpleErrorMessage("error_installing_update", e, e.getMessage()); } finally { getProgressListener().complete(); } } }.start(); } }); remindLaterButton.setEnabled(true); remindNeverButton.setEnabled(true); getProgressListener().complete(); } catch (Exception e) { SwingTools.showSimpleErrorMessage("error_resolving_dependencies", e, e.getMessage()); } } }.start(); } private void checkNeverAskAgain() { if (neverAskAgain.isSelected()) { ParameterService.setParameterValue(RapidMinerGUI.PROPERTY_RAPIDMINER_GUI_PURCHASED_NOT_INSTALLED_CHECK, "false"); ParameterService.saveParameters(); } } private void neverRemindAgain() { LogService.getRoot().log(Level.CONFIG, "com.rapid_i.deployment.update.client.PurchasedNotInstalledDialog.saving_ignored_extensions_file"); Document doc; try { doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); } catch (ParserConfigurationException e) { LogService.getRoot().log(Level.WARNING, I18N.getMessage(LogService.getRoot().getResourceBundle(), "com.rapid_i.deployment.update.client.PurchasedNotInstalledDialog.creating_xml_document_error", e), e); return; } Element root = doc.createElement(UpdateManager.NEVER_REMIND_INSTALL_EXTENSIONS_FILE_NAME); doc.appendChild(root); for (String i : purchasedModel.fetchPackageNames()) { Element entryElem = doc.createElement("extension_name"); entryElem.setTextContent(i); root.appendChild(entryElem); } File file = FileSystemService.getUserConfigFile(UpdateManager.NEVER_REMIND_INSTALL_EXTENSIONS_FILE_NAME); try { XMLTools.stream(doc, file, null); } catch (XMLException e) { LogService.getRoot().log(Level.WARNING, I18N.getMessage(LogService.getRoot().getResourceBundle(), "com.rapid_i.deployment.update.client.PurchasedNotInstalledDialog.saving_ignored_extensions_file_error", e), e); } } }