@@ -641,7 +641,7 @@
c.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(ModuleBean.class, "ACSD_TITLE_disabling"));
NotifyDescriptor d = new NotifyDescriptor.Confirmation(c,
NbBundle.getMessage(ModuleBean.class, "MB_TITLE_disabling"),
- NotifyDescriptor.OK_CANCEL_OPTION);
+ cancelable ? NotifyDescriptor.OK_CANCEL_OPTION : NotifyDescriptor.DEFAULT_OPTION);
if (org.openide.DialogDisplayer.getDefault().notify(d) != NotifyDescriptor.OK_OPTION) {
// User refused.
// Fire changes again since modules are now wrong & need recalc.
@@ -778,7 +778,7 @@
// Hmm, too complicated to deal with now. Skip it.
continue;
}
- doDisable(Collections.singleton(old));
+ doDisable(Collections.singleton(old), true);
if (old.isEnabled()) {
// Did not work for some reason, skip it.
continue;
Index: core/src/org/netbeans/core/ui/ModuleNode.java
===================================================================
RCS file: /cvs/core/src/org/netbeans/core/ui/ModuleNode.java,v
--- core/src/org/netbeans/core/ui/ModuleNode.java 30 Mar 2005 21:54:04 -0000 1.36
+++ core/src/org/netbeans/core/ui/ModuleNode.java 26 May 2005 14:37:36 -0000
@@ -43,6 +43,7 @@
import javax.swing.KeyStroke;
import javax.swing.AbstractAction;
import org.netbeans.core.IDESettings;
+import org.netbeans.core.modules.ModuleDeleter;
import org.openide.ErrorManager;
import org.openide.actions.DeleteAction;
import org.openide.actions.NewAction;
@@ -332,10 +333,25 @@
}
public void destroy () {
- item.delete();
+ ModuleDeleter deleter = getModuleDeleter ();
+ if (deleter != null && deleter.canDelete (item.getModule ())) {
+ try {
+ deleter.delete (item.getModule ());
+ } catch (IOException ioe) {
+ ErrorManager.getDefault ().notify (ErrorManager.USER, ioe);
+ }
+ } else {
+ item.delete();
+ }
}
public boolean canDestroy () {
+ ModuleDeleter deleter = getModuleDeleter ();
+ if (deleter != null) {
+ if (deleter.canDelete (item.getModule ())) {
+ return true;
+ }
+ }
return item.getJar() != null;
}
@@ -1035,4 +1051,14 @@
return ModuleBean.AllModulesBean.getDefault();
}
+ private static ModuleDeleter getModuleDeleter () {
+ ModuleDeleter deleter = (ModuleDeleter) Lookup.getDefault ().lookup (ModuleDeleter.class);
+ if (deleter != null) {
+ return deleter;
+ } else {
+ assert false : "Any ModuleDeleter should exist.";
+ return null;
+ }
+ }
+
}
Index: core/src/org/netbeans/core/ui/ModuleSelectionPanel.form
===================================================================
RCS file: core/src/org/netbeans/core/ui/ModuleSelectionPanel.form
--- core/src/org/netbeans/core/ui/ModuleSelectionPanel.form 5 Mar 2004 14:25:31 -0000 1.9
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,92 +0,0 @@
-
-
-
Index: core/src/org/netbeans/core/ui/ModuleSelectionPanel.java
===================================================================
RCS file: core/src/org/netbeans/core/ui/ModuleSelectionPanel.java
--- core/src/org/netbeans/core/ui/ModuleSelectionPanel.java 5 Mar 2004 14:25:31 -0000 1.23
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,324 +0,0 @@
-/*
- * Sun Public License Notice
- *
- * The contents of this file are subject to the Sun Public License
- * Version 1.0 (the "License"). You may not use this file except in
- * compliance with the License. A copy of the License is available at
- * http://www.sun.com/
- *
- * The Original Code is NetBeans. The Initial Developer of the Original
- * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
- * Microsystems, Inc. All Rights Reserved.
- */
-
-package org.netbeans.core.ui;
-
-import javax.swing.UIManager;
-import javax.swing.plaf.basic.BasicBorders;
-
-import javax.swing.UIManager;
-import javax.swing.border.Border;
-
-import javax.swing.*;
-import javax.swing.event.*;
-import java.util.*;
-import java.awt.*;
-import java.awt.Font;
-import java.awt.font.LineMetrics;
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeEvent;
-
-import org.openide.WizardDescriptor;
-import org.openide.nodes.*;
-import org.openide.util.NbBundle;
-import org.openide.explorer.ExplorerManager;
-import org.openide.cookies.InstanceCookie;
-import java.io.IOException;
-
-/** Module selection panel allows user to enable/disable modules in setup wizard
- *
- * @author cledantec, jrojcek, Jesse Glick
- */
-public class ModuleSelectionPanel extends javax.swing.JPanel
- implements PropertyChangeListener {
-
- /** See org.openide.WizardDescriptor.PROP_CONTENT_SELECTED_INDEX
- */
- private static final String PROP_CONTENT_SELECTED_INDEX = "WizardPanel_contentSelectedIndex"; // NOI18N
- /** See org.openide.WizardDescriptor.PROP_CONTENT_DATA
- */
- private static final String PROP_CONTENT_DATA = "WizardPanel_contentData"; // NOI18N
-
- // SetupWizard has to load it eagerly too, so no harm here.
- private final ModuleBean.AllModulesBean allModules = ModuleBean.AllModulesBean.getDefault();
-
- /** default size values */
- private static final int DEF_TREE_WIDTH = 320;
- private static final int DEF_0_COL_WIDTH = 60;
- private static final int DEF_1_COL_WIDTH = 150;
- private static final int DEF_HEIGHT = 250;
-
- /** Creates new form wizardFrame */
- public ModuleSelectionPanel() {
- putClientProperty(PROP_CONTENT_SELECTED_INDEX, new Integer(0));
- String name = NbBundle.getMessage(ModuleSelectionPanel.class, "LBL_SetupWizardModuleInstallation");
- putClientProperty(PROP_CONTENT_DATA, new String[] { name });
- setName(name);
- }
-
-
-
- /** Avoid initializing GUI, and allModules, until needed. */
- public void addNotify() {
- super.addNotify();
- if (treeTableView != null) return;
- synchronized (getTreeLock()) {
-
- initComponents();
-
- treeTableView.setProperties(
- new Node.Property[]{
- new PropertySupport.ReadWrite (
- "enabled", // NOI18N
- Boolean.TYPE,
- org.openide.util.NbBundle.getMessage (ModuleNode.class, "PROP_modules_enabled"),
- org.openide.util.NbBundle.getMessage (ModuleNode.class, "HINT_modules_enabled")
- ) {
- public Object getValue () {
- return null;
- }
-
- public void setValue (Object o) {
- }
- },
- new PropertySupport.ReadOnly (
- "specificationVersion", // NOI18N
- String.class,
- org.openide.util.NbBundle.getMessage (ModuleNode.class, "PROP_modules_specversion"),
- org.openide.util.NbBundle.getMessage (ModuleNode.class, "HINT_modules_specversion")
- ) {
- public Object getValue () {
- return null;
- }
- }
- }
- );
- //Fix for NPE on WinXP L&F - either may be null - Tim
- Font f = UIManager.getFont("controlFont");
- Integer i = (Integer) UIManager.get("nbDefaultFontSize");
- if (i == null) {
- i = new Integer(11); //fudge the default if not present
- }
- if (f == null) {
- f = getFont();
- }
-
- // perform additional preferred size computations for larger fonts
- if (f.getSize() > i.intValue()) { // NOI18N
- sizeTTVCarefully();
- } else {
- // direct sizing for default situation
- treeTableView.setPreferredSize(
- new Dimension (DEF_1_COL_WIDTH + DEF_0_COL_WIDTH + DEF_TREE_WIDTH,
- DEF_HEIGHT)
- );
- treeTableView.setTreePreferredWidth(DEF_TREE_WIDTH);
- treeTableView.setTableColumnPreferredWidth(0, DEF_0_COL_WIDTH);
- treeTableView.setTableColumnPreferredWidth(1, DEF_1_COL_WIDTH);
- }
- treeTableView.setPopupAllowed(false);
- treeTableView.setDefaultActionAllowed(false);
-
- // install proper border
- treeTableView.setBorder((Border)UIManager.get("Nb.ScrollPane.border")); // NOI18N
-
- manager = explorerPanel.getExplorerManager();
- ModuleNode node = new ModuleNode(true);
- manager.setRootContext(node);
-
- initAccessibility();
- }
- }
-
- /** Computes and sets right preferred sizes of TTV columns.
- * Sizes of columns are computed as maximum of default values and
- * header text length. Size of tree is aproximate, grows linearly with
- * font size.
- */
- private void sizeTTVCarefully () {
- Font headerFont = (Font)UIManager.getDefaults().get("TableHeader.font"); // NOI18N
- Font tableFont = (Font)UIManager.getDefaults().get("Table.font"); // NOI18N
- FontMetrics headerFm = getFontMetrics(headerFont);
-
- int enabledColWidth = Math.max(DEF_0_COL_WIDTH, headerFm.stringWidth(
- NbBundle.getMessage (ModuleNode.class, "PROP_modules_enabled")) + 20
- );
- int specColWidth = Math.max(DEF_1_COL_WIDTH, headerFm.stringWidth(
- NbBundle.getMessage (ModuleNode.class, "PROP_modules_specversion")) + 20
- );
- int defFontSize = UIManager.getDefaults().getInt("nbDefaultFontSize");
- int treeWidth = DEF_TREE_WIDTH + 10 * (tableFont.getSize() - defFontSize);
-
- treeTableView.setPreferredSize(
- new Dimension (treeWidth + enabledColWidth + specColWidth,
- DEF_HEIGHT + 10 * (tableFont.getSize() - defFontSize))
- );
- treeTableView.setTreePreferredWidth(treeWidth);
- treeTableView.setTableColumnPreferredWidth(0, enabledColWidth);
- treeTableView.setTableColumnPreferredWidth(1, specColWidth);
- }
-
- /** This method is called from within the constructor to
- * initialize the form.
- * WARNING: Do NOT modify this code. The content of this method is
- * always regenerated by the Form Editor.
- */
- private void initComponents() {//GEN-BEGIN:initComponents
- java.awt.GridBagConstraints gridBagConstraints;
-
- tableLabel = new javax.swing.JLabel();
- explorerPanel = new org.openide.explorer.ExplorerPanel();
- treeTableView = new org.openide.explorer.view.TreeTableView();
- descriptionLabel = new javax.swing.JLabel();
- descriptionPane = new javax.swing.JScrollPane();
- descriptionArea = new javax.swing.JTextArea();
-
- setLayout(new java.awt.GridBagLayout());
-
- setName(NbBundle.getMessage(ModuleSelectionPanel.class, "LBL_SetupWizardModuleInstallation"));
- tableLabel.setLabelFor(treeTableView);
- tableLabel.setText(NbBundle.getMessage(ModuleSelectionPanel.class, "LBL_SetupWizardCheckModules"));
- gridBagConstraints = new java.awt.GridBagConstraints();
- gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
- gridBagConstraints.insets = new java.awt.Insets(0, 1, 5, 0);
- add(tableLabel, gridBagConstraints);
-
- explorerPanel.add(treeTableView, java.awt.BorderLayout.CENTER);
-
- gridBagConstraints = new java.awt.GridBagConstraints();
- gridBagConstraints.gridx = 0;
- gridBagConstraints.gridy = 1;
- gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
- gridBagConstraints.weightx = 1.0;
- gridBagConstraints.weighty = 1.0;
- gridBagConstraints.insets = new java.awt.Insets(0, 0, 11, 0);
- add(explorerPanel, gridBagConstraints);
-
- descriptionLabel.setLabelFor(descriptionArea);
- descriptionLabel.setText(NbBundle.getMessage(ModuleSelectionPanel.class, "LBL_SetupWizardDescription"));
- gridBagConstraints = new java.awt.GridBagConstraints();
- gridBagConstraints.gridx = 0;
- gridBagConstraints.gridy = 2;
- gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
- gridBagConstraints.insets = new java.awt.Insets(0, 1, 5, 0);
- add(descriptionLabel, gridBagConstraints);
-
- descriptionPane.setMinimumSize(new java.awt.Dimension(22, 80));
- descriptionPane.setPreferredSize(new java.awt.Dimension(50, 80));
- descriptionArea.setEditable(false);
- descriptionArea.setLineWrap(true);
- descriptionArea.setWrapStyleWord(true);
- descriptionPane.setViewportView(descriptionArea);
-
- gridBagConstraints = new java.awt.GridBagConstraints();
- gridBagConstraints.gridx = 0;
- gridBagConstraints.gridy = 3;
- gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
- add(descriptionPane, gridBagConstraints);
-
- }//GEN-END:initComponents
-
- private void prevButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prevButtonActionPerformed
- // Add your handling code here:
- }//GEN-LAST:event_prevButtonActionPerformed
-
- // Variables declaration - do not modify//GEN-BEGIN:variables
- private javax.swing.JTextArea descriptionArea;
- private javax.swing.JLabel descriptionLabel;
- private javax.swing.JScrollPane descriptionPane;
- private org.openide.explorer.ExplorerPanel explorerPanel;
- private javax.swing.JLabel tableLabel;
- private org.openide.explorer.view.TreeTableView treeTableView;
- // End of variables declaration//GEN-END:variables
-
- private ExplorerManager manager;
-
- /** Handling of property changes in node structure and setup wizard descriptor
- */
- public void propertyChange(PropertyChangeEvent evt) {
- if ((evt.getSource() == manager)
- && (manager.PROP_SELECTED_NODES.equals(evt.getPropertyName()))) {
-
- Node[] nodes = manager.getSelectedNodes();
- String text = ""; // NOI18N
- if (nodes.length == 1) {
- InstanceCookie inst = (InstanceCookie)nodes[0].getCookie(InstanceCookie.class);
- if (inst != null) {
- try {
- if (inst.instanceClass() == ModuleBean.class) {
- ModuleBean bean = (ModuleBean)inst.instanceCreate();
- text = bean.getLongDescription();
- }
- } catch (IOException ioe) {
- // ignore
- } catch (ClassNotFoundException cnfe) {
- // ignore
- }
- }
- }
- descriptionArea.setText(text);
- descriptionArea.setCaretPosition(0);
- } else if ((evt.getSource() instanceof WizardDescriptor)
- && (WizardDescriptor.PROP_VALUE.equals(evt.getPropertyName()))) {
-
- WizardDescriptor wd = (WizardDescriptor)evt.getSource();
- if ((wd.getValue() == wd.CANCEL_OPTION) || (wd.getValue() == wd.CLOSED_OPTION)) {
- wd.removePropertyChangeListener(this);
- allModules.cancel();
- } else if (wd.getValue() == wd.FINISH_OPTION) {
- wd.removePropertyChangeListener(this);
- allModules.resume();
- }
- }
- }
-
-
- /** Initialize accesibility
- */
- public void initAccessibility(){
-
- java.util.ResourceBundle b = NbBundle.getBundle(this.getClass());
-
- this.getAccessibleContext().setAccessibleDescription(b.getString("ACSD_ModuleSelectionPanel"));
-
- tableLabel.setDisplayedMnemonic(b.getString("LBL_SetupWizardCheckModules_MNE").charAt(0));
- tableLabel.getAccessibleContext().setAccessibleDescription(b.getString("ACSD_tableLabel"));
-
- descriptionLabel.setDisplayedMnemonic(b.getString("LBL_SetupWizardDescription_MNE").charAt(0));
- descriptionLabel.getAccessibleContext().setAccessibleDescription(b.getString("ACSD_descriptionLabel"));
- }
-
- public void initFromSettings(Object settings) {
- if (settings instanceof WizardDescriptor) {
- ((WizardDescriptor)settings).addPropertyChangeListener(this);
- }
- addNotify();
- manager.addPropertyChangeListener(this);
- allModules.pause();
-
- }
- /** Provides the wizard panel with the opportunity to update the
- * settings with its current customized state.
- * Rather than updating its settings with every change in the GUI, it should collect them,
- * and then only save them when requested to by this method.
- * Also, the original settings passed to {@link #readSettings} should not be modified (mutated);
- * rather, the (copy) passed in here should be mutated according to the collected changes.
- * This method can be called multiple times on one instance of WizardDescriptor.Panel
.
- * @param settings the object representing a settings of the wizard
- */
- public void storeSettings (Object settings) {
- manager.removePropertyChangeListener(this);
- }
-
-
-}
Index: core/src/org/netbeans/core/ui/ModuleSelectionWizardPanel.java
===================================================================
RCS file: core/src/org/netbeans/core/ui/ModuleSelectionWizardPanel.java
--- core/src/org/netbeans/core/ui/ModuleSelectionWizardPanel.java 3 Sep 2004 14:03:06 -0000 1.3
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,105 +0,0 @@
-/*
- * Sun Public License Notice
- *
- * The contents of this file are subject to the Sun Public License
- * Version 1.0 (the "License"). You may not use this file except in
- * compliance with the License. A copy of the License is available at
- * http://www.sun.com/
- *
- * The Original Code is NetBeans. The Initial Developer of the Original
- * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
- * Microsystems, Inc. All Rights Reserved.
- */
-
-package org.netbeans.core.ui;
-
-import java.awt.Component;
-import javax.swing.event.ChangeListener;
-
-import org.openide.WizardDescriptor;
-import org.openide.util.HelpCtx;
-
-/** Module selection panel allows user to enable/disable modules in setup wizard
- *
- * @author Vincent Brabant, cledantec, jrojcek, Jesse Glick
- */
-public class ModuleSelectionWizardPanel implements WizardDescriptor.FinishPanel {
-
- /** aggregation, instance of UI component of this wizard panel */
- private ModuleSelectionPanel panelUI;
-
- /** Creates new form wizardFrame */
- public ModuleSelectionWizardPanel() {
- }
-
- /** Get the component displayed in this panel.
- * @return the component
- */
- public Component getComponent () {
- return getPanelUI();
- }
-
- /** Help for this panel.
- * When the panel is active, this is used as the help for the wizard dialog.
- * @return the help or null
if no help is supplied
- */
- public HelpCtx getHelp () {
- // #44551 - remove help Id
- //return new HelpCtx("setupwizard.moduleselection"); // NOI18N
- return null;
- }
-
- /** Provides the wizard panel with the current data--either
- * the default data or already-modified settings, if the user used the previous and/or next buttons.
- * This method can be called multiple times on one instance of WizardDescriptor.Panel
.
- * @param settings the object representing wizard panel state, as originally supplied to
- * {@link WizardDescriptor#WizardDescriptor(WizardDescriptor.Iterator,Object)}
- */
-
- public void readSettings (Object settings) {
- panelUI.initFromSettings(settings);
- }
-
- /** Provides the wizard panel with the opportunity to update the
- * settings with its current customized state.
- * Rather than updating its settings with every change in the GUI, it should collect them,
- * and then only save them when requested to by this method.
- * Also, the original settings passed to {@link #readSettings} should not be modified (mutated);
- * rather, the (copy) passed in here should be mutated according to the collected changes.
- * This method can be called multiple times on one instance of WizardDescriptor.Panel
.
- * @param settings the object representing a settings of the wizard
- */
- public void storeSettings (Object settings) {
- panelUI.storeSettings(settings);
- }
-
- /** Test whether the panel is finished and it is safe to proceed to the next one.
- * If the panel is valid, the "Next" (or "Finish") button will be enabled.
- * @return true
if the user has entered satisfactory information
- */
- public boolean isValid () {
- return true;
- }
-
- /** Add a listener to changes of the panel's validity.
- * @param l the listener to add
- * @see #isValid
- */
- public void addChangeListener (ChangeListener l) {
- }
-
- /** Remove a listener to changes of the panel's validity.
- * @param l the listener to remove
- */
- public void removeChangeListener (ChangeListener l) {
- }
-
- /** Accessor for UI component */
- private ModuleSelectionPanel getPanelUI() {
- if (panelUI == null) {
- panelUI = new ModuleSelectionPanel();
- }
- return panelUI;
- }
-
-}
Index: core/ui/src/org/netbeans/core/ui/resources/layer.xml
===================================================================
RCS file: /cvs/core/ui/src/org/netbeans/core/ui/resources/layer.xml,v
--- core/ui/src/org/netbeans/core/ui/resources/layer.xml 12 May 2005 23:36:09 -0000 1.91
+++ core/ui/src/org/netbeans/core/ui/resources/layer.xml 25 May 2005 14:08:33 -0000
@@ -400,7 +400,6 @@
-
Index: autoupdate/libsrc/org/netbeans/updater/UpdateTracking.java
===================================================================
RCS file: /cvs/autoupdate/libsrc/org/netbeans/updater/UpdateTracking.java,v
--- autoupdate/libsrc/org/netbeans/updater/UpdateTracking.java 16 Mar 2005 14:45:12 -0000 1.18
+++ autoupdate/libsrc/org/netbeans/updater/UpdateTracking.java 22 May 2005 08:25:46 -0000
@@ -46,6 +46,7 @@
private static final String ATTR_CRC = "crc"; // NOI18N
private static final String NBM_ORIGIN = "nbm"; // NOI18N
+ // XXX: used also in org.netbeans.modules.autoupate.ModuleDeleterImpl
private static final String INST_ORIGIN = "updater"; // NOI18N
/** Platform dependent file name separator */
Index: autoupdate/src/META-INF/services/org.netbeans.core.modules.ModuleDeleter
===================================================================
RCS file: autoupdate/src/META-INF/services/org.netbeans.core.modules.ModuleDeleter
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ autoupdate/src/META-INF/services/org.netbeans.core.modules.ModuleDeleter 22 May 2005 08:25:47 -0000
@@ -0,0 +1, @@
+org.netbeans.modules.autoupdate.ModuleDeleterImpl
Index: autoupdate/src/org/netbeans/modules/autoupdate/ModuleDeleterImpl.java
===================================================================
RCS file: autoupdate/src/org/netbeans/modules/autoupdate/ModuleDeleterImpl.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ autoupdate/src/org/netbeans/modules/autoupdate/ModuleDeleterImpl.java 26 May 2005 15:15:36 -0000
@@ -0,0 +1,279 @@
+/*
+ * Sun Public License Notice
+ *
+ * The contents of this file are subject to the Sun Public License
+ * Version 1.0 (the "License"). You may not use this file except in
+ * compliance with the License. A copy of the License is available at
+ * http://www.sun.com/
+ *
+ * The Original Code is NetBeans. The Initial Developer of the Original
+ * Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ */
+
+package org.netbeans.modules.autoupdate;
+
+import org.netbeans.core.modules.Module;
+import org.netbeans.core.modules.ModuleDeleter;
+import org.openide.filesystems.FileUtil;
+import org.openide.modules.InstalledFileLocator;
+import org.openide.util.RequestProcessor;
+import org.openide.xml.XMLUtil;
+import org.openide.ErrorManager;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.Repository;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+
+/** Control if the module's file can be deleted and can delete them from disk.
+ * Deletes all files what are installed together with given module, info about
+ * these files read from update_tracking
file corresponed to the module.
+ * If this update_tracking
doesn't exist the files cannot be deleted.
+ * The Deleter waits until the module is enabled before start delete its files.
+ *
+ *
The method are called from org.netbeans.core.ModuleNode
.
+ *
+ * @author Jiri Rechtacek
+ */
+public final class ModuleDeleterImpl implements ModuleDeleter {
+
+ private static final String ELEMENT_MODULE = "module"; // NOI18N
+ private static final String ELEMENT_VERSION = "module_version"; // NOI18N
+ private static final String ATTR_ORIGIN = "origin"; // NOI18N
+ private static final String ATTR_LAST = "last"; // NOI18N
+ private static final String ATTR_FILE_NAME = "name"; // NOI18N
+ private static final String UPDATE_TRACKING = "update_tracking"; // NOI18N
+ private static final String INST_ORIGIN = "updater"; // NOI18N
+ private static final boolean ONLY_FROM_AUTOUPDATE = false;
+ private static final int TIME_TO_CHECK = 2000;
+ private static final int MAX_CHECKS_OF_STATE = 50;
+
+ private ErrorManager err = ErrorManager.getDefault ().getInstance ("org.netbeans.modules.autoupdate.ModuleDeleterImpl"); // NOI18N
+
+ public boolean canDelete (Module module) {
+ if (module.isFixed ()) {
+ err.log ("Cannot delete module because module " + module.getCodeName () + " isFixed.");
+ }
+ return !module.isFixed () && findUpdateTracking (module, ONLY_FROM_AUTOUPDATE);
+ }
+
+ public void delete (final Module module) throws IOException {
+ if (module == null) {
+ throw new IllegalArgumentException ("Module argument cannot be null.");
+ }
+
+ err.log ("Find and delete " + module.getCodeNameBase () + " module config file.");
+ removeControlModuleFile (module);
+
+ RequestProcessor.Task cleaner = RequestProcessor.getDefault ().create (new Runnable () {
+ public void run () {
+ try {
+ removeModuleFiles (module);
+ } catch (IOException ioe) {
+ err.notify (ioe);
+ }
+ }
+ });
+
+ RequestProcessor.getDefault ().post (new ModuleStateChecker (module, cleaner), TIME_TO_CHECK);
+ }
+
+ private File locateControlFile (Module m) {
+ String configFile = "config" + File.separator + "Modules" + File.separator + m.getCodeNameBase ().replace ('.', '-') + ".xml"; // NOI18N
+ return InstalledFileLocator.getDefault ().locate (configFile, m.getCodeNameBase (), false);
+ }
+
+ private void removeControlModuleFile (Module m) throws IOException {
+ File configFile = null;
+ while ((configFile = locateControlFile (m)) != null) {
+ if (configFile != null && configFile.exists ()) {
+ err.log ("Try detele the config File " + configFile);
+ FileUtil.toFileObject (configFile).delete ();
+ } else {
+ err.log ("Warning: Confing File " + configFile + " doesn't exist!");
+ }
+ }
+ // XXX: the modules list should be delete automatically when config/Modules/module.xml is removed
+ FileObject modulesRoot = Repository.getDefault ().getDefaultFileSystem ().findResource ("Modules"); // NOI18N
+ err.log ("It's hack: Call refresh on " + modulesRoot + " file object.");
+ if (modulesRoot != null) {
+ modulesRoot.refresh ();
+ }
+ // end of hack
+ }
+
+ private File locateUpdateTracking (Module m) {
+ String fileNameToFind = UPDATE_TRACKING + File.separator + m.getCodeNameBase ().replace ('.', '-') + ".xml"; // NOI18N
+ return InstalledFileLocator.getDefault ().locate (fileNameToFind, m.getCodeNameBase (), false);
+ }
+
+ private boolean findUpdateTracking (Module module, boolean checkIfFromAutoupdate) {
+ File updateTracking = locateUpdateTracking (module);
+ if (updateTracking != null && updateTracking.exists ()) {
+ //err.log ("Find UPDATE_TRACKING: " + updateTracking + " found.");
+ // check the write permission
+ if (!updateTracking.getParentFile ().canWrite ()) {
+ err.log ("Cannot delete module " + module.getCodeName () + " because no write permission to directory " + updateTracking.getParent ());
+ return false;
+ }
+ if (checkIfFromAutoupdate) {
+ boolean isFromAutoupdate = fromAutoupdate (getModuleConfiguration (updateTracking));
+ err.log ("Is Module " + module.getCodeName () + " installed by AutoUpdate? " + isFromAutoupdate);
+ return isFromAutoupdate;
+ } else {
+ return true;
+ }
+ } else {
+ err.log ("Cannot delete module " + module.getCodeName () + " because no update_tracking file found.");
+ return false;
+ }
+ }
+
+ private boolean fromAutoupdate (Node moduleNode) {
+ Node attrOrigin = moduleNode.getAttributes ().getNamedItem (ATTR_ORIGIN);
+ assert attrOrigin != null : "ELEMENT_VERSION must contain ATTR_ORIGIN attribute.";
+ String origin = attrOrigin.getNodeValue ();
+ return INST_ORIGIN.equals (origin);
+ }
+
+ private void removeModuleFiles (Module m) throws IOException {
+ File updateTracking = null;
+ while ((updateTracking = locateUpdateTracking (m)) != null) {
+ removeModuleFilesInCluster (m, updateTracking);
+ }
+ }
+
+ private void removeModuleFilesInCluster (Module module, File updateTracking) throws IOException {
+ err.log ("Read update_tracking " + updateTracking + " file.");
+ Set/**/ moduleFiles = readModuleFiles (getModuleConfiguration (updateTracking));
+ String configFile = "config" + File.separator + "Modules" + File.separator + module.getCodeNameBase ().replace ('.', '-') + ".xml"; // NOI18N
+ if (moduleFiles.contains (configFile)) {
+ File file = InstalledFileLocator.getDefault ().locate (configFile, module.getCodeNameBase (), false);
+ //assert file != null : "File " + configFile + " is located in module " + module.getCodeNameBase () + " cluster.";
+ //assert file.exists () : "File " + file + " exists.";
+ if (file != null && file.exists ()) {
+ err.log ("Config File " + file + " is deleted.");
+ FileUtil.toFileObject (file).delete ();
+ } else {
+ err.log ("Warning: Confing File " + configFile + " doesn't exist!");
+ }
+ }
+ Iterator it = moduleFiles.iterator ();
+ while (it.hasNext ()) {
+ String fileName = (String) it.next ();
+ if (fileName.equals (configFile)) {
+ continue;
+ }
+ File file = InstalledFileLocator.getDefault ().locate (fileName, module.getCodeNameBase (), false);
+ assert file != null : "File " + configFile + " is located in module " + module.getCodeNameBase () + " cluster.";
+ assert file.exists () : "File " + file + " exists.";
+ if (file.exists ()) {
+ err.log ("File " + file + " is deleted.");
+ FileUtil.toFileObject (file).delete ();
+ } else {
+ err.log ("Warning: File " + file + " doesn't exist!");
+ }
+ }
+ FileUtil.toFileObject (updateTracking).delete ();
+ err.log ("File " + updateTracking + " is deleted.");
+ }
+
+ private Node getModuleConfiguration (File moduleUpdateTracking) {
+ Document document = null;
+ InputStream is;
+ try {
+ is = new FileInputStream (moduleUpdateTracking);
+ InputSource xmlInputSource = new InputSource (is);
+ document = XMLUtil.parse (xmlInputSource, false, false, null, org.openide.xml.EntityCatalog.getDefault ());
+ if (is != null) {
+ is.close ();
+ }
+ } catch (SAXException saxe) {
+ ErrorManager.getDefault ().notify (ErrorManager.INFORMATIONAL, saxe);
+ return null;
+ } catch (IOException ioe) {
+ ErrorManager.getDefault ().notify (ErrorManager.INFORMATIONAL, ioe);
+ }
+
+ assert document.getDocumentElement () != null : "File " + moduleUpdateTracking + " must contain element.";
+ return getModuleElement (document.getDocumentElement ());
+ }
+
+ private Node getModuleElement (Element element) {
+ Node lastElement = null;
+ assert ELEMENT_MODULE.equals (element.getTagName ()) : "The root element is: " + ELEMENT_MODULE + " but was: " + element.getTagName ();
+ NodeList listModuleVersions = element.getElementsByTagName (ELEMENT_VERSION);
+ for (int i = 0; i < listModuleVersions.getLength (); i++) {
+ lastElement = getModuleLastVersion (listModuleVersions.item (i));
+ if (lastElement != null) {
+ break;
+ }
+ }
+ return lastElement;
+ }
+
+ private Node getModuleLastVersion (Node version) {
+ Node attrLast = version.getAttributes ().getNamedItem (ATTR_LAST);
+ assert attrLast != null : "ELEMENT_VERSION must contain ATTR_LAST attribute.";
+ if (Boolean.valueOf (attrLast.getNodeValue ()).booleanValue ()) {
+ return version;
+ } else {
+ return null;
+ }
+ }
+
+ private Set/**/ readModuleFiles (Node version) {
+ Set/**/ files = new HashSet ();
+ NodeList fileNodes = version.getChildNodes ();
+ for (int i = 0; i < fileNodes.getLength (); i++) {
+ if (fileNodes.item (i).hasAttributes ()) {
+ NamedNodeMap map = fileNodes.item (i).getAttributes ();
+ files.add (map.getNamedItem (ATTR_FILE_NAME).getNodeValue ());
+ }
+ }
+ return files;
+ }
+
+ private class ModuleStateChecker implements Runnable {
+ RequestProcessor.Task cleaner;
+ Module m;
+ int checks;
+ public ModuleStateChecker (Module module, RequestProcessor.Task filesCleaner) {
+ cleaner = filesCleaner;
+ m = module;
+ checks = 0;
+ }
+
+ public void run () {
+ checks ++;
+ if (m.isEnabled () && m.isValid ()) {
+ if (checks < MAX_CHECKS_OF_STATE) {
+ err.log ("Module " + m.getCodeNameBase () + " is still valid, repost later.");
+ RequestProcessor.getDefault ().post (this, TIME_TO_CHECK);
+ } else {
+ err.log ("Warning: Module " + m.getCodeNameBase () + " is still valid but time-out. Task is terminated.");
+ }
+ return ;
+ }
+
+ // post clean task
+ cleaner.run ();
+ }
+
+ }
+}