--- a/autoupdate.services/libsrc/org/netbeans/updater/resources/autoupdate-catalog-2_6.dtd +++ a/autoupdate.services/libsrc/org/netbeans/updater/resources/autoupdate-catalog-2_6.dtd @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + --- a/autoupdate.services/src/org/netbeans/modules/autoupdate/services/UpdateLicenseImpl.java +++ a/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,41 @@ 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 () { + if(agreement!=null) { + return agreement; + } else if (url!=null) { + agreement = AutoupdateCatalogCache.getDefault().getLicense(name,url); + } return agreement; } - + public void setUrl(URL url) { + this.url = url; + } public void setAgreement (String content) { - this.agreement = content; + if(content!=null) { + AutoupdateCatalogCache.getDefault().storeLicense(name,content); + } } } --- a/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/AutoupdateCatalogCache.java +++ a/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/AutoupdateCatalogCache.java @@ -43,6 +43,7 @@ import java.io.BufferedOutputStream; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @@ -60,7 +61,7 @@ */ public class AutoupdateCatalogCache { private File cacheDir; - private Exception storedException; + private static AutoupdateCatalogCache INSTANCE; @@ -100,7 +101,7 @@ assert dir != null && dir.exists () : "Cache directory must exist."; File cache = new File (dir, codeName); - copy (original, cache); + copyCatalog(original, cache); try { url = cache.toURI ().toURL (); @@ -137,8 +138,75 @@ 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 { + return copyLicense(url, file); + } catch (IOException e) { + err.log(Level.INFO, "Can`t load license from " + url, e); + return null; + } + } + 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; + } + } + } + + public void storeLicense(String name, String content) { + synchronized (name.intern()) { + File file = getLicenseFile(name); + if (file.exists() || content==null) { + return; + } + + 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 license " + name + " 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) throws IOException { + private void copyCatalog (final URL sourceUrl, final File cache) throws IOException { // -- create NetworkListener // -- request stream // -- report success or IOException @@ -151,124 +219,37 @@ 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); - } - - }; + DownloadCatalogListener nwl = new DownloadCatalogListener(sourceUrl, cache, temp); 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 String copyLicense (final URL sourceUrl, final File cache) throws IOException { + // -- create NetworkListener + // -- request stream + // -- report success or IOException + // -- if success then do copy + + err.log(Level.INFO, "Processing URL: " + sourceUrl); // NOI18N + + String prefix = ""; + while (prefix.length () < 3) { + prefix += cache.getName(); } + final File temp = File.createTempFile (prefix, null, cache.getParentFile ()); //NOI18N + temp.deleteOnExit(); + + DownloadLicenseListener nwl = new DownloadLicenseListener(sourceUrl, cache, temp); + + NetworkAccess.Task task = NetworkAccess.createNetworkAcessTask (sourceUrl, AutoupdateSettings.getOpenConnectionTimeout (), nwl); + task.waitFinished (); + nwl.notifyException (); + return nwl.getLicense(); } - - 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); - } - } - - } + } --- a/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/AutoupdateCatalogParser.java +++ a/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); --- a/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/DownloadCatalogListener.java +++ a/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/DownloadCatalogListener.java @@ -0,0 +1,188 @@ +/* + * 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 DownloadCatalogListener implements NetworkAccess.NetworkListener { + + private Exception storedException; + private File cache; + private File temp; + private URL sourceUrl; + + public DownloadCatalogListener(URL sourceUrl, File cache, File temp) { + this.sourceUrl = sourceUrl; + this.cache = cache; + this.temp = temp; + } + 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) { + 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); + } + } + } +} --- a/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/DownloadLicenseListener.java +++ a/autoupdate.services/src/org/netbeans/modules/autoupdate/updateprovider/DownloadLicenseListener.java @@ -0,0 +1,195 @@ +/* + * 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 Dmitry Lipin + */ +public class DownloadLicenseListener implements NetworkAccess.NetworkListener { + + private Exception storedException; + private File cache; + private File temp; + private URL sourceUrl; + private StringBuilder license; + + public DownloadLicenseListener(URL sourceUrl, File cache, File temp) { + this.sourceUrl = sourceUrl; + this.cache = cache; + this.temp = temp; + license = new StringBuilder(); + } + 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()); + } + + } + public String getLicense() { + return license.toString(); + } + + 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; + license.append(new String(bytes,0,read,"utf-8")); + } + + + 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); + } + } + + } +} --- a/autoupdate.services/src/org/netbeans/spi/autoupdate/UpdateLicense.java +++ a/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)); + } } --- a/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/wizards/InstallUnitWizardIterator.java +++ a/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/wizards/InstallUnitWizardIterator.java @@ -133,9 +133,10 @@ if (isCompact) { return ; } + /* if (getModel ().allLicensesApproved ()) { panels.remove (licenseApprovalStep); - } + }*/ if (! getModel ().hasCustomComponents ()) { panels.remove (customHandleStep); }