diff --git a/apisupport.harness/release/suite.xml b/apisupport.harness/release/suite.xml --- a/apisupport.harness/release/suite.xml +++ b/apisupport.harness/release/suite.xml @@ -210,7 +210,16 @@ - + + + + + + + + + + diff --git a/autoupdate.services/libsrc/org/netbeans/updater/resources/autoupdate-catalog-2_6.dtd b/autoupdate.services/libsrc/org/netbeans/updater/resources/autoupdate-catalog-2_6.dtd new file mode 100644 --- /dev/null +++ b/autoupdate.services/libsrc/org/netbeans/updater/resources/autoupdate-catalog-2_6.dtd @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/autoupdate.services/src/org/netbeans/modules/autoupdate/services/UpdateLicenseImpl.java b/autoupdate.services/src/org/netbeans/modules/autoupdate/services/UpdateLicenseImpl.java --- a/autoupdate.services/src/org/netbeans/modules/autoupdate/services/UpdateLicenseImpl.java +++ b/autoupdate.services/src/org/netbeans/modules/autoupdate/services/UpdateLicenseImpl.java @@ -41,6 +41,9 @@ package org.netbeans.modules.autoupdate.services; +import java.net.URL; +import org.netbeans.modules.autoupdate.updateprovider.AutoupdateCatalogCache; + /** * * @author Jiri Rechtacek @@ -48,23 +51,44 @@ public final class UpdateLicenseImpl { private String name; private String agreement; + private URL url; /** Creates a new instance of UpdateLicense */ public UpdateLicenseImpl (String licenseName, String agreement) { this.name = licenseName; this.agreement = agreement; } + /** Creates a new instance of UpdateLicense */ + public UpdateLicenseImpl (String licenseName, String agreement, URL url) { + this.name = licenseName; + this.url = url; + setAgreement(agreement); + } public String getName () { return name; } - + public URL getURL() { + return url; + } public String getAgreement () { - return agreement; + if(agreement!=null) { + return agreement; + } else if (url!=null) { + return AutoupdateCatalogCache.getDefault().getLicense(name,url); + } else { + return null; + } } - + public void setUrl(URL url) { + this.url = url; + } public void setAgreement (String content) { - this.agreement = content; + if(content!=null) { + AutoupdateCatalogCache.getDefault().storeLicense(name,content); + } else { + agreement = null; + } } } diff --git a/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/AutoupdateCatalogCache.java b/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/AutoupdateCatalogCache.java --- a/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/AutoupdateCatalogCache.java +++ b/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/AutoupdateCatalogCache.java @@ -41,12 +41,10 @@ package org.netbeans.modules.autoupdate.updateprovider; -import java.io.BufferedOutputStream; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.logging.Level; @@ -60,7 +58,7 @@ */ public class AutoupdateCatalogCache { private File cacheDir; - private Exception storedException; + private static AutoupdateCatalogCache INSTANCE; @@ -89,6 +87,7 @@ cacheDir = new File(dir, "catalogcache"); // NOI18N } cacheDir.mkdirs(); + getLicenseDir().mkdirs(); err.log (Level.FINE, "getCacheDirectory: " + cacheDir.getPath ()); return; } @@ -100,7 +99,7 @@ assert dir != null && dir.exists () : "Cache directory must exist."; File cache = new File (dir, codeName); - copy (original, cache); + copy(original, cache, false); try { url = cache.toURI ().toURL (); @@ -137,8 +136,91 @@ return null; } } + private File getLicenseDir() { + return new File(getCatalogCache(), "licenses"); + } + + private File getLicenseFile(String name) { + return new File(getLicenseDir(), name); + } + + public String getLicense(String name) { + return getLicense(name, null); + } + + public String getLicense(String name, URL url) { + synchronized (name.intern()) { + File file = getLicenseFile(name); + if (!file.exists()) { + if (url == null) { + return null; + } + try { + copy(url, file, true); + } catch (IOException e) { + // if can`t get the license, treat it as empty but delete it on exit + err.log(Level.INFO, "Can`t store license from " + url + " to " + file, e); + try { + if (file.exists()) { + file.delete(); + } + file.createNewFile(); + file.deleteOnExit(); // + + } catch (IOException ex) { + err.log(Level.INFO, "Can`t create empty license file", ex); + } + } + } + return readFile(file); + } + } + + public void storeLicense(String name, String content) { + synchronized (name.intern()) { + File file = getLicenseFile(name); + if (file.exists() || content == null) { + return; + } + writeToFile(content, file); + } + } - private void copy (final URL sourceUrl, final File cache) throws IOException { + private String readFile(File file) { + try { + FileInputStream fr = new FileInputStream(file); + byte[] buffer = new byte[8192]; + int n = 0; + StringBuilder sb = new StringBuilder(); + while ((n = fr.read(buffer)) != -1) { + sb.append(new String(buffer, 0, n, "utf-8"));//NOI18N + } + return sb.toString(); + } catch (IOException e) { + err.log(Level.INFO, "Can`t read license from file " + file, e); + return null; + } + } + private void writeToFile(String content, File file) { + FileOutputStream fw = null; + try { + fw = new FileOutputStream(file); + fw.write(content.getBytes("utf-8")); //NOI18N + } catch (IOException e) { + err.log(Level.INFO, "Can`t write to " + file, e); + } finally { + if (fw != null) { + try { + fw.flush(); + fw.close(); + } catch (IOException e) { + err.log(Level.INFO, "Can`t output stream for " + file, e); + } + } + } + } + + private void copy (final URL sourceUrl, final File cache, final boolean allowZeroSize) throws IOException { // -- create NetworkListener // -- request stream // -- report success or IOException @@ -151,124 +233,13 @@ prefix += cache.getName(); } final File temp = File.createTempFile (prefix, null, cache.getParentFile ()); //NOI18N - temp.deleteOnExit(); - storeException (null); + temp.deleteOnExit(); - NetworkAccess.NetworkListener nwl = new NetworkAccess.NetworkListener () { - - public void streamOpened (InputStream stream, int contentLength) { - err.log (Level.FINE, "Successfully started reading URI " + sourceUrl); - try { - doCopy (sourceUrl, stream, cache, temp, contentLength); - } catch (IOException ex) { - storeException (ex); - } - } - - public void accessCanceled () { - err.log (Level.FINE, "Processing " + sourceUrl + " was cancelled."); - storeException (new IOException ("Processing " + sourceUrl + " was cancelled.")); - } - - public void accessTimeOut () { - err.log (Level.FINE, "Timeout when processing " + sourceUrl); - storeException (new IOException ("Timeout when processing " + sourceUrl)); - } - - public void notifyException (Exception x){ - err.log (Level.INFO, - "Reading URL " + sourceUrl + " failed (" + x + - ")"); - storeException (x); - } - - }; + DownloadListener nwl = new DownloadListener(sourceUrl, cache, temp,allowZeroSize); NetworkAccess.Task task = NetworkAccess.createNetworkAcessTask (sourceUrl, AutoupdateSettings.getOpenConnectionTimeout (), nwl); task.waitFinished (); - notifyException (); + nwl.notifyException (); } - - private void notifyException () throws IOException { - if (isExceptionStored ()) { - throw new IOException (getStoredException ().getLocalizedMessage ()); - } - } - - private boolean isExceptionStored () { - return storedException != null; - } - - private void storeException (Exception x) { - storedException = x; - } - - private Exception getStoredException () { - return storedException; - } - - private void doCopy (URL sourceUrl, InputStream is, File cache, File temp, int contentLength) throws IOException { - - OutputStream os = null; - int read = 0; - int totalRead = 0; - - try { - os = new BufferedOutputStream(new FileOutputStream (temp)); - byte [] bytes = new byte [1024]; - while ((read = is.read (bytes)) != -1) { - os.write (bytes, 0, read); - totalRead+=read; - } - is.close (); - os.flush (); - os.close (); - os = null; - if(contentLength!=-1 && contentLength!=totalRead) { - err.log(Level.INFO, "Content length was reported as " + contentLength + " bytes, but read " + totalRead + " bytes from " + sourceUrl); - throw new IOException("unexpected closed connection to " + sourceUrl); - } - if(totalRead==0) { - err.log(Level.INFO, "Connection content length was " + contentLength + " bytes (read " + totalRead + "bytes), catalog size can`t be that size - likely server with catalog at " + sourceUrl + " is temporary down"); - throw new IOException("zero sized catalog reported at " + sourceUrl); - } - synchronized (this) { - if (cache.exists () && ! cache.delete ()) { - err.log (Level.INFO, "Cannot delete cache " + cache); - try { - Thread.sleep(200); - } catch (InterruptedException ie) { - assert false : ie; - } - cache.delete(); - } - } - err.log (Level.INFO, "Read " + totalRead + " bytes from catalog at " + sourceUrl); - - if(temp.length()==0) { - err.log (Level.INFO, "Temp cache size is zero bytes"); - } - if (! temp.renameTo (cache)) { - err.log (Level.INFO, "Cannot rename temp " + temp + " to cache " + cache); - } - if(cache.exists() && cache.length()==0) { - err.log (Level.INFO, "Final cache size is zero bytes"); - } - } catch (IOException ioe) { - err.log (Level.INFO, "Writing content of URL " + sourceUrl + " failed.", ioe); - throw ioe; - } finally { - try { - if (is != null) is.close (); - if (os != null) { - os.flush (); - os.close (); - } - } catch (IOException ioe) { - err.log (Level.INFO, "Closing streams failed.", ioe); - } - } - - } - + } diff --git a/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/AutoupdateCatalogParser.java b/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/AutoupdateCatalogParser.java --- a/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/AutoupdateCatalogParser.java +++ b/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/AutoupdateCatalogParser.java @@ -52,7 +52,9 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Stack; @@ -118,6 +120,7 @@ private static final String MODULE_ATTR_EAGER = "eager"; // NOI18N private static final String MODULE_ATTR_AUTOLOAD = "autoload"; // NOI18N private static final String MODULE_ATTR_LICENSE = "license"; // NOI18N + private static final String LICENSE_ATTR_URL = "url"; // NOI18N private static final String MANIFEST_ATTR_SPECIFICATION_VERSION = "OpenIDE-Module-Specification-Version"; // NOI18N @@ -187,7 +190,7 @@ private Stack currentGroup = new Stack (); private String catalogDate; private Stack currentModule = new Stack (); - private Stack currentLicense = new Stack (); + private Stack> currentLicense = new Stack> (); private Stack currentNotificationUrl = new Stack (); private Map name2license = new HashMap (); private List lines = new ArrayList (); @@ -253,23 +256,24 @@ break; case license : assert ! currentLicense.empty () : "Premature end of license " + qName; - - if (! lines.isEmpty ()) { - - // find and fill UpdateLicenseImpl - StringBuffer sb = new StringBuffer (bufferInitSize); - for (String line : lines) { - sb.append (line); + Map curLic = currentLicense.peek (); + String licenseName = curLic.keySet().iterator().next(); + Collection values = curLic.values(); + String licenseUrl = (values.size() > 0) ? values.iterator().next() : null; + UpdateLicenseImpl updateLicenseImpl = this.name2license.get (licenseName); + if (updateLicenseImpl == null) { + ERR.info("Unpaired license " + licenseName + " without any module."); + } else { + if (!lines.isEmpty()) { + // find and fill UpdateLicenseImpl + StringBuffer sb = new StringBuffer(bufferInitSize); + for (String line : lines) { + sb.append(line); + } + updateLicenseImpl.setAgreement(sb.toString()); + } else if (licenseUrl != null) { + updateLicenseImpl.setUrl(getDistribution(licenseUrl, baseUri)); } - UpdateLicenseImpl updateLicenseImpl = this.name2license.get (currentLicense.peek ()); - // in invalid catalog might be a un-paired license - // assert updateLicenseImpl != null : "UpdateLicenseImpl found in map for key " + currentLicense.peek (); - if (updateLicenseImpl != null) { - updateLicenseImpl.setAgreement (sb.toString ()); - } else { - ERR.info ("Unpaired license " + currentLicense.peek () + " without any module."); - } - } currentLicense.pop (); @@ -356,7 +360,9 @@ ERR.info ("Not supported yet."); break; case license : - currentLicense.push (attributes.getValue (LICENSE_ATTR_NAME)); + Map map = new HashMap (); + map.put(attributes.getValue (LICENSE_ATTR_NAME), attributes.getValue (LICENSE_ATTR_URL)); + currentLicense.push (map); break; default: ERR.warning ("Unknown element " + qName); diff --git a/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/DownloadListener.java b/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/DownloadListener.java new file mode 100644 --- /dev/null +++ b/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/DownloadListener.java @@ -0,0 +1,190 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2009 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 2009 Sun Microsystems, Inc. + */ +package org.netbeans.modules.autoupdate.updateprovider; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author dlm198383 + */ +public class DownloadListener implements NetworkAccess.NetworkListener { + + private Exception storedException; + private File cache; + private File temp; + private URL sourceUrl; + private boolean allowZeroLength; + + public DownloadListener(URL sourceUrl, File cache, File temp, boolean allowZeroLength) { + this.sourceUrl = sourceUrl; + this.cache = cache; + this.temp = temp; + this.allowZeroLength = allowZeroLength; + } + private Logger err = Logger.getLogger(this.getClass().getName()); + + public void streamOpened(InputStream stream, int contentLength) { + err.log(Level.FINE, "Successfully started reading URI " + sourceUrl); + try { + doCopy(sourceUrl, stream, cache, temp, contentLength); + } catch (IOException ex) { + storeException(ex); + } + } + + public void accessCanceled() { + err.log(Level.FINE, "Processing " + sourceUrl + " was cancelled."); + storeException(new IOException("Processing " + sourceUrl + " was cancelled.")); + } + + public void accessTimeOut() { + err.log(Level.FINE, "Timeout when processing " + sourceUrl); + storeException(new IOException("Timeout when processing " + sourceUrl)); + } + + public void notifyException(Exception x) { + err.log(Level.INFO, + "Reading URL " + sourceUrl + " failed (" + x + + ")"); + storeException(x); + } + + public void notifyException() throws IOException { + if (isExceptionStored()) { + throw new IOException(getStoredException().getLocalizedMessage()); + } + + } + + private boolean isExceptionStored() { + return storedException != null; + } + + private void storeException(Exception x) { + storedException = x; + } + + private Exception getStoredException() { + return storedException; + } + + private void doCopy(URL sourceUrl, InputStream is, File cache, File temp, int contentLength) throws IOException { + + OutputStream os = null; + int read = 0; + int totalRead = 0; + + try { + os = new BufferedOutputStream(new FileOutputStream(temp)); + byte[] bytes = new byte[1024]; + while ((read = is.read(bytes)) != -1) { + os.write(bytes, 0, read); + totalRead += read; + + } + + is.close(); + os.flush(); + os.close(); + os = null; + if (contentLength != -1 && contentLength != totalRead) { + err.log(Level.INFO, "Content length was reported as " + contentLength + " bytes, but read " + totalRead + " bytes from " + sourceUrl); + throw new IOException("unexpected closed connection to " + sourceUrl); + } + + if (totalRead == 0 && !allowZeroLength) { + err.log(Level.INFO, "Connection content length was " + contentLength + " bytes (read " + totalRead + "bytes), expected file size can`t be that size - likely server with file at " + sourceUrl + " is temporary down"); + throw new IOException("zero sized file reported at " + sourceUrl); + } + + synchronized (this) { + if (cache.exists() && !cache.delete()) { + err.log(Level.INFO, "Cannot delete cache " + cache); + try { + Thread.sleep(200); + } catch (InterruptedException ie) { + assert false : ie; + } + + cache.delete(); + } + + } + err.log(Level.INFO, "Read " + totalRead + " bytes from file at " + sourceUrl); + + if (temp.length() == 0) { + err.log(Level.INFO, "Temp cache size is zero bytes"); + } + + if (!temp.renameTo(cache)) { + err.log(Level.INFO, "Cannot rename temp " + temp + " to cache " + cache); + } + + if (cache.exists() && cache.length() == 0) { + err.log(Level.INFO, "Final cache size is zero bytes"); + } + + } catch (IOException ioe) { + err.log(Level.INFO, "Writing content of URL " + sourceUrl + " failed.", ioe); + throw ioe; + } finally { + try { + if (is != null) { + is.close(); + } + if (os != null) { + os.flush(); + os.close(); + } + + } catch (IOException ioe) { + err.log(Level.INFO, "Closing streams failed.", ioe); + } + } + } +} diff --git a/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/NetworkAccess.java b/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/NetworkAccess.java --- a/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/NetworkAccess.java +++ b/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/NetworkAccess.java @@ -75,7 +75,7 @@ } private void postTask () { - final SizedConnection connectTask = createCallableNetwork (url, timeout); + final SizedConnection connectTask = createCallableNetwork (url, timeout); rpTask = RequestProcessor.getDefault ().post (new Runnable () { public void run () { connect = es.submit (connectTask); @@ -103,8 +103,8 @@ rpTask.waitFinished (); } - private SizedConnection createCallableNetwork (final URL url, final int timeout) { - return new SizedConnection () { + private SizedConnection createCallableNetwork (final URL url, final int timeout) { + return new SizedConnection () { private int contentLength = -1; public int getContentLength() { @@ -126,7 +126,7 @@ } } - private interface SizedConnection extends Callable { + private interface SizedConnection extends Callable { public int getContentLength(); } public interface NetworkListener { diff --git a/autoupdate.services/src/org/netbeans/spi/autoupdate/UpdateLicense.java b/autoupdate.services/src/org/netbeans/spi/autoupdate/UpdateLicense.java --- a/autoupdate.services/src/org/netbeans/spi/autoupdate/UpdateLicense.java +++ b/autoupdate.services/src/org/netbeans/spi/autoupdate/UpdateLicense.java @@ -41,6 +41,7 @@ package org.netbeans.spi.autoupdate; +import java.net.URL; import org.netbeans.modules.autoupdate.services.UpdateLicenseImpl; /** Represents License Agreement for usage in Autoupdate infrastructure. @@ -64,5 +65,14 @@ public static final UpdateLicense createUpdateLicense (String licenseName, String agreement) { return new UpdateLicense (new UpdateLicenseImpl (licenseName, agreement)); } - + + /** + * + * @param licenseName name of license + * @param agreementUrl URL to the license agreement + * @return UpdateLicense + */ + public static final UpdateLicense createUpdateLicense (String licenseName, String agreement, URL agreementUrl) { + return new UpdateLicense (new UpdateLicenseImpl (licenseName, agreement, agreementUrl)); + } } diff --git a/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/wizards/InstallUnitWizardIterator.java b/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/wizards/InstallUnitWizardIterator.java --- a/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/wizards/InstallUnitWizardIterator.java +++ b/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/wizards/InstallUnitWizardIterator.java @@ -44,6 +44,7 @@ import java.util.ArrayList; import java.util.List; import java.util.NoSuchElementException; +import java.util.logging.Logger; import javax.swing.event.ChangeListener; import org.openide.WizardDescriptor; import org.openide.util.NbBundle; @@ -128,12 +129,14 @@ // If nothing unusual changes in the middle of the wizard, simply: public void addChangeListener (ChangeListener l) {} public void removeChangeListener (ChangeListener l) {} - + private void compactPanels () { if (isCompact) { return ; } - if (getModel ().allLicensesApproved ()) { + + boolean allLicensesTouched = getModel().allLicensesTouched(); + if (allLicensesTouched && getModel ().allLicensesApproved ()) { panels.remove (licenseApprovalStep); } if (! getModel ().hasCustomComponents ()) { @@ -142,7 +145,7 @@ if (! getModel ().hasStandardComponents ()) { panels.remove (installStep); } - isCompact = true; + isCompact = allLicensesTouched; } } diff --git a/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/wizards/InstallUnitWizardModel.java b/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/wizards/InstallUnitWizardModel.java --- a/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/wizards/InstallUnitWizardModel.java +++ b/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/wizards/InstallUnitWizardModel.java @@ -67,6 +67,7 @@ private OperationContainer updateContainer = null; private OperationContainer customContainer = Containers.forCustomInstall (); private PluginManagerUI manager; + private boolean allLicensesTouched = false; /** Creates a new instance of InstallUnitWizardModel */ public InstallUnitWizardModel (OperationType doOperation, OperationContainer updateContainer) { @@ -129,11 +130,16 @@ break; } } + allLicensesTouched = true; return res; + } + public boolean allLicensesTouched() { + return allLicensesTouched; } public void addApprovedLicenses (Collection licences) { approvedLicences.addAll (licences); + allLicensesTouched = false; } public InstallSupport getInstallSupport () { diff --git a/nbbuild/antsrc/org/netbeans/nbbuild/MakeUpdateDesc.java b/nbbuild/antsrc/org/netbeans/nbbuild/MakeUpdateDesc.java --- a/nbbuild/antsrc/org/netbeans/nbbuild/MakeUpdateDesc.java +++ b/nbbuild/antsrc/org/netbeans/nbbuild/MakeUpdateDesc.java @@ -51,6 +51,7 @@ import org.apache.tools.ant.DirectoryScanner; import java.io.File; import java.io.FileOutputStream; +import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -163,6 +164,13 @@ dist_base = dbase; } + private boolean useLicenseUrl; + + + public void setUseLicenseUrl(boolean useLicenseUrl) { + this.useLicenseUrl = useLicenseUrl; + } + private Path updaterJar; /** Fileset for platform/modules/ext/updater.jar, to be used in DTD validation. */ public Path createUpdaterJar() { @@ -269,7 +277,9 @@ } File desc_ent = new File(ent_name); desc_ent.delete(); - if (use25DTD) { + if(useLicenseUrl) { + pw.println(""); + } else if (use25DTD) { pw.println(""); } else if (targetClustersDefined) { pw.println(""); @@ -317,7 +329,27 @@ pw.println (); Map licenses = new HashMap(); Set licenseNames = new HashSet(); - + + String prefix = null; + if (dist_base != null) { + // fix/enforce distribution URL base + if (dist_base.equals(".")) { + prefix = ""; + } else { + prefix = dist_base + "/"; + } + } + final File licensesDir = new File(desc.getParentFile(), "licenses"); + if (useLicenseUrl) { + if (licensesDir.exists()) { + for (File f : licensesDir.listFiles()) { + f.delete(); + } + } else { + licensesDir.mkdir(); + } + } + for (Map.Entry> entry : modulesByGroup.entrySet()) { String groupName = entry.getKey(); // Don't indent; embedded descriptions would get indented otherwise. @@ -335,20 +367,26 @@ String name = manifest.getAttribute("OpenIDE-Module-Name"); if (name.length() > 0) { log(" Adding module " + name + " (" + m.nbm.getAbsolutePath() + ")"); - } - if (dist_base != null) { - // fix/enforce distribution URL base - String prefix; - if (dist_base.equals(".")) { - prefix = ""; - } else { - prefix = dist_base + "/"; - } + } + if(prefix!=null) { module.setAttribute("distribution", prefix + m.relativePath); } NodeList licenseList = module.getElementsByTagName("license"); if (licenseList.getLength() > 0) { Element license = (Element) licenseList.item(0); + if (useLicenseUrl) { + String relativePath = "licenses/" + license.getAttribute("name") + ".license"; + String path = relativePath; + if (prefix != null) { + path = prefix + relativePath; + } + license.setAttribute("url", path); + String licenseText = license.getTextContent(); + license.setTextContent(""); + FileWriter fw = new FileWriter(new File(desc.getParentFile(), relativePath)); + fw.write(licenseText); + fw.close(); + } // XXX ideally would compare the license texts to make sure they actually match up licenses.put(license.getAttribute("name"), license); module.removeChild(license); diff --git a/nbbuild/build.xml b/nbbuild/build.xml --- a/nbbuild/build.xml +++ b/nbbuild/build.xml @@ -924,7 +924,8 @@ - + + @@ -2034,8 +2035,9 @@ + - +