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