diff --git a/plugins/scm-hg-plugin/src/main/java/sonia/scm/api/rest/resources/HgConfigResource.java b/plugins/scm-hg-plugin/src/main/java/sonia/scm/api/rest/resources/HgConfigResource.java index a19d6605ed..99dce9040e 100644 --- a/plugins/scm-hg-plugin/src/main/java/sonia/scm/api/rest/resources/HgConfigResource.java +++ b/plugins/scm-hg-plugin/src/main/java/sonia/scm/api/rest/resources/HgConfigResource.java @@ -38,7 +38,10 @@ package sonia.scm.api.rest.resources; import com.google.inject.Inject; import com.google.inject.Singleton; +import sonia.scm.cache.CacheManager; import sonia.scm.installer.HgInstallerFactory; +import sonia.scm.installer.HgPackageReader; +import sonia.scm.installer.HgPackages; import sonia.scm.repository.HgConfig; import sonia.scm.repository.HgRepositoryHandler; import sonia.scm.web.HgWebConfigWriter; @@ -79,11 +82,14 @@ public class HgConfigResource * * * @param handler + * @param cacheManager */ @Inject - public HgConfigResource(HgRepositoryHandler handler) + public HgConfigResource(HgRepositoryHandler handler, + CacheManager cacheManager) { this.handler = handler; + this.pkgReader = new HgPackageReader(cacheManager); } //~--- methods -------------------------------------------------------------- @@ -168,6 +174,20 @@ public class HgConfigResource return new InstallationsResponse(installations); } + /** + * Method description + * + * + * @return + */ + @GET + @Path("packages") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public HgPackages getPackages() + { + return pkgReader.getPackages(); + } + /** * Method description * @@ -279,4 +299,7 @@ public class HgConfigResource /** Field description */ private HgRepositoryHandler handler; + + /** Field description */ + private HgPackageReader pkgReader; } diff --git a/plugins/scm-hg-plugin/src/main/java/sonia/scm/installer/HgPackage.java b/plugins/scm-hg-plugin/src/main/java/sonia/scm/installer/HgPackage.java new file mode 100644 index 0000000000..6bd5a416a6 --- /dev/null +++ b/plugins/scm-hg-plugin/src/main/java/sonia/scm/installer/HgPackage.java @@ -0,0 +1,262 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.installer; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.repository.HgConfig; + +//~--- JDK imports ------------------------------------------------------------ + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * + * @author Sebastian Sdorra + */ +@XmlRootElement(name = "package") +@XmlAccessorType(XmlAccessType.FIELD) +public class HgPackage +{ + + /** + * Method description + * + * + * @return + */ + public String getArch() + { + return arch; + } + + /** + * Method description + * + * + * @return + */ + public HgConfig getHgConfigTemplate() + { + return hgConfigTemplate; + } + + /** + * Method description + * + * + * @return + */ + public String getHgVersion() + { + return hgVersion; + } + + /** + * Method description + * + * + * @return + */ + public String getId() + { + return id; + } + + /** + * Method description + * + * + * @return + */ + public String getPlatform() + { + return platform; + } + + /** + * Method description + * + * + * @return + */ + public String getPythonVersion() + { + return pythonVersion; + } + + /** + * Method description + * + * + * @return + */ + public long getSize() + { + return size; + } + + /** + * Method description + * + * + * @return + */ + public String getUrl() + { + return url; + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param arch + */ + public void setArch(String arch) + { + this.arch = arch; + } + + /** + * Method description + * + * + * @param hgConfigTemplate + */ + public void setHgConfigTemplate(HgConfig hgConfigTemplate) + { + this.hgConfigTemplate = hgConfigTemplate; + } + + /** + * Method description + * + * + * @param hgVersion + */ + public void setHgVersion(String hgVersion) + { + this.hgVersion = hgVersion; + } + + /** + * Method description + * + * + * @param id + */ + public void setId(String id) + { + this.id = id; + } + + /** + * Method description + * + * + * @param platform + */ + public void setPlatform(String platform) + { + this.platform = platform; + } + + /** + * Method description + * + * + * @param pythonVersion + */ + public void setPythonVersion(String pythonVersion) + { + this.pythonVersion = pythonVersion; + } + + /** + * Method description + * + * + * @param size + */ + public void setSize(long size) + { + this.size = size; + } + + /** + * Method description + * + * + * @param url + */ + public void setUrl(String url) + { + this.url = url; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private String arch; + + /** Field description */ + @XmlElement(name = "hg-config-template") + private HgConfig hgConfigTemplate; + + /** Field description */ + @XmlElement(name = "hg-version") + private String hgVersion; + + /** Field description */ + private String id; + + /** Field description */ + private String platform; + + /** Field description */ + @XmlElement(name = "python-version") + private String pythonVersion; + + /** Field description */ + private long size; + + /** Field description */ + private String url; +} diff --git a/plugins/scm-hg-plugin/src/main/java/sonia/scm/installer/HgPackageReader.java b/plugins/scm-hg-plugin/src/main/java/sonia/scm/installer/HgPackageReader.java new file mode 100644 index 0000000000..111e8c443c --- /dev/null +++ b/plugins/scm-hg-plugin/src/main/java/sonia/scm/installer/HgPackageReader.java @@ -0,0 +1,229 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.installer; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sonia.scm.PlatformType; +import sonia.scm.cache.Cache; +import sonia.scm.cache.CacheManager; +import sonia.scm.util.IOUtil; +import sonia.scm.util.SystemUtil; +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; +import java.io.InputStream; + +import java.net.URL; + +import java.util.ArrayList; +import java.util.List; +import java.util.zip.GZIPInputStream; + +import javax.xml.bind.JAXB; + +/** + * + * @author Sebastian Sdorra + */ +public class HgPackageReader +{ + + /** Field description */ + public static final String CACHENAME = "sonia.scm.hg.packages"; + + /** Field description */ + public static final String PACKAGEURL = + "http://download.scm-manager.org/pkg/mercurial/packages.xml.gz"; + + /** the logger for HgPackageReader */ + private static final Logger logger = + LoggerFactory.getLogger(HgPackageReader.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param cacheManager + */ + public HgPackageReader(CacheManager cacheManager) + { + cache = cacheManager.getCache(String.class, HgPackages.class, CACHENAME); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + public HgPackages getPackages() + { + HgPackages packages = cache.get(HgPackages.class.getName()); + + if (packages == null) + { + packages = getRemptePackages(); + filterPackage(packages); + cache.put(HgPackages.class.getName(), packages); + } + + return packages; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param packages + */ + private void filterPackage(HgPackages packages) + { + List pkgList = new ArrayList(); + + for (HgPackage pkg : packages) + { + boolean add = true; + + if (Util.isNotEmpty(pkg.getPlatform())) + { + PlatformType pt = PlatformType.createPlatformType(pkg.getPlatform()); + + if (SystemUtil.getPlatform().getType() != pt) + { + if (logger.isDebugEnabled()) + { + logger.debug("reject package {}, because of wrong platform {}", + pkg.getId(), pkg.getPlatform()); + } + + add = false; + } + } + + if (add && Util.isNotEmpty(pkg.getArch())) + { + if (!SystemUtil.getArch().equals(pkg.getArch())) + { + if (logger.isDebugEnabled()) + { + logger.debug("reject package {}, because of wrong arch {}", + pkg.getId(), pkg.getArch()); + } + + add = false; + } + } + + if (add) + { + if (logger.isDebugEnabled()) + { + logger.debug("added HgPackage {}", pkg.getId()); + } + + pkgList.add(pkg); + } + } + + packages.setPackages(pkgList); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + private HgPackages getRemptePackages() + { + if (logger.isInfoEnabled()) + { + logger.info("fetch HgPackages from {}", PACKAGEURL); + } + + HgPackages packages = null; + InputStream input = null; + + try + { + URL url = new URL(PACKAGEURL); + + if (PACKAGEURL.endsWith(".gz")) + { + input = new GZIPInputStream(url.openStream()); + } + else + { + input = url.openStream(); + } + + packages = JAXB.unmarshal(input, HgPackages.class); + } + catch (IOException ex) + { + logger.error("could not read HgPackages from {}", PACKAGEURL); + } + finally + { + IOUtil.close(input); + } + + if (packages == null) + { + packages = new HgPackages(); + packages.setPackages(new ArrayList()); + } + + return packages; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private Cache cache; +} diff --git a/plugins/scm-hg-plugin/src/main/java/sonia/scm/installer/HgPackages.java b/plugins/scm-hg-plugin/src/main/java/sonia/scm/installer/HgPackages.java new file mode 100644 index 0000000000..515fac6d9a --- /dev/null +++ b/plugins/scm-hg-plugin/src/main/java/sonia/scm/installer/HgPackages.java @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.installer; + +//~--- JDK imports ------------------------------------------------------------ + +import java.util.Iterator; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * + * @author Sebastian Sdorra + */ +@XmlRootElement(name = "packages") +@XmlAccessorType(XmlAccessType.FIELD) +public class HgPackages implements Iterable +{ + + /** + * Method description + * + * + * @return + */ + @Override + public Iterator iterator() + { + return packages.iterator(); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + public List getPackages() + { + return packages; + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param packages + */ + public void setPackages(List packages) + { + this.packages = packages; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + @XmlElement(name = "package") + private List packages; +} diff --git a/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hg.config-wizard.js b/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hg.config-wizard.js index c5094e3937..68851d781a 100644 --- a/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hg.config-wizard.js +++ b/plugins/scm-hg-plugin/src/main/resources/sonia/scm/hg.config-wizard.js @@ -114,18 +114,6 @@ Sonia.hg.ConfigWizardPanel = Ext.extend(Ext.Panel,{ hgConfig: null, initComponent: function(){ - - var navHandler = function(direction) { - var layout = this.getLayout(); - var i = layout.activeItem.id.split('step-')[1]; - i = parseInt(i) - 1; - var next = parseInt(i) + direction; - layout.setActiveItem(next); - Ext.getCmp('move-prev').setDisabled(next == 0); - Ext.getCmp('move-next').setDisabled(next == 2); - Ext.getCmp('finish').setDisabled(next != 2); - }; - this.addEvents('finish'); var hgInstallationStore = new Ext.data.Store({ @@ -154,18 +142,20 @@ Sonia.hg.ConfigWizardPanel = Ext.extend(Ext.Panel,{ bodyStyle: 'padding: 5px', defaults: { bodyCssClass: 'x-panel-mc', - border: false + border: false, + labelWidth: 120, + width: 230 }, bbar: ['->',{ id: 'move-prev', text: 'Back', - handler: navHandler.createDelegate(this, [-1]), + handler: this.navHandler.createDelegate(this, [-1]), disabled: true, scope: this },{ id: 'move-next', text: 'Next', - handler: navHandler.createDelegate(this, [1]), + handler: this.navHandler.createDelegate(this, [1]), scope: this },{ id: 'finish', @@ -176,7 +166,22 @@ Sonia.hg.ConfigWizardPanel = Ext.extend(Ext.Panel,{ }], items: [{ id: 'step-1', + items: [{ + xtype: 'radiogroup', + name: 'configureOrDownload', + columns: 1, + items: [ + {boxLabel: 'Configure local installation', name: 'cod', inputValue: 'local', checked: true}, + {boxLabel: 'Download and install', name: 'cod', inputValue: 'remote', disabled: true}, + ] + }] + },{ + id: 'step-2', layout: 'form', + width: '100%', + defaults: { + width: 230 + }, items: [{ id: 'mercurial', fieldLabel: 'Mercurial Installation', @@ -208,9 +213,6 @@ Sonia.hg.ConfigWizardPanel = Ext.extend(Ext.Panel,{ allowBlank: false, value: this.hgConfig.pythonBinary }] - },{ - id: 'step-2', - html: '

Step 2

' },{ id: 'step-3', html: '

Step 3

' @@ -221,6 +223,17 @@ Sonia.hg.ConfigWizardPanel = Ext.extend(Ext.Panel,{ Sonia.hg.ConfigWizardPanel.superclass.initComponent.apply(this, arguments); }, + navHandler: function(direction){ + var layout = this.getLayout(); + var i = layout.activeItem.id.split('step-')[1]; + i = parseInt(i) - 1; + var next = parseInt(i) + direction; + layout.setActiveItem(next); + Ext.getCmp('move-prev').setDisabled(next == 0); + Ext.getCmp('move-next').setDisabled(next == 2); + Ext.getCmp('finish').setDisabled(next != 2); + }, + applyChanges: function(){ var mercurial = Ext.getCmp('mercurial').getValue(); var python = Ext.getCmp('python').getValue();