Added
Link Here
|
1 |
/* |
2 |
* Sun Public License Notice |
3 |
* |
4 |
* The contents of this file are subject to the Sun Public License |
5 |
* Version 1.0 (the "License"). You may not use this file except in |
6 |
* compliance with the License. A copy of the License is available at |
7 |
* http://www.sun.com/ |
8 |
* |
9 |
* The Original Code is NetBeans. The Initial Developer of the Original |
10 |
* Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun |
11 |
* Microsystems, Inc. All Rights Reserved. |
12 |
*/ |
13 |
|
14 |
package org.netbeans.modules.autoupdate; |
15 |
|
16 |
import org.netbeans.core.modules.UninstallModulePerformer; |
17 |
import org.openide.filesystems.FileUtil; |
18 |
import org.openide.modules.ModuleInfo; |
19 |
import org.openide.xml.XMLUtil; |
20 |
import org.openide.ErrorManager; |
21 |
|
22 |
import java.io.File; |
23 |
import java.io.FileInputStream; |
24 |
import java.io.IOException; |
25 |
import java.io.InputStream; |
26 |
import java.util.ArrayList; |
27 |
import java.util.Collections; |
28 |
import java.util.Enumeration; |
29 |
import java.util.HashSet; |
30 |
import java.util.Iterator; |
31 |
import java.util.List; |
32 |
import java.util.Set; |
33 |
import java.util.StringTokenizer; |
34 |
|
35 |
import org.w3c.dom.Document; |
36 |
import org.w3c.dom.Element; |
37 |
import org.w3c.dom.NamedNodeMap; |
38 |
import org.w3c.dom.Node; |
39 |
import org.w3c.dom.NodeList; |
40 |
import org.xml.sax.InputSource; |
41 |
import org.xml.sax.SAXException; |
42 |
|
43 |
|
44 |
/** |
45 |
* |
46 |
* @author Jiri Rechtacek |
47 |
*/ |
48 |
public final class UninstallModule implements UninstallModulePerformer { |
49 |
|
50 |
private static final String ELEMENT_MODULES = "installed_modules"; // NOI18N |
51 |
private static final String ELEMENT_MODULE = "module"; // NOI18N |
52 |
private static final String ATTR_CODENAMEBASE = "codename"; // NOI18N |
53 |
private static final String ELEMENT_VERSION = "module_version"; // NOI18N |
54 |
private static final String ATTR_VERSION = "specification_version"; // NOI18N |
55 |
private static final String ATTR_ORIGIN = "origin"; // NOI18N |
56 |
private static final String ATTR_LAST = "last"; // NOI18N |
57 |
private static final String ATTR_INSTALL = "install_time"; // NOI18N |
58 |
private static final String ELEMENT_FILE = "file"; // NOI18N |
59 |
private static final String ATTR_FILE_NAME = "name"; // NOI18N |
60 |
private static final String ATTR_CRC = "crc"; // NOI18N |
61 |
private static final String UPDATE_TRACKING = "update_tracking"; // NOI18N |
62 |
|
63 |
private ErrorManager err = ErrorManager.getDefault ().getInstance ("org.netbeans.modules.autoupdate.UninstallModule"); |
64 |
|
65 |
public boolean uninstallModule (ModuleInfo [] modules) { |
66 |
if (modules == null) { |
67 |
throw new IllegalArgumentException ("Modules argument cannot be null."); |
68 |
} |
69 |
|
70 |
for (int i = 0; i < modules.length; i++) { |
71 |
err.log ("Module " + modules [i].getCodeNameBase () + " is being deleted. All module's file will be removed."); |
72 |
try { |
73 |
removeModuleFiles (modules[i]); |
74 |
} catch (IOException ioe) { |
75 |
err.notify (ioe); |
76 |
} |
77 |
} |
78 |
return false; |
79 |
} |
80 |
|
81 |
// support for module uninstall |
82 |
|
83 |
private void removeModuleFiles (ModuleInfo m) throws IOException { |
84 |
Iterator it = clusters ().iterator (); |
85 |
while (it.hasNext ()) { |
86 |
removeModuleFilesInCluster (m, (File)it.next ()); |
87 |
} |
88 |
return; |
89 |
} |
90 |
|
91 |
private void removeModuleFilesInCluster (ModuleInfo module, File cluster) throws IOException { |
92 |
File updateTracking = new File (cluster + File.separator + UPDATE_TRACKING); |
93 |
if (!updateTracking.isDirectory ()) return; |
94 |
File moduleUpdateTracking = FileUtil.normalizeFile (new File (updateTracking, module.getCodeNameBase ().replace ('.', '-') + ".xml")); // NOI18N |
95 |
if (!moduleUpdateTracking.exists ()) return; |
96 |
err.log ("UPDATE_TRACKING: " + moduleUpdateTracking + " found."); |
97 |
Set/*<String>*/ moduleFiles = getModuleFiles (moduleUpdateTracking); |
98 |
Iterator it = moduleFiles.iterator (); |
99 |
while (it.hasNext ()) { |
100 |
String fileName = (String) it.next (); |
101 |
File file = FileUtil.normalizeFile (new File (cluster + File.separator + fileName)); |
102 |
//assert file.exists () : "File " + file + " exists."; |
103 |
if (file.exists ()) { |
104 |
err.log ("File " + file + " is deleted."); |
105 |
FileUtil.toFileObject (file).delete (); |
106 |
} else { |
107 |
err.log ("Warning: File " + file + " doesn't exist!"); |
108 |
} |
109 |
} |
110 |
FileUtil.toFileObject (moduleUpdateTracking).delete (); |
111 |
} |
112 |
|
113 |
// XXX replace with file locator |
114 |
private static File getPlatformDir () { |
115 |
return new File (System.getProperty ("netbeans.home")); // NOI18N |
116 |
} |
117 |
|
118 |
private static List/*<File>*/ clusters () { |
119 |
ArrayList/*<File>*/ files = new ArrayList (); |
120 |
|
121 |
File ud = new File (System.getProperty ("netbeans.user")); // NOI18N |
122 |
files.add (ud); |
123 |
|
124 |
String dirs = System.getProperty ("netbeans.dirs"); // NOI18N |
125 |
|
126 |
if (dirs != null) { |
127 |
Enumeration en = new StringTokenizer (dirs, File.pathSeparator); |
128 |
while (en.hasMoreElements ()) { |
129 |
File f = new File ((String)en.nextElement ()); |
130 |
files.add (f); |
131 |
} |
132 |
} |
133 |
|
134 |
|
135 |
File id = getPlatformDir (); |
136 |
files.add (id); |
137 |
|
138 |
return Collections.unmodifiableList (files); |
139 |
} |
140 |
|
141 |
private Set/*<String>*/ getModuleFiles (File moduleUpdateTracking) { |
142 |
return readFromUpdateTracking (moduleUpdateTracking); |
143 |
} |
144 |
|
145 |
private Set/*<String>*/ readFromUpdateTracking (File moduleUpdateTracking) { |
146 |
Document document = null; |
147 |
InputStream is; |
148 |
try { |
149 |
is = new FileInputStream (moduleUpdateTracking); |
150 |
InputSource xmlInputSource = new InputSource (is); |
151 |
document = XMLUtil.parse (xmlInputSource, false, false, null, org.openide.xml.EntityCatalog.getDefault ()); |
152 |
if (is != null) { |
153 |
is.close (); |
154 |
} |
155 |
} catch (SAXException saxe) { |
156 |
ErrorManager.getDefault ().notify (ErrorManager.INFORMATIONAL, saxe); |
157 |
return Collections.EMPTY_SET; |
158 |
} catch (IOException ioe) { |
159 |
ErrorManager.getDefault ().notify (ErrorManager.INFORMATIONAL, ioe); |
160 |
} |
161 |
|
162 |
assert document.getDocumentElement () != null : "File " + moduleUpdateTracking + " must contain <module> element."; |
163 |
return readModuleElement (document.getDocumentElement ()); |
164 |
} |
165 |
|
166 |
private Set/*<String>*/ readModuleElement (Element element) { |
167 |
Set/*<String>*/ files = new HashSet (); |
168 |
assert ELEMENT_MODULE.equals (element.getTagName ()) : "The root element is: " + ELEMENT_MODULE + " but was: " + element.getTagName (); |
169 |
NodeList listModuleVersions = element.getElementsByTagName (ELEMENT_VERSION); |
170 |
for (int i = 0; i < listModuleVersions.getLength (); i++) { |
171 |
files.addAll (readModuleVersion (listModuleVersions.item (i))); |
172 |
} |
173 |
return files; |
174 |
} |
175 |
|
176 |
private Set/*<String>*/ readModuleVersion (Node version) { |
177 |
Node attrLast = version.getAttributes ().getNamedItem (ATTR_LAST); |
178 |
assert attrLast != null : "ELEMENT_VERSION must contain ATTR_LAST attribute."; |
179 |
if (Boolean.valueOf (attrLast.getNodeValue ()).booleanValue ()) { |
180 |
return readModuleFiles (version); |
181 |
} else { |
182 |
return Collections.EMPTY_SET; |
183 |
} |
184 |
} |
185 |
|
186 |
private Set/*<String>*/ readModuleFiles (Node version) { |
187 |
Set/*<String>*/ files = new HashSet (); |
188 |
NodeList fileNodes = version.getChildNodes (); |
189 |
for (int i = 0; i < fileNodes.getLength (); i++) { |
190 |
if (fileNodes.item (i).hasAttributes ()) { |
191 |
NamedNodeMap map = fileNodes.item (i).getAttributes (); |
192 |
files.add (map.getNamedItem (ATTR_FILE_NAME).getNodeValue ()); |
193 |
} |
194 |
} |
195 |
return files; |
196 |
} |
197 |
|
198 |
// end of module uninstall |
199 |
|
200 |
} |