Index: core/src/org/netbeans/core/modules/UninstallModulePerformer.java =================================================================== RCS file: core/src/org/netbeans/core/modules/UninstallModulePerformer.java diff -N core/src/org/netbeans/core/modules/UninstallModulePerformer.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ core/src/org/netbeans/core/modules/UninstallModulePerformer.java 13 May 2005 16:28:50 -0000 @@ -0,0 +1,28 @@ +/* + * 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.core.modules; + +import org.openide.modules.ModuleInfo; + +/** + * XXX + * + * @since ??? + * @author Jiri Rechtacek + */ +public interface UninstallModulePerformer { + + public boolean uninstallModule (ModuleInfo [] modules); + +} Index: core/src/org/netbeans/core/ui/ModuleBean.java =================================================================== RCS file: /cvs/core/src/org/netbeans/core/ui/ModuleBean.java,v retrieving revision 1.35 diff -u -r1.35 ModuleBean.java --- core/src/org/netbeans/core/ui/ModuleBean.java 24 Jan 2005 14:06:10 -0000 1.35 +++ core/src/org/netbeans/core/ui/ModuleBean.java 13 May 2005 16:28:50 -0000 @@ -18,6 +18,7 @@ import org.netbeans.core.modules.*; import java.util.*; import javax.swing.SwingUtilities; +import org.openide.modules.ModuleInfo; import org.openide.modules.SpecificationVersion; import java.io.File; import java.beans.*; @@ -585,8 +586,26 @@ private void doDelete(Set modules) { if (modules.isEmpty()) return; err.log("doDelete: " + modules); + // Have to be turned off first: doDisable(modules); + + UninstallModulePerformer performer = getUninstallModulePerformer (); + if (performer != null) { + System.out.println("###: Wow. I call the performer " + performer); + ModuleInfo [] moduleInfos = new ModuleInfo [modules.size ()]; + Iterator it = modules.iterator (); + int i = 0; + while (it.hasNext ()) { + Object o = it.next (); + assert o instanceof ModuleInfo : o + " must be instanceof ModuleInfo."; + moduleInfos [i++] = (ModuleInfo) o; + } + performer.uninstallModule (moduleInfos); + } else { + System.out.println("###: sorry, I have no performers!"); + } + Iterator it = modules.iterator(); while (it.hasNext()) { Module m = (Module)it.next(); @@ -947,4 +966,15 @@ } } + private static UninstallModulePerformer getUninstallModulePerformer () { + Lookup.Result result = Lookup.getDefault ().lookup (new Lookup.Template (UninstallModulePerformer.class)); + if (!result.allInstances ().isEmpty ()) { + return (UninstallModulePerformer) result.allInstances ().iterator ().next (); + } else { + assert false : "Any UninstallModulePerformer should exits."; + return null; + } + } + + } Index: autoupdate/src/META-INF/services/org.netbeans.core.modules.UninstallModulePerformer =================================================================== RCS file: autoupdate/src/META-INF/services/org.netbeans.core.modules.UninstallModulePerformer diff -N autoupdate/src/META-INF/services/org.netbeans.core.modules.UninstallModulePerformer --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ autoupdate/src/META-INF/services/org.netbeans.core.modules.UninstallModulePerformer 13 May 2005 16:28:51 -0000 @@ -0,0 +1 @@ +org.netbeans.modules.autoupdate.UninstallModule Index: autoupdate/src/org/netbeans/modules/autoupdate/UninstallModule.java =================================================================== RCS file: autoupdate/src/org/netbeans/modules/autoupdate/UninstallModule.java diff -N autoupdate/src/org/netbeans/modules/autoupdate/UninstallModule.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ autoupdate/src/org/netbeans/modules/autoupdate/UninstallModule.java 13 May 2005 16:28:51 -0000 @@ -0,0 +1,200 @@ +/* + * 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.UninstallModulePerformer; +import org.openide.filesystems.FileUtil; +import org.openide.modules.ModuleInfo; +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.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.StringTokenizer; + +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; + + +/** + * + * @author Jiri Rechtacek + */ +public final class UninstallModule implements UninstallModulePerformer { + + private static final String ELEMENT_MODULES = "installed_modules"; // NOI18N + private static final String ELEMENT_MODULE = "module"; // NOI18N + private static final String ATTR_CODENAMEBASE = "codename"; // NOI18N + private static final String ELEMENT_VERSION = "module_version"; // NOI18N + private static final String ATTR_VERSION = "specification_version"; // NOI18N + private static final String ATTR_ORIGIN = "origin"; // NOI18N + private static final String ATTR_LAST = "last"; // NOI18N + private static final String ATTR_INSTALL = "install_time"; // NOI18N + private static final String ELEMENT_FILE = "file"; // NOI18N + private static final String ATTR_FILE_NAME = "name"; // NOI18N + private static final String ATTR_CRC = "crc"; // NOI18N + private static final String UPDATE_TRACKING = "update_tracking"; // NOI18N + + private ErrorManager err = ErrorManager.getDefault ().getInstance ("org.netbeans.modules.autoupdate.UninstallModule"); + + public boolean uninstallModule (ModuleInfo [] modules) { + if (modules == null) { + throw new IllegalArgumentException ("Modules argument cannot be null."); + } + + for (int i = 0; i < modules.length; i++) { + err.log ("Module " + modules [i].getCodeNameBase () + " is being deleted. All module's file will be removed."); + try { + removeModuleFiles (modules[i]); + } catch (IOException ioe) { + err.notify (ioe); + } + } + return false; + } + + // support for module uninstall + + private void removeModuleFiles (ModuleInfo m) throws IOException { + Iterator it = clusters ().iterator (); + while (it.hasNext ()) { + removeModuleFilesInCluster (m, (File)it.next ()); + } + return; + } + + private void removeModuleFilesInCluster (ModuleInfo module, File cluster) throws IOException { + File updateTracking = new File (cluster + File.separator + UPDATE_TRACKING); + if (!updateTracking.isDirectory ()) return; + File moduleUpdateTracking = FileUtil.normalizeFile (new File (updateTracking, module.getCodeNameBase ().replace ('.', '-') + ".xml")); // NOI18N + if (!moduleUpdateTracking.exists ()) return; + err.log ("UPDATE_TRACKING: " + moduleUpdateTracking + " found."); + Set/**/ moduleFiles = getModuleFiles (moduleUpdateTracking); + Iterator it = moduleFiles.iterator (); + while (it.hasNext ()) { + String fileName = (String) it.next (); + File file = FileUtil.normalizeFile (new File (cluster + File.separator + fileName)); + //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 (moduleUpdateTracking).delete (); + } + + // XXX replace with file locator + private static File getPlatformDir () { + return new File (System.getProperty ("netbeans.home")); // NOI18N + } + + private static List/**/ clusters () { + ArrayList/**/ files = new ArrayList (); + + File ud = new File (System.getProperty ("netbeans.user")); // NOI18N + files.add (ud); + + String dirs = System.getProperty ("netbeans.dirs"); // NOI18N + + if (dirs != null) { + Enumeration en = new StringTokenizer (dirs, File.pathSeparator); + while (en.hasMoreElements ()) { + File f = new File ((String)en.nextElement ()); + files.add (f); + } + } + + + File id = getPlatformDir (); + files.add (id); + + return Collections.unmodifiableList (files); + } + + private Set/**/ getModuleFiles (File moduleUpdateTracking) { + return readFromUpdateTracking (moduleUpdateTracking); + } + + private Set/**/ readFromUpdateTracking (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 Collections.EMPTY_SET; + } catch (IOException ioe) { + ErrorManager.getDefault ().notify (ErrorManager.INFORMATIONAL, ioe); + } + + assert document.getDocumentElement () != null : "File " + moduleUpdateTracking + " must contain element."; + return readModuleElement (document.getDocumentElement ()); + } + + private Set/**/ readModuleElement (Element element) { + Set/**/ files = new HashSet (); + 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++) { + files.addAll (readModuleVersion (listModuleVersions.item (i))); + } + return files; + } + + private Set/**/ readModuleVersion (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 readModuleFiles (version); + } else { + return Collections.EMPTY_SET; + } + } + + 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; + } + + // end of module uninstall + +}