Added
Link Here
|
1 |
/* |
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 |
* |
4 |
* Copyright 2010 Oracle and/or its affiliates. All rights reserved. |
5 |
* |
6 |
* Oracle and Java are registered trademarks of Oracle and/or its affiliates. |
7 |
* Other names may be trademarks of their respective owners. |
8 |
* |
9 |
* The contents of this file are subject to the terms of either the GNU |
10 |
* General Public License Version 2 only ("GPL") or the Common |
11 |
* Development and Distribution License("CDDL") (collectively, the |
12 |
* "License"). You may not use this file except in compliance with the |
13 |
* License. You can obtain a copy of the License at |
14 |
* http://www.netbeans.org/cddl-gplv2.html |
15 |
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the |
16 |
* specific language governing permissions and limitations under the |
17 |
* License. When distributing the software, include this License Header |
18 |
* Notice in each file and include the License file at |
19 |
* nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this |
20 |
* particular file as subject to the "Classpath" exception as provided |
21 |
* by Oracle in the GPL Version 2 section of the License file that |
22 |
* accompanied this code. If applicable, add the following below the |
23 |
* License Header, with the fields enclosed by brackets [] replaced by |
24 |
* your own identifying information: |
25 |
* "Portions Copyrighted [year] [name of copyright owner]" |
26 |
* |
27 |
* If you wish your version of this file to be governed by only the CDDL |
28 |
* or only the GPL Version 2, indicate your decision by adding |
29 |
* "[Contributor] elects to include this software in this distribution |
30 |
* under the [CDDL or GPL Version 2] license." If you do not indicate a |
31 |
* single choice of license, a recipient has the option to distribute |
32 |
* your version of this file under either the CDDL, the GPL Version 2 or |
33 |
* to extend the choice of license to its licensees as provided above. |
34 |
* However, if you add GPL Version 2 code and therefore, elected the GPL |
35 |
* Version 2 license, then the option applies only if the new code is |
36 |
* made subject to such option by the copyright holder. |
37 |
* |
38 |
* Contributor(s): |
39 |
* |
40 |
* Portions Copyrighted 2010 Sun Microsystems, Inc. |
41 |
*/ |
42 |
package org.netbeans.modules.autoupdate.services; |
43 |
|
44 |
import java.io.File; |
45 |
import java.io.FileInputStream; |
46 |
import java.io.FileOutputStream; |
47 |
import java.io.IOException; |
48 |
import java.io.OutputStream; |
49 |
import java.io.OutputStreamWriter; |
50 |
import java.io.PrintWriter; |
51 |
import java.net.URL; |
52 |
import java.util.ArrayList; |
53 |
import java.util.List; |
54 |
import java.util.jar.Attributes; |
55 |
import java.util.jar.JarFile; |
56 |
import java.util.jar.JarOutputStream; |
57 |
import java.util.jar.Manifest; |
58 |
import java.util.jar.Pack200; |
59 |
import java.util.logging.Level; |
60 |
import java.util.zip.GZIPOutputStream; |
61 |
import java.util.zip.ZipEntry; |
62 |
import org.netbeans.api.autoupdate.InstallSupport; |
63 |
import org.netbeans.api.autoupdate.OperationContainer; |
64 |
import org.netbeans.api.autoupdate.OperationContainer.OperationInfo; |
65 |
import org.netbeans.api.autoupdate.OperationException; |
66 |
import org.netbeans.api.autoupdate.OperationSupport.Restarter; |
67 |
import org.netbeans.api.autoupdate.TestUtils; |
68 |
import org.netbeans.api.autoupdate.UpdateElement; |
69 |
import org.netbeans.api.autoupdate.UpdateUnit; |
70 |
import org.netbeans.api.autoupdate.UpdateUnitProvider; |
71 |
import org.netbeans.api.autoupdate.UpdateUnitProviderFactory; |
72 |
import org.netbeans.core.startup.MainLookup; |
73 |
import org.netbeans.junit.NbTestCase; |
74 |
import org.netbeans.modules.autoupdate.updateprovider.AutoupdateCatalogProvider; |
75 |
import org.openide.filesystems.FileUtil; |
76 |
import org.openide.util.Lookup; |
77 |
|
78 |
public class NbmExternalTest extends NbTestCase { |
79 |
|
80 |
protected List<UpdateUnit> keepItNotToGC; |
81 |
private static File catalogFile; |
82 |
private static URL catalogURL; |
83 |
private File tmpDirectory; |
84 |
private List<File> nbms = new ArrayList<File>(); |
85 |
private List<String> moduleElements = new ArrayList<String>(); |
86 |
|
87 |
public NbmExternalTest(String testName) { |
88 |
super(testName); |
89 |
} |
90 |
|
91 |
@Override |
92 |
protected Level logLevel() { |
93 |
return Level.FINE; |
94 |
} |
95 |
|
96 |
|
97 |
public static class MyProvider extends AutoupdateCatalogProvider { |
98 |
|
99 |
public MyProvider() { |
100 |
super("test-updates-provider", "test-updates-provider", catalogURL, UpdateUnitProvider.CATEGORY.STANDARD); |
101 |
} |
102 |
} |
103 |
|
104 |
private String getModuleElement(boolean visible, String codeName, String releaseVersion, String implVersion, String moduleName, String distr, String specVersion, String dependency) { |
105 |
String releaseVersionAppendix = ((releaseVersion != null /*&& Integer.parseInt(releaseVersion)!=0*/) ? ("/" + releaseVersion) : ""); |
106 |
return "\n<module " |
107 |
+ "\n codenamebase='" + codeName + "' " |
108 |
+ "\n distribution='" + distr + "' " |
109 |
+ "\n downloadsize='0' " |
110 |
+ "\n homepage='' " |
111 |
+ "\n license='AD9FBBC9' " |
112 |
+ "\n moduleauthor='' " |
113 |
+ "\n needsrestart='false' " |
114 |
+ "\n releasedate='2007/01/30'>" |
115 |
+ "\n <manifest " |
116 |
+ "\n AutoUpdate-Show-In-Client='" + visible + "' " |
117 |
+ "\n OpenIDE-Module='" + codeName + releaseVersionAppendix + "'" |
118 |
+ "\n OpenIDE-Module-Implementation-Version='" + (implVersion == null ? "070130" : implVersion) + "' " |
119 |
+ "\n OpenIDE-Module-Java-Dependencies='Java > 1.4' " |
120 |
+ "\n OpenIDE-Module-Name='" + moduleName + "' " |
121 |
+ (dependency != null ? " OpenIDE-Module-Module-Dependencies=\"" + dependency.replace(">", ">") + "\" " : "") |
122 |
+ "\n OpenIDE-Module-Requires='org.openide.modules.ModuleFormat1' " |
123 |
+ "\n OpenIDE-Module-Specification-Version='" + specVersion + "'/>" |
124 |
+ "\n</module>"; |
125 |
} |
126 |
|
127 |
private String createInfoXML(boolean visible, String codeName, String releaseVersion, String implVersion, String moduleName, String distr, String specVersion, String dependency) { |
128 |
String moduleElement = getModuleElement(visible, codeName, releaseVersion, implVersion, moduleName, distr, specVersion, dependency); |
129 |
|
130 |
moduleElements.add(moduleElement); |
131 |
moduleElements.add("\n <license name='AD9FBBC9'>[NO LICENSE SPECIFIED]" |
132 |
+ "\n</license>\n"); |
133 |
return "<?xml version='1.0' encoding='UTF-8'?>" |
134 |
+ "<!DOCTYPE module PUBLIC '-//NetBeans//DTD Autoupdate Module Info 2.5//EN' 'http://www.netbeans.org/dtds/autoupdate-info-2_5.dtd'>" |
135 |
+ moduleElement; |
136 |
} |
137 |
|
138 |
private void writeCatalog() throws IOException { |
139 |
String res = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" |
140 |
+ "<!DOCTYPE module_updates PUBLIC \"-//NetBeans//DTD Autoupdate Catalog 2.5//EN\" \"http://www.netbeans.org/dtds/autoupdate-catalog-2_5.dtd\">" |
141 |
+ "<module_updates timestamp=\"00/00/19/08/03/2006\">\n"; |
142 |
for (String element : moduleElements) { |
143 |
res += element; |
144 |
} |
145 |
res += "</module_updates>\n"; |
146 |
if (catalogFile == null) { |
147 |
catalogFile = File.createTempFile("catalog-", ".xml", tmpDirectory); |
148 |
catalogURL = catalogFile.toURI().toURL(); |
149 |
} |
150 |
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(catalogFile), "UTF-8")); |
151 |
pw.write(res); |
152 |
pw.close(); |
153 |
} |
154 |
|
155 |
private String getConfigXML(String codeName, String moduleFile, String specVersion) { |
156 |
return "<?xml version='1.0' encoding='UTF-8'?>" |
157 |
+ " <!DOCTYPE module PUBLIC '-//NetBeans//DTD Module Status 1.0//EN'" |
158 |
+ " 'http://www.netbeans.org/dtds/module-status-1_0.dtd'>" |
159 |
+ " <module name='" + codeName + "'>" |
160 |
+ " <param name='autoload'>false</param>" |
161 |
+ " <param name='eager'>false</param>" |
162 |
+ " <param name='enabled'>true</param>" |
163 |
+ " <param name='jar'>modules/" + moduleFile + ".jar</param>" |
164 |
+ " <param name='reloadable'>false</param>" |
165 |
+ " <param name='specversion'>" + specVersion + "</param>" |
166 |
+ " </module>"; |
167 |
} |
168 |
|
169 |
private String getManifest(String codeName, String releaseVersion, String implVersion, String moduleDir, String specVersion, boolean visible, String dependency) { |
170 |
String releaseVersionAppendix = ((releaseVersion != null /*&& Integer.parseInt(releaseVersion)!=0*/) ? ("/" + releaseVersion) : ""); |
171 |
return "Manifest-Version: 1.0\n" |
172 |
+ "Ant-Version: Apache Ant 1.7.0\n" |
173 |
+ "Created-By: 1.6.0-b105 (Sun Microsystems Inc.)\n" |
174 |
+ "OpenIDE-Module-Public-Packages: -\n" |
175 |
+ "OpenIDE-Module-Java-Dependencies: Java > 1.4\n" |
176 |
+ "OpenIDE-Module-Implementation-Version: " + (implVersion == null ? "070130" : implVersion) |
177 |
+ "\n" |
178 |
+ (dependency != null ? ("OpenIDE-Module-Module-Dependencies: " + dependency + "\n") : "") |
179 |
+ "OpenIDE-Module: " + codeName + releaseVersionAppendix |
180 |
+ "\n" |
181 |
+ "OpenIDE-Module-Localizing-Bundle: " + moduleDir + "Bundle.properties\n" |
182 |
+ "OpenIDE-Module-Specification-Version: " + specVersion + "\n" |
183 |
+ "OpenIDE-Module-Requires: org.openide.modules.ModuleFormat1\n" |
184 |
+ "AutoUpdate-Show-In-Client: " + visible + "\n" |
185 |
+ "\n"; |
186 |
} |
187 |
|
188 |
private File prepareNBM(String codeName, String releaseVersion, String implVersion, String specVersion, boolean visible, String dependency) throws Exception { |
189 |
String moduleName = codeName.substring(codeName.lastIndexOf(".") + 1); |
190 |
String moduleFile = codeName.replace(".", "-"); |
191 |
String moduleDir = codeName.replace(".", "/") + "/"; |
192 |
File nbm = File.createTempFile(moduleFile + "-", ".nbm", tmpDirectory); |
193 |
|
194 |
final String MODULE_NAME_PROP = "OpenIDE-Module-Name"; |
195 |
|
196 |
File jar = new File(tmpDirectory, "x.jar"); |
197 |
jar.getParentFile().mkdirs(); |
198 |
JarOutputStream jos = new JarOutputStream(new FileOutputStream(jar)); |
199 |
int idx = moduleDir.indexOf("/"); |
200 |
while (idx != -1) { |
201 |
jos.putNextEntry(new ZipEntry(moduleDir.substring(0, idx + 1))); |
202 |
idx = moduleDir.indexOf("/", idx + 1); |
203 |
} |
204 |
|
205 |
jos.putNextEntry(new ZipEntry(moduleDir + "Bundle.properties")); |
206 |
jos.write(new String(MODULE_NAME_PROP + "=" + moduleName).getBytes("UTF-8")); |
207 |
jos.putNextEntry(new ZipEntry("META-INF/")); |
208 |
jos.putNextEntry(new ZipEntry("META-INF/manifest.mf")); |
209 |
jos.write(getManifest(codeName, releaseVersion, implVersion, moduleDir, specVersion, visible, dependency).getBytes("UTF-8")); |
210 |
jos.close(); |
211 |
File ext = new File(jar.getParentFile(), jar.getName() + ".external"); |
212 |
FileOutputStream os = new FileOutputStream(ext); |
213 |
os.write(("URL: " + jar.toURI().toString() + "\n").getBytes()); |
214 |
os.close(); |
215 |
|
216 |
Manifest mf = new Manifest(); |
217 |
mf.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); |
218 |
|
219 |
|
220 |
jos = new JarOutputStream(new FileOutputStream(nbm), mf); |
221 |
jos.putNextEntry(new ZipEntry("Info/")); |
222 |
jos.putNextEntry(new ZipEntry("Info/info.xml")); |
223 |
jos.write(createInfoXML(visible, codeName, releaseVersion, implVersion, moduleName, nbm.toURI().toURL().toString(), specVersion, dependency).getBytes("UTF-8")); |
224 |
|
225 |
jos.putNextEntry(new ZipEntry("netbeans/")); |
226 |
jos.putNextEntry(new ZipEntry("netbeans/modules/")); |
227 |
jos.putNextEntry(new ZipEntry("netbeans/config/")); |
228 |
jos.putNextEntry(new ZipEntry("netbeans/config/Modules/")); |
229 |
jos.putNextEntry(new ZipEntry("netbeans/config/Modules/" + moduleFile + ".xml")); |
230 |
|
231 |
jos.write(getConfigXML(codeName, moduleFile, specVersion).getBytes("UTF-8")); |
232 |
|
233 |
|
234 |
jos.putNextEntry(new ZipEntry("netbeans/modules/" + moduleFile + ".jar.external")); |
235 |
|
236 |
FileInputStream fis = new FileInputStream(ext); |
237 |
FileUtil.copy(fis, jos); |
238 |
fis.close(); |
239 |
ext.delete(); |
240 |
jos.close(); |
241 |
nbms.add(nbm); |
242 |
|
243 |
return nbm; |
244 |
} |
245 |
|
246 |
protected void setUp() throws Exception { |
247 |
super.setUp(); |
248 |
this.clearWorkDir(); |
249 |
tmpDirectory = new File(getWorkDirPath(), "tmp"); |
250 |
tmpDirectory.mkdirs(); |
251 |
|
252 |
writeCatalog(); |
253 |
|
254 |
TestUtils.setUserDir(getWorkDirPath()); |
255 |
TestUtils.testInit(); |
256 |
|
257 |
MainLookup.register(new MyProvider()); |
258 |
assert Lookup.getDefault().lookup(MyProvider.class) != null; |
259 |
UpdateUnitProviderFactory.getDefault().refreshProviders(null, true); |
260 |
} |
261 |
|
262 |
private void doInstall(OperationContainer<InstallSupport> installContainer) throws OperationException { |
263 |
InstallSupport support = installContainer.getSupport(); |
264 |
assertNotNull(support); |
265 |
|
266 |
InstallSupport.Validator v = support.doDownload(null, false); |
267 |
assertNotNull(v); |
268 |
InstallSupport.Installer i = support.doValidate(v, null); |
269 |
assertNotNull(i); |
270 |
Restarter r = null; |
271 |
try { |
272 |
r = support.doInstall(i, null); |
273 |
} catch (OperationException ex) { |
274 |
if (OperationException.ERROR_TYPE.INSTALL == ex.getErrorType()) { |
275 |
// can ingore |
276 |
// module system cannot load the module either |
277 |
} else { |
278 |
fail(ex.toString()); |
279 |
} |
280 |
} |
281 |
assertNull("Installing new element require restarting though it should not", r); |
282 |
} |
283 |
|
284 |
public void testNbmWithExternal() throws Exception { |
285 |
String moduleCNB = "org.netbeans.modules.mymodule"; |
286 |
String moduleReleaseVersion = "1"; |
287 |
String moduleImplVersion = "2"; |
288 |
String moduleSpecVersion = "1.0"; |
289 |
|
290 |
prepareNBM(moduleCNB, moduleReleaseVersion, moduleImplVersion, moduleSpecVersion, false, null); |
291 |
|
292 |
writeCatalog(); |
293 |
UpdateUnitProviderFactory.getDefault().refreshProviders(null, true); |
294 |
OperationContainer<InstallSupport> installContainer = OperationContainer.createForInstall(); |
295 |
UpdateUnit moduleUnit = getUpdateUnit(moduleCNB); |
296 |
assertNull("cannot be installed", moduleUnit.getInstalled()); |
297 |
UpdateElement moduleElement = getAvailableUpdate(moduleUnit, 0); |
298 |
assertEquals(moduleElement.getSpecificationVersion(), moduleSpecVersion); |
299 |
OperationInfo<InstallSupport> independentInfo = installContainer.add(moduleElement); |
300 |
assertNotNull(independentInfo); |
301 |
doInstall(installContainer); |
302 |
|
303 |
File module = new File(new File(getWorkDir(), "modules"), "org-netbeans-modules-mymodule.jar"); |
304 |
assertTrue("module file exists", module.exists()); |
305 |
assertTrue("module was not installed from NBM external", moduleUnit.getInstalled() != null); |
306 |
} |
307 |
|
308 |
|
309 |
|
310 |
public UpdateUnit getUpdateUnit(String codeNameBase) { |
311 |
UpdateUnit uu = UpdateManagerImpl.getInstance().getUpdateUnit(codeNameBase); |
312 |
assertNotNull(uu); |
313 |
return uu; |
314 |
} |
315 |
|
316 |
public UpdateElement getAvailableUpdate(UpdateUnit updateUnit, int idx) { |
317 |
List<UpdateElement> available = updateUnit.getAvailableUpdates(); |
318 |
assertTrue(available.size() > idx); |
319 |
return available.get(idx); |
320 |
|
321 |
} |
322 |
} |