diff -r 21298aae226f -r 73c9b84e15b9 apisupport.harness/manifest.mf --- a/apisupport.harness/manifest.mf Sun Jan 31 17:32:35 2010 +0100 +++ b/apisupport.harness/manifest.mf Wed Feb 03 15:37:22 2010 +0300 @@ -1,5 +1,5 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.modules.apisupport.harness -OpenIDE-Module-Specification-Version: 1.20 +OpenIDE-Module-Specification-Version: 1.21 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/apisupport/harness/Bundle.properties diff -r 21298aae226f -r 73c9b84e15b9 apisupport.harness/release/README --- a/apisupport.harness/release/README Sun Jan 31 17:32:35 2010 +0100 +++ b/apisupport.harness/release/README Wed Feb 03 15:37:22 2010 +0300 @@ -796,6 +796,10 @@ also define just ${nbjdk.home} directly, without using ${nbjdk.active}, if you do not need to use the Java Platform Manager to set up the JDK definition. +pack200.excludes [since 6.9] - comma- or space- separated list of patterns of +files relative to cluster directory for which pack200 compression should not be used +while creating NBMs. + project.license [since 6.0] - license to use for newly created files in the project (applies also to suites); default is 'cddl' for modules inside netbeans.org. diff -r 21298aae226f -r 73c9b84e15b9 autoupdate.services/libsrc/org/netbeans/updater/ModuleUpdater.java --- a/autoupdate.services/libsrc/org/netbeans/updater/ModuleUpdater.java Sun Jan 31 17:32:35 2010 +0100 +++ b/autoupdate.services/libsrc/org/netbeans/updater/ModuleUpdater.java Wed Feb 03 15:37:22 2010 +0300 @@ -291,6 +291,7 @@ } + /** Unpack the distribution files into update directory */ private void unpack () { @@ -356,11 +357,11 @@ try { jarFile = new JarFile (nbm); - Enumeration entries = jarFile.entries(); + Enumeration entries = jarFile.entries(); List executableFiles = readExecutableFilesList(jarFile); List filesToChmod = new ArrayList (); while( entries.hasMoreElements() ) { - JarEntry entry = (JarEntry) entries.nextElement(); + JarEntry entry = entries.nextElement(); checkStop(); if ( entry.getName().startsWith( UPDATE_NETBEANS_DIR ) ) { if (! entry.isDirectory ()) { @@ -370,11 +371,6 @@ } String pathTo = entry.getName ().substring (UPDATE_NETBEANS_DIR.length () + 1); // path without netbeans prefix - if ( mu.isL10n() ) - version.addL10NFileWithCrc( pathTo, Long.toString( entry.getCrc() ), mu.getSpecification_version()); - else - version.addFileWithCrc( pathTo, Long.toString( entry.getCrc() ) ); - File destFile = new File (cluster, entry.getName ().substring (UPDATE_NETBEANS_DIR.length())); if ( destFile.exists() ) { File bckFile = new File( getBackupDirectory (cluster), entry.getName() ); @@ -387,10 +383,27 @@ } else { destFile.getParentFile ().mkdirs (); } + bytesRead = copyStreams( jarFile.getInputStream( entry ), new FileOutputStream( destFile ), bytesRead ); if(executableFiles.contains(pathTo)) { filesToChmod.add(destFile); } + long crc = entry.getCrc(); + if(pathTo.endsWith(".jar.pack.gz") && + jarFile.getEntry(entry.getName().substring(0, entry.getName().lastIndexOf(".pack.gz")))==null) { + //check if file.jar.pack.gz does not exit for file.jar - then unpack current .pack.gz file + File unpacked = new File(destFile.getParentFile(), destFile.getName().substring(0, destFile.getName().lastIndexOf(".pack.gz"))); + unpack200(destFile, unpacked); + destFile.delete(); + pathTo = pathTo.substring(0, pathTo.length() - ".pack.gz".length()); + crc = UpdateTracking.getFileCRC(unpacked); + } + if ( mu.isL10n() ) { + version.addL10NFileWithCrc( pathTo, Long.toString(crc), mu.getSpecification_version()); + } else { + version.addFileWithCrc( pathTo, Long.toString(crc)); + } + UpdaterFrame.setProgressValue( bytesRead ); } } else if ( entry.getName().startsWith( UPDATE_MAIN_DIR )&& @@ -467,6 +480,28 @@ t.deleteUnusedFiles (); } } + + private boolean unpack200(File src, File dest) { + String unpack200Executable = new File(System.getProperty("java.home"), + "bin/unpack200" + (isWindows() ? ".exe" : "")).getAbsolutePath(); + ProcessBuilder pb = new ProcessBuilder(unpack200Executable, src.getAbsolutePath(), dest.getAbsolutePath()); + pb.directory(src.getParentFile()); + int result = 1; + try { + //maybe reuse start() method here? + Process process = pb.start(); + //TODO: Need to think of unpack200/lvprcsrv.exe issues + //https://netbeans.org/bugzilla/show_bug.cgi?id=117334 + //https://netbeans.org/bugzilla/show_bug.cgi?id=119861 + result = process.waitFor(); + process.destroy(); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return result == 0; + } private List readExecutableFilesList(JarFile jarFile) { List list = new ArrayList(); diff -r 21298aae226f -r 73c9b84e15b9 autoupdate.services/libsrc/org/netbeans/updater/UpdateTracking.java --- a/autoupdate.services/libsrc/org/netbeans/updater/UpdateTracking.java Sun Jan 31 17:32:35 2010 +0100 +++ b/autoupdate.services/libsrc/org/netbeans/updater/UpdateTracking.java Wed Feb 03 15:37:22 2010 +0300 @@ -508,8 +508,8 @@ bsrc = new BufferedInputStream( new FileInputStream( file ) ); byte[] bytes = new byte[1024]; int i; - while( (i = bsrc.read()) != -1 ) { - crc.update( (byte)i ); + while( (i = bsrc.read(bytes)) != -1 ) { + crc.update(bytes, 0, i ); } } finally { diff -r 21298aae226f -r 73c9b84e15b9 autoupdate.services/manifest.mf --- a/autoupdate.services/manifest.mf Sun Jan 31 17:32:35 2010 +0100 +++ b/autoupdate.services/manifest.mf Wed Feb 03 15:37:22 2010 +0300 @@ -1,7 +1,7 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.modules.autoupdate.services OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/autoupdate/services/resources/Bundle.properties -OpenIDE-Module-Specification-Version: 1.17 +OpenIDE-Module-Specification-Version: 1.18 OpenIDE-Module-Layer: org/netbeans/modules/autoupdate/services/resources/layer.xml AutoUpdate-Show-In-Client: false AutoUpdate-Essential-Module: true diff -r 21298aae226f -r 73c9b84e15b9 autoupdate.services/nbproject/project.properties --- a/autoupdate.services/nbproject/project.properties Sun Jan 31 17:32:35 2010 +0100 +++ b/autoupdate.services/nbproject/project.properties Wed Feb 03 15:37:22 2010 +0300 @@ -5,3 +5,4 @@ javadoc.arch=${basedir}/arch.xml javadoc.apichanges=${basedir}/apichanges.xml test.unit.cp.extra=${basedir}/modules/ext/updater.jar +pack200.excludes=modules/ext/updater.jar \ No newline at end of file diff -r 21298aae226f -r 73c9b84e15b9 autoupdate.services/test/unit/src/org/netbeans/modules/autoupdate/services/NbmPack200Test.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/autoupdate.services/test/unit/src/org/netbeans/modules/autoupdate/services/NbmPack200Test.java Wed Feb 03 15:37:22 2010 +0300 @@ -0,0 +1,341 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2010 Sun Microsystems, Inc. + */ +package org.netbeans.modules.autoupdate.services; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.jar.Attributes; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import java.util.jar.Pack200; +import java.util.zip.GZIPOutputStream; +import java.util.zip.ZipEntry; +import org.netbeans.api.autoupdate.InstallSupport; +import org.netbeans.api.autoupdate.OperationContainer; +import org.netbeans.api.autoupdate.OperationContainer.OperationInfo; +import org.netbeans.api.autoupdate.OperationException; +import org.netbeans.api.autoupdate.OperationSupport.Restarter; +import org.netbeans.api.autoupdate.TestUtils; +import org.netbeans.api.autoupdate.UpdateElement; +import org.netbeans.api.autoupdate.UpdateUnit; +import org.netbeans.api.autoupdate.UpdateUnitProvider; +import org.netbeans.api.autoupdate.UpdateUnitProviderFactory; +import org.netbeans.core.startup.MainLookup; +import org.netbeans.junit.NbTestCase; +import org.netbeans.modules.autoupdate.updateprovider.AutoupdateCatalogProvider; +import org.openide.filesystems.FileUtil; +import org.openide.util.Lookup; + +/** + * + * @author Dmitry Lipin + */ +public class NbmPack200Test extends NbTestCase { + + protected List keepItNotToGC; + private static File catalogFile; + private static URL catalogURL; + private File tmpDirectory; + private List nbms = new ArrayList(); + private List moduleElements = new ArrayList(); + + public NbmPack200Test(String testName) { + super(testName); + } + + public static class MyProvider extends AutoupdateCatalogProvider { + + public MyProvider() { + super("test-updates-provider", "test-updates-provider", catalogURL, UpdateUnitProvider.CATEGORY.STANDARD); + } + } + + private String getModuleElement(boolean visible, String codeName, String releaseVersion, String implVersion, String moduleName, String distr, String specVersion, String dependency) { + String releaseVersionAppendix = ((releaseVersion != null /*&& Integer.parseInt(releaseVersion)!=0*/) ? ("/" + releaseVersion) : ""); + return "\n" + + "\n ", ">") + "\" " : "") + + "\n OpenIDE-Module-Requires='org.openide.modules.ModuleFormat1' " + + "\n OpenIDE-Module-Specification-Version='" + specVersion + "'/>" + + "\n [NO LICENSE SPECIFIED]" + + "\n" + + "\n\n"; + } + + private String createInfoXML(boolean visible, String codeName, String releaseVersion, String implVersion, String moduleName, String distr, String specVersion, String dependency) { + String moduleElement = getModuleElement(visible, codeName, releaseVersion, implVersion, moduleName, distr, specVersion, dependency); + + moduleElements.add(moduleElement); + return "" + + "" + + moduleElement; + } + + private void writeCatalog() throws IOException { + String res = "\n" + + "" + + "\n"; + for (String element : moduleElements) { + res += element; + } + res += "\n"; + if (catalogFile == null) { + catalogFile = File.createTempFile("catalog-", ".xml", tmpDirectory); + catalogURL = catalogFile.toURI().toURL(); + } + PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(catalogFile), "UTF-8")); + pw.write(res); + pw.close(); + } + + private String getConfigXML(String codeName, String moduleFile, String specVersion) { + return "" + + " " + + " " + + " false" + + " false" + + " true" + + " modules/" + moduleFile + ".jar" + + " false" + + " " + specVersion + "" + + " "; + } + + private String getManifest(String codeName, String releaseVersion, String implVersion, String moduleDir, String specVersion, boolean visible, String dependency) { + String releaseVersionAppendix = ((releaseVersion != null /*&& Integer.parseInt(releaseVersion)!=0*/) ? ("/" + releaseVersion) : ""); + return "Manifest-Version: 1.0\n" + + "Ant-Version: Apache Ant 1.7.0\n" + + "Created-By: 1.6.0-b105 (Sun Microsystems Inc.)\n" + + "OpenIDE-Module-Public-Packages: -\n" + + "OpenIDE-Module-Java-Dependencies: Java > 1.4\n" + + "OpenIDE-Module-Implementation-Version: " + (implVersion == null ? "070130" : implVersion) + + "\n" + + (dependency != null ? ("OpenIDE-Module-Module-Dependencies: " + dependency + "\n") : "") + + "OpenIDE-Module: " + codeName + releaseVersionAppendix + + "\n" + + "OpenIDE-Module-Localizing-Bundle: " + moduleDir + "Bundle.properties\n" + + "OpenIDE-Module-Specification-Version: " + specVersion + "\n" + + "OpenIDE-Module-Requires: org.openide.modules.ModuleFormat1\n" + + "AutoUpdate-Show-In-Client: " + visible + "\n" + + "\n"; + } + + private File prepareNBM(String codeName, String releaseVersion, String implVersion, String specVersion, boolean visible, String dependency) throws Exception { + String moduleName = codeName.substring(codeName.lastIndexOf(".") + 1); + String moduleFile = codeName.replace(".", "-"); + String moduleDir = codeName.replace(".", "/") + "/"; + File nbm = File.createTempFile(moduleFile + "-", ".nbm", tmpDirectory); + + final String MODULE_NAME_PROP = "OpenIDE-Module-Name"; + + File jar = new File(tmpDirectory, "netbeans/modules/" + moduleFile + ".jar"); + jar.getParentFile().mkdirs(); + JarOutputStream jos = new JarOutputStream(new FileOutputStream(jar)); + int idx = moduleDir.indexOf("/"); + while (idx != -1) { + jos.putNextEntry(new ZipEntry(moduleDir.substring(0, idx + 1))); + idx = moduleDir.indexOf("/", idx + 1); + } + + jos.putNextEntry(new ZipEntry(moduleDir + "Bundle.properties")); + jos.write(new String(MODULE_NAME_PROP + "=" + moduleName).getBytes("UTF-8")); + jos.putNextEntry(new ZipEntry("META-INF/")); + jos.putNextEntry(new ZipEntry("META-INF/manifest.mf")); + jos.write(getManifest(codeName, releaseVersion, implVersion, moduleDir, specVersion, visible, dependency).getBytes("UTF-8")); + jos.close(); + File jarPackGz = new File(jar.getParentFile(), jar.getName() + ".pack.gz"); + assertEquals("Cannot compress jar using pack200", pack200(jar, jarPackGz), true); + jar.delete(); + + + Manifest mf = new Manifest(); + mf.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); + + + jos = new JarOutputStream(new FileOutputStream(nbm), mf); + jos.putNextEntry(new ZipEntry("Info/")); + jos.putNextEntry(new ZipEntry("Info/info.xml")); + jos.write(createInfoXML(visible, codeName, releaseVersion, implVersion, moduleName, nbm.toURI().toURL().toString(), specVersion, dependency).getBytes("UTF-8")); + + jos.putNextEntry(new ZipEntry("netbeans/")); + jos.putNextEntry(new ZipEntry("netbeans/modules/")); + jos.putNextEntry(new ZipEntry("netbeans/config/")); + jos.putNextEntry(new ZipEntry("netbeans/config/Modules/")); + jos.putNextEntry(new ZipEntry("netbeans/config/Modules/" + moduleFile + ".xml")); + + jos.write(getConfigXML(codeName, moduleFile, specVersion).getBytes("UTF-8")); + + + jos.putNextEntry(new ZipEntry("netbeans/modules/" + moduleFile + ".jar.pack.gz")); + + FileInputStream fis = new FileInputStream(jarPackGz); + FileUtil.copy(fis, jos); + fis.close(); + jarPackGz.delete(); + jos.close(); + nbms.add(nbm); + + return nbm; + } + + private boolean pack200(final File sourceFile, final File targetFile) throws IOException { + OutputStream outputStream = null; + JarFile jarFile = null; + boolean result = false; + try { + jarFile = new JarFile(sourceFile); + outputStream = new GZIPOutputStream(new FileOutputStream(targetFile)); + Pack200.newPacker().pack(jarFile, outputStream); + result = true; + } finally { + if (jarFile != null) { + try { + jarFile.close(); + } catch (IOException e) { + } + } + if (outputStream != null) { + try { + outputStream.close(); + } catch (IOException e) { + } + } + } + return result; + } + + protected void setUp() throws Exception { + super.setUp(); + this.clearWorkDir(); + tmpDirectory = new File(getWorkDirPath(), "tmp"); + tmpDirectory.mkdirs(); + + writeCatalog(); + + TestUtils.setUserDir(getWorkDirPath()); + TestUtils.testInit(); + + MainLookup.register(new MyProvider()); + assert Lookup.getDefault().lookup(MyProvider.class) != null; + UpdateUnitProviderFactory.getDefault().refreshProviders(null, true); + } + + private void doInstall(OperationContainer installContainer) throws OperationException { + InstallSupport support = installContainer.getSupport(); + assertNotNull(support); + + InstallSupport.Validator v = support.doDownload(null, false); + assertNotNull(v); + InstallSupport.Installer i = support.doValidate(v, null); + assertNotNull(i); + Restarter r = null; + try { + r = support.doInstall(i, null); + } catch (OperationException ex) { + if (OperationException.ERROR_TYPE.INSTALL == ex.getErrorType()) { + // can ingore + // module system cannot load the module either + } else { + fail(ex.toString()); + } + } + assertNull("Installing new element require restarting though it should not", r); + } + + + public void testNbmWithPack200Compression() throws Exception { + String moduleCNB = "org.netbeans.modules.mymodule"; + String moduleReleaseVersion = "1"; + String moduleImplVersion = "2"; + String moduleSpecVersion = "1.0"; + + prepareNBM(moduleCNB, moduleReleaseVersion, moduleImplVersion, moduleSpecVersion, false, null); + + writeCatalog(); + UpdateUnitProviderFactory.getDefault().refreshProviders(null, true); + OperationContainer installContainer = OperationContainer.createForInstall(); + UpdateUnit moduleUnit = getUpdateUnit(moduleCNB); + assertNull("cannot be installed", moduleUnit.getInstalled()); + UpdateElement moduleElement = getAvailableUpdate(moduleUnit, 0); + assertEquals(moduleElement.getSpecificationVersion(), moduleSpecVersion); + OperationInfo independentInfo = installContainer.add(moduleElement); + assertNotNull(independentInfo); + doInstall(installContainer); + assertTrue("module was not installed from NBM with pack200 compression", moduleUnit.getInstalled() != null); + assertTrue("module was not enabled after installation from NBM with pack200 compression", moduleUnit.getInstalled().isEnabled()); + } + + + + public UpdateUnit getUpdateUnit(String codeNameBase) { + UpdateUnit uu = UpdateManagerImpl.getInstance().getUpdateUnit(codeNameBase); + assertNotNull(uu); + return uu; + } + + public UpdateElement getAvailableUpdate(UpdateUnit updateUnit, int idx) { + List available = updateUnit.getAvailableUpdates(); + assertTrue(available.size() > idx); + return available.get(idx); + + } +} diff -r 21298aae226f -r 73c9b84e15b9 nbbuild/antsrc/org/netbeans/nbbuild/AutoUpdate.java --- a/nbbuild/antsrc/org/netbeans/nbbuild/AutoUpdate.java Sun Jan 31 17:32:35 2010 +0100 +++ b/nbbuild/antsrc/org/netbeans/nbbuild/AutoUpdate.java Wed Feb 03 15:37:22 2010 +0300 @@ -39,9 +39,11 @@ package org.netbeans.nbbuild; +import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @@ -239,25 +241,39 @@ if (zipEntry.getName().endsWith("/")) { continue; } - final String relName = zipEntry.getName().substring(9); + String relName = zipEntry.getName().substring(9); File trgt = new File(whereTo, relName.replace('/', File.separatorChar)); trgt.getParentFile().mkdirs(); log("Writing " + trgt, Project.MSG_VERBOSE); InputStream is = zf.getInputStream(zipEntry); OutputStream os = new FileOutputStream(trgt); + boolean doUnpack200 = false; + if(relName.endsWith(".jar.pack.gz") && zf.getEntry(zipEntry.getName().substring(0, zipEntry.getName().length() + 8))==null) { + doUnpack200 = true; + } CRC32 crc = new CRC32(); for (;;) { int len = is.read(bytes); if (len == -1) { break; } - crc.update(bytes, 0, len); + if(!doUnpack200) { + crc.update(bytes, 0, len); + } os.write(bytes, 0, len); } is.close(); os.close(); - config.write((" \n").getBytes("UTF-8")); + long crcValue = crc.getValue(); + if(doUnpack200) { + File dest = new File(trgt.getParentFile(), trgt.getName().substring(0, trgt.getName().length() - 8)); + unpack200(trgt, dest); + trgt.delete(); + crcValue = getFileCRC(dest); + relName = relName.substring(0, relName.length() - 8); + } + config.write((" \n").getBytes("UTF-8")); } config.write(" \n\n".getBytes("UTF-8")); config.close(); @@ -274,6 +290,53 @@ } } + private boolean unpack200(File src, File dest) { + // Copy of ModuleUpdater.unpack200 + + log("Unpacking " + src + " to " + dest, Project.MSG_VERBOSE); + String unpack200Executable = new File(System.getProperty("java.home"), + "bin/unpack200" + (isWindows() ? ".exe" : "")).getAbsolutePath(); + ProcessBuilder pb = new ProcessBuilder(unpack200Executable, src.getAbsolutePath(), dest.getAbsolutePath()); + pb.directory(src.getParentFile()); + int result = 1; + try { + //maybe reuse start() method here? + Process process = pb.start(); + //TODO: Need to think of unpack200/lvprcsrv.exe issues + //https://netbeans.org/bugzilla/show_bug.cgi?id=117334 + //https://netbeans.org/bugzilla/show_bug.cgi?id=119861 + result = process.waitFor(); + process.destroy(); + } catch (IOException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return result == 0; + } + private static boolean isWindows() { + String os = System.getProperty("os.name"); // NOI18N + return (os != null && os.toLowerCase().startsWith("windows"));//NOI18N + } + + private static long getFileCRC(File file) throws IOException { + BufferedInputStream bsrc = null; + CRC32 crc = new CRC32(); + try { + bsrc = new BufferedInputStream( new FileInputStream( file ) ); + byte[] bytes = new byte[1024]; + int i; + while( (i = bsrc.read(bytes)) != -1 ) { + crc.update(bytes, 0, i ); + } + } + finally { + if ( bsrc != null ) + bsrc.close(); + } + return crc.getValue(); + } + private boolean matches(String cnb, String targetCluster) { for (Modules ps : modules) { if (ps.clusters != null) { diff -r 21298aae226f -r 73c9b84e15b9 nbbuild/antsrc/org/netbeans/nbbuild/MakeNBM.java --- a/nbbuild/antsrc/org/netbeans/nbbuild/MakeNBM.java Sun Jan 31 17:32:35 2010 +0100 +++ b/nbbuild/antsrc/org/netbeans/nbbuild/MakeNBM.java Wed Feb 03 15:37:22 2010 +0300 @@ -58,6 +58,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Date; +import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Locale; @@ -66,8 +67,12 @@ import java.util.StringTokenizer; import java.util.jar.Attributes; import java.util.jar.Attributes.Name; +import java.util.jar.JarEntry; import java.util.jar.JarFile; +import java.util.jar.Pack200; +import java.util.jar.Pack200.Packer; import java.util.zip.CRC32; +import java.util.zip.GZIPOutputStream; import java.util.zip.ZipEntry; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; @@ -323,6 +328,9 @@ private Attributes englishAttr = null; private Path updaterJar; private FileSet executablesSet; + private boolean usePack200; + private String pack200excludes; + private final static Packer packer = Pack200.newPacker(); /** Try to find and create localized info.xml files */ public void setLocales(String s) { @@ -346,6 +354,14 @@ this.file = file; } + public void setUsePack200(boolean usePack200) { + this.usePack200 = usePack200; + } + + public void setPack200Excludes(String pack200excludes) { + this.pack200excludes = pack200excludes; + } + /** List of executable files in NBM concatinated by ${line.separator}. */ public FileSet createExecutables() { return (executablesSet = new FileSet()); @@ -648,8 +664,66 @@ ZipFileSet fs = new ZipFileSet(); List moduleFiles = new ArrayList (); fs.setDir( productDir ); - for (int i=0; i < files.length; i++) { - fs.createInclude().setName( files[i] ); + String [] filesForPackaging = null; + if(usePack200 && pack200excludes!=null && !pack200excludes.equals("")) { + FileSet pack200Files = new FileSet(); + pack200Files.setDir(productDir); + pack200Files.setExcludes(pack200excludes); + pack200Files.setProject(getProject()); + for (int i=0; i < files.length; i++) { + pack200Files.createInclude().setName( files[i] ); + } + DirectoryScanner ds = pack200Files.getDirectoryScanner(); + ds.scan(); + filesForPackaging = ds.getIncludedFiles(); + } + + List packedFiles = new ArrayList(); + for (int i = 0; i < files.length; i++) { + if (usePack200) { + File sourceFile = new File(productDir, files[i]); + if (sourceFile.isFile() && sourceFile.getName().endsWith(".jar")) { + + boolean doPackage = true; + if (filesForPackaging != null) { + doPackage = false; + for (String f : filesForPackaging) { + if (new File(productDir, f).equals(sourceFile)) { + doPackage = true; + break; + } + } + } + if(doPackage) { + //if both .jar and .jad exist - skip it + //if both .jar and .jar.pack.gz exist - skip it + for (String f : files) { + if(f.equals(files[i].substring(0, files[i].lastIndexOf(".jar")) + ".jad") || + f.equals(files[i] + ".pack.gz")) { + doPackage = false; + break; + } + } + + } + if (doPackage) { + File targetFile = new File(productDir, files[i] + ".pack.gz"); + try { + if (pack200(sourceFile, targetFile)) { + packedFiles.add(targetFile); + files[i] = files[i] + ".pack.gz"; + } + } catch (IOException e) { + if(targetFile.exists()) { + targetFile.delete(); + } + log("Can`t pack file " + sourceFile, e, Project.MSG_WARN); + } + } + } + } + + fs.createInclude().setName(files[i]); moduleFiles.add(files[i]); } fs.setPrefix("netbeans/"); @@ -715,6 +789,9 @@ jar.setLocation(getLocation()); jar.init (); jar.execute (); + for(File f : packedFiles) { + f.delete(); + } // Print messages if we overrode anything. // if (nbm.lastModified() != jarModified) { @@ -766,6 +843,63 @@ } } + private boolean isSigned(final JarFile jar) throws IOException { + Enumeration entries = jar.entries(); + boolean signatureInfoPresent = false; + boolean signatureFilePresent = false; + while (entries.hasMoreElements()) { + String entryName = entries.nextElement().getName(); + if (entryName.startsWith("META-INF/")) { + if (entryName.endsWith(".RSA") || entryName.endsWith(".DSA")) { + signatureFilePresent = true; + if (signatureInfoPresent) { + break; + } + } else if (entryName.endsWith(".SF")) { + signatureInfoPresent = true; + if (signatureFilePresent) { + break; + } + } + } + } + return signatureFilePresent && signatureInfoPresent; + } + + private boolean pack200(final File sourceFile, final File targetFile) throws IOException { + OutputStream outputStream = null; + JarFile jarFile = null; + boolean result = false; + try { + jarFile = new JarFile(sourceFile); + if(!isSigned(jarFile)) { + outputStream = new GZIPOutputStream(new FileOutputStream(targetFile)); + packer.pack(jarFile, outputStream); + result = true; + } + } finally { + if(jarFile!=null) { + try { + jarFile.close(); + } catch (IOException e) { + log("Cannot close output stream jar for file " + sourceFile, e, Project.MSG_WARN); + } + } + if(outputStream!=null) { + try { + outputStream.close(); + } catch (IOException e) { + log("Cannot close output stream for file " + targetFile, e, Project.MSG_WARN); + } + if(result) { + targetFile.setLastModified(sourceFile.lastModified()); + } + } + } + return result; + } + + private Document createInfoXml(final Attributes attr) throws BuildException { DOMImplementation domimpl; try { diff -r 21298aae226f -r 73c9b84e15b9 nbbuild/templates/common.xml --- a/nbbuild/templates/common.xml Sun Jan 31 17:32:35 2010 +0100 +++ b/nbbuild/templates/common.xml Wed Feb 03 15:37:22 2010 +0300 @@ -407,6 +407,8 @@ + +