diff --git a/maven/pom.xml b/maven/pom.xml index e584ea664d..886e45927a 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm.maven scm-maven-plugins pom - 1.17-SNAPSHOT + 1.18-SNAPSHOT scm-maven-plugins diff --git a/maven/scm-maven-plugin/pom.xml b/maven/scm-maven-plugin/pom.xml index beea26afd7..304335efd5 100644 --- a/maven/scm-maven-plugin/pom.xml +++ b/maven/scm-maven-plugin/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm.maven scm-maven-plugin - 1.17-SNAPSHOT + 1.18-SNAPSHOT maven-plugin scm-maven-plugin diff --git a/maven/scm-plugin-archetype/pom.xml b/maven/scm-plugin-archetype/pom.xml index 931bad0a01..0b354ee0bb 100644 --- a/maven/scm-plugin-archetype/pom.xml +++ b/maven/scm-plugin-archetype/pom.xml @@ -6,12 +6,12 @@ scm-maven-plugins sonia.scm.maven - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm.maven scm-plugin-archetype - 1.17-SNAPSHOT + 1.18-SNAPSHOT scm-plugin-archetype diff --git a/pom.xml b/pom.xml index db1bb49860..c09c85f055 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ sonia.scm scm pom - 1.17-SNAPSHOT + 1.18-SNAPSHOT The easiest way to share your Git, Mercurial and Subversion repositories over http. @@ -390,8 +390,8 @@ 4.10 - 1.6.4 - 1.0.4 + 1.6.6 + 1.0.6 2.5 3.0 @@ -401,8 +401,8 @@ 7.6.4.v20120524 - 1.3.0.201202151440-r - 1.7.4-1.v1 + 2.0.0.201206130900-r + 1.7.5-1 1.6 diff --git a/scm-clients/pom.xml b/scm-clients/pom.xml index 2a8f241d6a..2965268154 100644 --- a/scm-clients/pom.xml +++ b/scm-clients/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm.clients scm-clients pom - 1.17-SNAPSHOT + 1.18-SNAPSHOT scm-clients @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.17-SNAPSHOT + 1.18-SNAPSHOT diff --git a/scm-clients/scm-cli-client/pom.xml b/scm-clients/scm-cli-client/pom.xml index c3eb4276fa..e4c2b720b7 100644 --- a/scm-clients/scm-cli-client/pom.xml +++ b/scm-clients/scm-cli-client/pom.xml @@ -6,12 +6,12 @@ scm-clients sonia.scm.clients - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm.clients scm-cli-client - 1.17-SNAPSHOT + 1.18-SNAPSHOT scm-cli-client @@ -35,7 +35,7 @@ scm-core sonia.scm - 1.17-SNAPSHOT + 1.18-SNAPSHOT guice @@ -55,7 +55,7 @@ sonia.scm.clients scm-client-impl - 1.17-SNAPSHOT + 1.18-SNAPSHOT diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/BooleanModifyOptionHandler.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/BooleanModifyOptionHandler.java index 76d2e350de..46d18badb6 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/BooleanModifyOptionHandler.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/BooleanModifyOptionHandler.java @@ -1,34 +1,35 @@ /** - * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * 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 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. + * 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.cli; //~--- non-JDK imports -------------------------------------------------------- diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/CreateRepositorySubCommand.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/CreateRepositorySubCommand.java index 79e8c5a96f..52828eba25 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/CreateRepositorySubCommand.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/CreateRepositorySubCommand.java @@ -170,7 +170,7 @@ public class CreateRepositorySubCommand extends TemplateSubCommand Map env = new HashMap(); - env.put("repository", new RepositoryWrapper(repository)); + env.put("repository", new RepositoryWrapper(config, repository)); renderTemplate(env, GetRepositorySubCommand.TEMPLATE); } diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/GetRepositorySubCommand.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/GetRepositorySubCommand.java index 9e9c0fbe29..c7c497bacf 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/GetRepositorySubCommand.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/GetRepositorySubCommand.java @@ -104,7 +104,7 @@ public class GetRepositorySubCommand extends TemplateSubCommand { Map env = new HashMap(); - env.put("repository", new RepositoryWrapper(repository)); + env.put("repository", new RepositoryWrapper(config, repository)); renderTemplate(env, TEMPLATE); } else diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/ListRepositoriesSubCommand.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/ListRepositoriesSubCommand.java index 518bd062d5..2235781791 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/ListRepositoriesSubCommand.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/ListRepositoriesSubCommand.java @@ -74,7 +74,7 @@ public class ListRepositoriesSubCommand extends TemplateSubCommand List repositories = session.getRepositoryHandler().getAll(); Map env = new HashMap(); - env.put("repositories", WrapperUtil.wrapRepositories(repositories)); + env.put("repositories", WrapperUtil.wrapRepositories(config, repositories)); renderTemplate(env, TEMPLATE); } } diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/ModifyRepositorySubCommand.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/ModifyRepositorySubCommand.java index 1f991fa746..5ec4c59519 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/ModifyRepositorySubCommand.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/ModifyRepositorySubCommand.java @@ -214,7 +214,7 @@ public class ModifyRepositorySubCommand extends TemplateSubCommand Map env = new HashMap(); - env.put("repository", new RepositoryWrapper(repository)); + env.put("repository", new RepositoryWrapper(config, repository)); renderTemplate(env, GetRepositorySubCommand.TEMPLATE); } else diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/PermissionSubCommand.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/PermissionSubCommand.java index c701a45808..a6b5eba2f5 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/PermissionSubCommand.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/PermissionSubCommand.java @@ -120,7 +120,7 @@ public abstract class PermissionSubCommand extends TemplateSubCommand Map env = new HashMap(); - env.put("repository", new RepositoryWrapper(repository)); + env.put("repository", new RepositoryWrapper(config, repository)); renderTemplate(env, GetRepositorySubCommand.TEMPLATE); } else diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/wrapper/RepositoryWrapper.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/wrapper/RepositoryWrapper.java index 68d5131cbc..216afde624 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/wrapper/RepositoryWrapper.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/wrapper/RepositoryWrapper.java @@ -35,6 +35,7 @@ package sonia.scm.cli.wrapper; //~--- non-JDK imports -------------------------------------------------------- +import sonia.scm.cli.config.ServerConfig; import sonia.scm.repository.Permission; import sonia.scm.repository.Repository; @@ -54,10 +55,25 @@ public class RepositoryWrapper extends AbstractWrapper * Constructs ... * * + * @param config * @param repository */ - public RepositoryWrapper(Repository repository) + public RepositoryWrapper(ServerConfig config, Repository repository) { + this(config.getServerUrl(), repository); + } + + /** + * Constructs ... + * + * + * + * @param baseUrl + * @param repository + */ + public RepositoryWrapper(String baseUrl, Repository repository) + { + this.baseUrl = baseUrl; this.repository = repository; } @@ -159,7 +175,7 @@ public class RepositoryWrapper extends AbstractWrapper */ public String getUrl() { - return repository.getUrl(); + return repository.createUrl(baseUrl); } /** @@ -186,6 +202,9 @@ public class RepositoryWrapper extends AbstractWrapper //~--- fields --------------------------------------------------------------- + /** Field description */ + private String baseUrl; + /** Field description */ private Repository repository; } diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/wrapper/WrapperUtil.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/wrapper/WrapperUtil.java index dce0bef3fc..f508b45039 100644 --- a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/wrapper/WrapperUtil.java +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/wrapper/WrapperUtil.java @@ -35,6 +35,7 @@ package sonia.scm.cli.wrapper; //~--- non-JDK imports -------------------------------------------------------- +import sonia.scm.cli.config.ServerConfig; import sonia.scm.group.Group; import sonia.scm.repository.Repository; import sonia.scm.user.User; @@ -76,18 +77,22 @@ public class WrapperUtil * Method description * * + * + * @param baseUrl + * + * @param config * @param repositories * * @return */ - public static List wrapRepositories( + public static List wrapRepositories(ServerConfig config, Collection repositories) { List wrappers = new ArrayList(); for (Repository r : repositories) { - wrappers.add(new RepositoryWrapper(r)); + wrappers.add(new RepositoryWrapper(config.getServerUrl(), r)); } return wrappers; diff --git a/scm-clients/scm-client-api/pom.xml b/scm-clients/scm-client-api/pom.xml index 11c2d5b26b..b113cdbe04 100644 --- a/scm-clients/scm-client-api/pom.xml +++ b/scm-clients/scm-client-api/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm.clients scm-client-api jar - 1.17-SNAPSHOT + 1.18-SNAPSHOT scm-client-api diff --git a/scm-clients/scm-client-impl/pom.xml b/scm-clients/scm-client-impl/pom.xml index 4bf887cab0..b0994e6702 100644 --- a/scm-clients/scm-client-impl/pom.xml +++ b/scm-clients/scm-client-impl/pom.xml @@ -6,13 +6,13 @@ sonia.scm.clients scm-clients - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm.clients scm-client-impl jar - 1.17-SNAPSHOT + 1.18-SNAPSHOT scm-client-impl @@ -36,7 +36,7 @@ scm-core sonia.scm - 1.17-SNAPSHOT + 1.18-SNAPSHOT aopalliance @@ -60,7 +60,7 @@ sonia.scm.clients scm-client-api - 1.17-SNAPSHOT + 1.18-SNAPSHOT @@ -112,7 +112,7 @@ sonia.scm scm-test - 1.17-SNAPSHOT + 1.18-SNAPSHOT test diff --git a/scm-core/pom.xml b/scm-core/pom.xml index bedccaf606..141ad66a66 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm scm-core - 1.17-SNAPSHOT + 1.18-SNAPSHOT scm-core diff --git a/scm-core/src/main/java/sonia/scm/ServletContainerDetector.java b/scm-core/src/main/java/sonia/scm/ServletContainerDetector.java index f4f935ce9e..6038abed05 100644 --- a/scm-core/src/main/java/sonia/scm/ServletContainerDetector.java +++ b/scm-core/src/main/java/sonia/scm/ServletContainerDetector.java @@ -215,7 +215,7 @@ public class ServletContainerDetector */ public boolean isScmServer() { - return "scm-server".equals(System.getProperty("app-name")); + return "scm-server".equals(System.getProperty("app.name")); } /** diff --git a/scm-core/src/main/java/sonia/scm/filter/GZipFilterConfig.java b/scm-core/src/main/java/sonia/scm/filter/GZipFilterConfig.java index 047a56c4e4..1132ff1259 100644 --- a/scm-core/src/main/java/sonia/scm/filter/GZipFilterConfig.java +++ b/scm-core/src/main/java/sonia/scm/filter/GZipFilterConfig.java @@ -1,34 +1,35 @@ /** - * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * 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 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. + * 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.filter; /** diff --git a/scm-core/src/main/java/sonia/scm/i18n/Bundle.java b/scm-core/src/main/java/sonia/scm/i18n/Bundle.java index 9523948cd7..be349fddb7 100644 --- a/scm-core/src/main/java/sonia/scm/i18n/Bundle.java +++ b/scm-core/src/main/java/sonia/scm/i18n/Bundle.java @@ -1,34 +1,35 @@ /** - * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * 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 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. + * 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.i18n; //~--- non-JDK imports -------------------------------------------------------- diff --git a/scm-core/src/main/java/sonia/scm/net/HttpRequest.java b/scm-core/src/main/java/sonia/scm/net/HttpRequest.java index 588e4dd111..68c391c646 100644 --- a/scm-core/src/main/java/sonia/scm/net/HttpRequest.java +++ b/scm-core/src/main/java/sonia/scm/net/HttpRequest.java @@ -174,7 +174,7 @@ public class HttpRequest * * * @return - * + * * @since 1.14 */ public boolean isDecodeGZip() @@ -182,6 +182,42 @@ public class HttpRequest return decodeGZip; } + /** + * Method description + * + * + * @return + * @since 1.17 + */ + public boolean isDisableCertificateValidation() + { + return disableCertificateValidation; + } + + /** + * Method description + * + * + * @return + * @since 1.17 + */ + public boolean isDisableHostnameValidation() + { + return disableHostnameValidation; + } + + /** + * Method description + * + * + * @return + * @since 1.17 + */ + public boolean isIgnoreProxySettings() + { + return ignoreProxySettings; + } + //~--- set methods ---------------------------------------------------------- /** @@ -208,15 +244,41 @@ public class HttpRequest * @param decodeGZip * * @return - * + * * @since 1.14 */ public HttpRequest setDecodeGZip(boolean decodeGZip) { this.decodeGZip = decodeGZip; + return this; } + /** + * Method description + * + * + * @param disableCertificateValidation + * @since 1.17 + */ + public void setDisableCertificateValidation( + boolean disableCertificateValidation) + { + this.disableCertificateValidation = disableCertificateValidation; + } + + /** + * Method description + * + * + * @param disableHostnameValidation + * @since 1.17 + */ + public void setDisableHostnameValidation(boolean disableHostnameValidation) + { + this.disableHostnameValidation = disableHostnameValidation; + } + /** * Method description * @@ -232,6 +294,18 @@ public class HttpRequest return this; } + /** + * Method description + * + * + * @param ignoreProxySettings + * @since 1.17 + */ + public void setIgnoreProxySettings(boolean ignoreProxySettings) + { + this.ignoreProxySettings = ignoreProxySettings; + } + /** * Method description * @@ -277,10 +351,19 @@ public class HttpRequest //~--- fields --------------------------------------------------------------- /** Field description */ - private boolean decodeGZip = false; + private Map> headers; /** Field description */ - private Map> headers; + private boolean ignoreProxySettings = false; + + /** Field description */ + private boolean disableHostnameValidation = false; + + /** Field description */ + private boolean disableCertificateValidation = false; + + /** Field description */ + private boolean decodeGZip = false; /** Field description */ private Map> parameters; diff --git a/scm-core/src/main/java/sonia/scm/plugin/PluginCondition.java b/scm-core/src/main/java/sonia/scm/plugin/PluginCondition.java index 11198ae3f8..7cae04f45c 100644 --- a/scm-core/src/main/java/sonia/scm/plugin/PluginCondition.java +++ b/scm-core/src/main/java/sonia/scm/plugin/PluginCondition.java @@ -42,6 +42,8 @@ import sonia.scm.util.Util; //~--- JDK imports ------------------------------------------------------------ +import java.io.Serializable; + import java.util.ArrayList; import java.util.List; @@ -57,9 +59,14 @@ import javax.xml.bind.annotation.XmlRootElement; */ @XmlRootElement(name = "conditions") @XmlAccessorType(XmlAccessType.FIELD) -public class PluginCondition implements Cloneable +public class PluginCondition implements Cloneable, Serializable { + /** Field description */ + private static final long serialVersionUID = 2406156062634968672L; + + //~--- constructors --------------------------------------------------------- + /** * Constructs ... * diff --git a/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java b/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java index 4031def5a1..47363b9895 100644 --- a/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java +++ b/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java @@ -40,6 +40,8 @@ import sonia.scm.util.Util; //~--- JDK imports ------------------------------------------------------------ +import java.io.Serializable; + import java.util.ArrayList; import java.util.List; @@ -55,9 +57,14 @@ import javax.xml.bind.annotation.XmlRootElement; */ @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "plugin-information") -public class PluginInformation implements Validateable, Cloneable +public class PluginInformation implements Validateable, Cloneable, Serializable { + /** Field description */ + private static final long serialVersionUID = 461382048865977206L; + + //~--- methods -------------------------------------------------------------- + /** * Method description * diff --git a/scm-core/src/main/java/sonia/scm/plugin/PluginRepository.java b/scm-core/src/main/java/sonia/scm/plugin/PluginRepository.java index 3ea5f40186..eba67110c5 100644 --- a/scm-core/src/main/java/sonia/scm/plugin/PluginRepository.java +++ b/scm-core/src/main/java/sonia/scm/plugin/PluginRepository.java @@ -33,13 +33,22 @@ package sonia.scm.plugin; +//~--- JDK imports ------------------------------------------------------------ + +import java.io.Serializable; + /** * * @author Sebastian Sdorra */ -public class PluginRepository +public class PluginRepository implements Serializable { + /** Field description */ + private static final long serialVersionUID = -9504354306304731L; + + //~--- constructors --------------------------------------------------------- + /** * Constructs ... * diff --git a/scm-core/src/main/java/sonia/scm/repository/BlameLine.java b/scm-core/src/main/java/sonia/scm/repository/BlameLine.java index 7d60e6e9f6..ff23ca8fd3 100644 --- a/scm-core/src/main/java/sonia/scm/repository/BlameLine.java +++ b/scm-core/src/main/java/sonia/scm/repository/BlameLine.java @@ -37,15 +37,24 @@ package sonia.scm.repository; import com.google.common.base.Objects; +//~--- JDK imports ------------------------------------------------------------ + +import java.io.Serializable; + /** * Single line of a file, in a {@link BlameResult}. * * @author Sebastian Sdorra * @since 1.8 */ -public class BlameLine +public class BlameLine implements Serializable { + /** Field description */ + private static final long serialVersionUID = 2816601606921153670L; + + //~--- constructors --------------------------------------------------------- + /** * Constructs ... * diff --git a/scm-core/src/main/java/sonia/scm/repository/BlameLinePreProcessor.java b/scm-core/src/main/java/sonia/scm/repository/BlameLinePreProcessor.java new file mode 100644 index 0000000000..68141f5aaf --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/BlameLinePreProcessor.java @@ -0,0 +1,58 @@ +/** + * 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.repository; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.plugin.ExtensionPoint; + +/** + * A pre processor for {@link BlameLine} objects. A pre processor is able to + * modify the object before it is delivered to the user interface. + * + * @author Sebastian Sdorra + * @since 1.17 + */ +@ExtensionPoint +public interface BlameLinePreProcessor extends PreProcessor +{ + + /** + * Process the given blame line. + * + * + * @param blameLine blame line to process. + */ + @Override + public void process(BlameLine blameLine); +} diff --git a/scm-core/src/main/java/sonia/scm/repository/BlameLinePreProcessorFactory.java b/scm-core/src/main/java/sonia/scm/repository/BlameLinePreProcessorFactory.java new file mode 100644 index 0000000000..8ff5b6e01c --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/BlameLinePreProcessorFactory.java @@ -0,0 +1,62 @@ +/** + * 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.repository; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.plugin.ExtensionPoint; + +/** + * The BlameLinePreProcessorFactory create {@link BlameLinePreProcessor} + * objects for a specific repository. + * + * @author Sebastian Sdorra + * @since 1.17 + */ +@ExtensionPoint +public interface BlameLinePreProcessorFactory + extends PreProcessorFactory +{ + + /** + * Create a new {@link BlameLinePreProcessor} for the given repository. + * + * + * @param repository repository + * + * @return {@link BlameLinePreProcessor} for the given repository + */ + @Override + public BlameLinePreProcessor createPreProcessor(Repository repository); +} diff --git a/scm-core/src/main/java/sonia/scm/repository/BlameResult.java b/scm-core/src/main/java/sonia/scm/repository/BlameResult.java index a1ef0db44c..3acb4928b1 100644 --- a/scm-core/src/main/java/sonia/scm/repository/BlameResult.java +++ b/scm-core/src/main/java/sonia/scm/repository/BlameResult.java @@ -36,9 +36,13 @@ package sonia.scm.repository; //~--- non-JDK imports -------------------------------------------------------- import com.google.common.base.Objects; +import com.google.common.collect.Lists; //~--- JDK imports ------------------------------------------------------------ +import java.io.Serializable; + +import java.util.Iterator; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; @@ -48,17 +52,23 @@ import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; /** - * Class description + * Changeset information by line for a given file. * + * TODO for 2.0 implement {@link Iterable} * * @author Sebastian Sdorra * @since 1.8 */ @XmlRootElement(name = "blame-result") @XmlAccessorType(XmlAccessType.FIELD) -public class BlameResult +public class BlameResult implements Serializable, Iterable { + /** Field description */ + private static final long serialVersionUID = -8606237881465520606L; + + //~--- constructors --------------------------------------------------------- + /** * Constructs ... * @@ -131,6 +141,20 @@ public class BlameResult return Objects.hashCode(total, blameLines); } + /** + * Method description + * + * + * @return + * + * @since 1.17 + */ + @Override + public Iterator iterator() + { + return getBlameLines().iterator(); + } + /** * {@inheritDoc} * @@ -158,6 +182,9 @@ public class BlameResult */ public List getBlameLines() { + if ( blameLines == null ){ + blameLines = Lists.newArrayList(); + } return blameLines; } diff --git a/scm-core/src/main/java/sonia/scm/repository/BlameViewer.java b/scm-core/src/main/java/sonia/scm/repository/BlameViewer.java index 6192329017..c77d5e92e4 100644 --- a/scm-core/src/main/java/sonia/scm/repository/BlameViewer.java +++ b/scm-core/src/main/java/sonia/scm/repository/BlameViewer.java @@ -33,6 +33,10 @@ package sonia.scm.repository; +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.repository.api.RepositoryService; + //~--- JDK imports ------------------------------------------------------------ import java.io.IOException; @@ -43,7 +47,10 @@ import java.io.IOException; * * @author Sebastian Sdorra * @since 1.8 + * + * @deprecated use {@link RepositoryService#getBlameCommand()} instead. */ +@Deprecated public interface BlameViewer { diff --git a/scm-core/src/main/java/sonia/scm/repository/BlameViewerProvider.java b/scm-core/src/main/java/sonia/scm/repository/BlameViewerProvider.java index 5c2419ac16..6af34a5bf1 100644 --- a/scm-core/src/main/java/sonia/scm/repository/BlameViewerProvider.java +++ b/scm-core/src/main/java/sonia/scm/repository/BlameViewerProvider.java @@ -33,11 +33,18 @@ package sonia.scm.repository; +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.repository.api.RepositoryService; + /** * * @author Sebastian Sdorra * @since 1.8 + * + * @deprecated use {@link RepositoryService#getBlameCommand()} instead. */ +@Deprecated public interface BlameViewerProvider { diff --git a/scm-core/src/main/java/sonia/scm/repository/BlameViewerUtil.java b/scm-core/src/main/java/sonia/scm/repository/BlameViewerUtil.java index e552a53d1f..d824b256e1 100644 --- a/scm-core/src/main/java/sonia/scm/repository/BlameViewerUtil.java +++ b/scm-core/src/main/java/sonia/scm/repository/BlameViewerUtil.java @@ -44,6 +44,7 @@ import org.slf4j.LoggerFactory; import sonia.scm.NotSupportedFeatuerException; import sonia.scm.cache.Cache; import sonia.scm.cache.CacheManager; +import sonia.scm.repository.api.RepositoryService; import sonia.scm.util.AssertUtil; //~--- JDK imports ------------------------------------------------------------ @@ -55,8 +56,11 @@ import java.io.IOException; * * @author Sebastian Sdorra * @since 1.8 + * + * @deprecated use {@link RepositoryService#getBlameCommand()} instead. */ @Singleton +@Deprecated public class BlameViewerUtil extends PartCacheClearHook { @@ -75,7 +79,6 @@ public class BlameViewerUtil extends PartCacheClearHook * * @param repositoryManager * @param cacheManager - * @return */ @Inject public BlameViewerUtil(RepositoryManager repositoryManager, diff --git a/scm-core/src/main/java/sonia/scm/repository/BrowserResult.java b/scm-core/src/main/java/sonia/scm/repository/BrowserResult.java index 7230b2ab48..7880b58f11 100644 --- a/scm-core/src/main/java/sonia/scm/repository/BrowserResult.java +++ b/scm-core/src/main/java/sonia/scm/repository/BrowserResult.java @@ -39,6 +39,8 @@ import com.google.common.base.Objects; //~--- JDK imports ------------------------------------------------------------ +import java.io.Serializable; + import java.util.Iterator; import java.util.List; @@ -55,9 +57,14 @@ import javax.xml.bind.annotation.XmlRootElement; */ @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "browser-result") -public class BrowserResult implements Iterable +public class BrowserResult implements Iterable, Serializable { + /** Field description */ + private static final long serialVersionUID = 2818662048045182761L; + + //~--- constructors --------------------------------------------------------- + /** * Constructs ... * diff --git a/scm-core/src/main/java/sonia/scm/repository/Changeset.java b/scm-core/src/main/java/sonia/scm/repository/Changeset.java index 3fb89a064e..379582c8c8 100644 --- a/scm-core/src/main/java/sonia/scm/repository/Changeset.java +++ b/scm-core/src/main/java/sonia/scm/repository/Changeset.java @@ -62,7 +62,7 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "changeset") @XmlAccessorType(XmlAccessType.FIELD) public class Changeset extends BasicPropertiesAware - implements Validateable, Cloneable, Serializable + implements Validateable, Serializable { /** Field description */ @@ -108,26 +108,6 @@ public class Changeset extends BasicPropertiesAware //~--- methods -------------------------------------------------------------- - /** - * {@inheritDoc} - * - * - * @return - */ - @Override - public Changeset clone() - { - Changeset changeset = new Changeset(id, date, author, description); - - changeset.setBranches(branches); - changeset.setTags(tags); - changeset.setModifications(modifications); - changeset.setProperties(properties); - changeset.setParents(parents); - - return changeset; - } - /** * {@inheritDoc} * diff --git a/scm-core/src/main/java/sonia/scm/repository/ChangesetPagingResult.java b/scm-core/src/main/java/sonia/scm/repository/ChangesetPagingResult.java index d4a105d22b..2b1b455939 100644 --- a/scm-core/src/main/java/sonia/scm/repository/ChangesetPagingResult.java +++ b/scm-core/src/main/java/sonia/scm/repository/ChangesetPagingResult.java @@ -35,6 +35,8 @@ package sonia.scm.repository; //~--- JDK imports ------------------------------------------------------------ +import java.io.Serializable; + import java.util.Iterator; import java.util.List; @@ -50,9 +52,14 @@ import javax.xml.bind.annotation.XmlRootElement; */ @XmlRootElement(name = "changeset-paging") @XmlAccessorType(XmlAccessType.FIELD) -public class ChangesetPagingResult implements Iterable +public class ChangesetPagingResult implements Iterable, Serializable { + /** Field description */ + private static final long serialVersionUID = -8678755403658841733L; + + //~--- constructors --------------------------------------------------------- + /** * Constructs ... * diff --git a/scm-core/src/main/java/sonia/scm/repository/ChangesetPreProcessor.java b/scm-core/src/main/java/sonia/scm/repository/ChangesetPreProcessor.java index 3e6db77967..0758f2d0a9 100644 --- a/scm-core/src/main/java/sonia/scm/repository/ChangesetPreProcessor.java +++ b/scm-core/src/main/java/sonia/scm/repository/ChangesetPreProcessor.java @@ -38,7 +38,11 @@ package sonia.scm.repository; import sonia.scm.plugin.ExtensionPoint; /** - * + * A pre processor for {@link Changeset} objects. A pre processor is able to + * modify the object before it is delivered to the user interface. + * + * TODO for 2.0 extends {@link PreProcessor} interface. + * * @author Sebastian Sdorra */ @ExtensionPoint @@ -46,10 +50,10 @@ public interface ChangesetPreProcessor { /** - * Method description + * Process the given changeset. * * - * @param changeset + * @param changeset changeset to process */ public void process(Changeset changeset); } diff --git a/scm-core/src/main/java/sonia/scm/repository/ChangesetPreProcessorFactory.java b/scm-core/src/main/java/sonia/scm/repository/ChangesetPreProcessorFactory.java index fc3cc92387..47ab5786e2 100644 --- a/scm-core/src/main/java/sonia/scm/repository/ChangesetPreProcessorFactory.java +++ b/scm-core/src/main/java/sonia/scm/repository/ChangesetPreProcessorFactory.java @@ -38,6 +38,10 @@ package sonia.scm.repository; import sonia.scm.plugin.ExtensionPoint; /** + * The ChangesetPreProcessorFactory create {@link ChangesetPreProcessor} + * objects for a specific repository. + * + * TODO for 2.0 extends {@link PreProcessorFactory} interface. * * @author Sebastian Sdorra * @since 1.7 @@ -47,12 +51,12 @@ public interface ChangesetPreProcessorFactory { /** - * Method description + * Create a new {@link ChangesetPreProcessor} for the given repository. * * - * @param repository + * @param repository repository * - * @return + * @return {@link ChangesetPreProcessor} for the given repository */ public ChangesetPreProcessor createPreProcessor(Repository repository); } diff --git a/scm-core/src/main/java/sonia/scm/repository/ChangesetViewer.java b/scm-core/src/main/java/sonia/scm/repository/ChangesetViewer.java index 0f9561e4d0..7d925bb8f4 100644 --- a/scm-core/src/main/java/sonia/scm/repository/ChangesetViewer.java +++ b/scm-core/src/main/java/sonia/scm/repository/ChangesetViewer.java @@ -33,6 +33,10 @@ package sonia.scm.repository; +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.repository.api.RepositoryService; + //~--- JDK imports ------------------------------------------------------------ import java.io.IOException; @@ -40,7 +44,10 @@ import java.io.IOException; /** * * @author Sebastian Sdorra + * + * @deprecated use {@link RepositoryService#getLogCommand()} instead. */ +@Deprecated public interface ChangesetViewer { diff --git a/scm-core/src/main/java/sonia/scm/repository/ChangesetViewerProvider.java b/scm-core/src/main/java/sonia/scm/repository/ChangesetViewerProvider.java index 4ccf0b86af..54ed628a60 100644 --- a/scm-core/src/main/java/sonia/scm/repository/ChangesetViewerProvider.java +++ b/scm-core/src/main/java/sonia/scm/repository/ChangesetViewerProvider.java @@ -33,11 +33,18 @@ package sonia.scm.repository; +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.repository.api.RepositoryService; + /** * * @author Sebastian Sdorra * @since 1.8 + * + * @deprecated use {@link RepositoryService#getLogCommand()} instead. */ +@Deprecated public interface ChangesetViewerProvider { diff --git a/scm-core/src/main/java/sonia/scm/repository/ChangesetViewerUtil.java b/scm-core/src/main/java/sonia/scm/repository/ChangesetViewerUtil.java index 75c62964e5..1e12f9ab76 100644 --- a/scm-core/src/main/java/sonia/scm/repository/ChangesetViewerUtil.java +++ b/scm-core/src/main/java/sonia/scm/repository/ChangesetViewerUtil.java @@ -37,13 +37,13 @@ package sonia.scm.repository; import com.google.inject.Inject; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sonia.scm.NotSupportedFeatuerException; import sonia.scm.cache.Cache; import sonia.scm.cache.CacheManager; +import sonia.scm.repository.api.RepositoryService; import sonia.scm.util.AssertUtil; import sonia.scm.util.Util; @@ -58,7 +58,10 @@ import java.util.Set; * * @author Sebastian Sdorra * @since 1.6 + * + * @deprecated use {@link RepositoryService#getLogCommand()} instead. */ +@Deprecated public class ChangesetViewerUtil extends PartCacheClearHook { @@ -468,8 +471,6 @@ public class ChangesetViewerUtil extends PartCacheClearHook } } - - /** * Method description * diff --git a/scm-core/src/main/java/sonia/scm/repository/DiffViewer.java b/scm-core/src/main/java/sonia/scm/repository/DiffViewer.java index 8b9ba11187..149d1b22b9 100644 --- a/scm-core/src/main/java/sonia/scm/repository/DiffViewer.java +++ b/scm-core/src/main/java/sonia/scm/repository/DiffViewer.java @@ -37,12 +37,16 @@ package sonia.scm.repository; import java.io.IOException; import java.io.OutputStream; +import sonia.scm.repository.api.RepositoryService; /** * * @author Sebastian Sdorra * @since 1.8 + * + * @deprecated use {@link RepositoryService#getDiffCommand()} instead. */ +@Deprecated public interface DiffViewer { diff --git a/scm-core/src/main/java/sonia/scm/repository/DiffViewerProvider.java b/scm-core/src/main/java/sonia/scm/repository/DiffViewerProvider.java index eea836977b..4876d3a5c7 100644 --- a/scm-core/src/main/java/sonia/scm/repository/DiffViewerProvider.java +++ b/scm-core/src/main/java/sonia/scm/repository/DiffViewerProvider.java @@ -33,11 +33,18 @@ package sonia.scm.repository; +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.repository.api.RepositoryService; + /** * * @author Sebastian Sdorra * @since 1.8 + * + * @deprecated use {@link RepositoryService#getDiffCommand()} instead. */ +@Deprecated public interface DiffViewerProvider { diff --git a/scm-core/src/main/java/sonia/scm/repository/EscapeUtil.java b/scm-core/src/main/java/sonia/scm/repository/EscapeUtil.java index 291bd4a553..b4e85faac0 100644 --- a/scm-core/src/main/java/sonia/scm/repository/EscapeUtil.java +++ b/scm-core/src/main/java/sonia/scm/repository/EscapeUtil.java @@ -1,27 +1,29 @@ /** - * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * 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 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. + * 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 * @@ -68,6 +70,34 @@ public class EscapeUtil } } + /** + * Method description + * + * + * @param result + * @since 1.17 + */ + public static void escape(BlameResult result) + { + for (BlameLine line : result.getBlameLines()) + { + escape(line); + } + } + + /** + * Method description + * + * + * @param line + * @since 1.17 + */ + public static void escape(BlameLine line) + { + line.setDescription(escape(line.getDescription())); + escape(line.getAuthor()); + } + /** * Method description * @@ -90,17 +120,25 @@ public class EscapeUtil public static void escape(Changeset changeset) { changeset.setDescription(escape(changeset.getDescription())); + escape(changeset.getAuthor()); + changeset.setBranches(escapeList(changeset.getBranches())); + changeset.setTags(escapeList(changeset.getTags())); + } - Person person = changeset.getAuthor(); - + /** + * Method description + * + * + * @param person + * @since 1.17 + */ + public static void escape(Person person) + { if (person != null) { person.setName(escape(person.getName())); person.setMail(escape(person.getMail())); } - - changeset.setBranches(escapeList(changeset.getBranches())); - changeset.setTags(escapeList(changeset.getTags())); } /** diff --git a/scm-core/src/main/java/sonia/scm/repository/FileObject.java b/scm-core/src/main/java/sonia/scm/repository/FileObject.java index 089ac48361..df6576464d 100644 --- a/scm-core/src/main/java/sonia/scm/repository/FileObject.java +++ b/scm-core/src/main/java/sonia/scm/repository/FileObject.java @@ -41,6 +41,8 @@ import sonia.scm.LastModifiedAware; //~--- JDK imports ------------------------------------------------------------ +import java.io.Serializable; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; @@ -53,9 +55,14 @@ import javax.xml.bind.annotation.XmlRootElement; */ @XmlRootElement(name = "file") @XmlAccessorType(XmlAccessType.FIELD) -public class FileObject implements LastModifiedAware +public class FileObject implements LastModifiedAware, Serializable { + /** Field description */ + private static final long serialVersionUID = -5562537629609891499L; + + //~--- methods -------------------------------------------------------------- + /** * {@inheritDoc} * diff --git a/scm-core/src/main/java/sonia/scm/repository/FileObjectPreProcessor.java b/scm-core/src/main/java/sonia/scm/repository/FileObjectPreProcessor.java index 1f4e2e42ea..0e6560136f 100644 --- a/scm-core/src/main/java/sonia/scm/repository/FileObjectPreProcessor.java +++ b/scm-core/src/main/java/sonia/scm/repository/FileObjectPreProcessor.java @@ -33,10 +33,16 @@ package sonia.scm.repository; +//~--- non-JDK imports -------------------------------------------------------- + import sonia.scm.plugin.ExtensionPoint; /** - * + * A pre processor for {@link FileObject} objects. A pre processor is able to + * modify the object before it is delivered to the user interface. + * + * TODO for 2.0 extends {@link PreProcessor} interface. + * * @author Sebastian Sdorra * @since 1.10 */ @@ -45,10 +51,10 @@ public interface FileObjectPreProcessor { /** - * Method description + * Process the given file object. * * - * @param fileObject + * @param fileObject file object to process */ public void process(FileObject fileObject); } diff --git a/scm-core/src/main/java/sonia/scm/repository/FileObjectPreProcessorFactory.java b/scm-core/src/main/java/sonia/scm/repository/FileObjectPreProcessorFactory.java index 2e3dce877c..746aed75f3 100644 --- a/scm-core/src/main/java/sonia/scm/repository/FileObjectPreProcessorFactory.java +++ b/scm-core/src/main/java/sonia/scm/repository/FileObjectPreProcessorFactory.java @@ -38,6 +38,10 @@ package sonia.scm.repository; import sonia.scm.plugin.ExtensionPoint; /** + * The FileObjectPreProcessorFactory create {@link FileObjectPreProcessor} + * objects for a specific repository. + * + * TODO for 2.0 extends {@link PreProcessorFactory} interface. * * @author Sebastian Sdorra * @since 1.10 @@ -47,12 +51,12 @@ public interface FileObjectPreProcessorFactory { /** - * Method description + * Create a new {@link FileObjectPreProcessor} for the given repository. * * - * @param repository + * @param repository repository * - * @return + * @return {@link FileObjectPreProcessor} for the given repository */ public FileObjectPreProcessor createPreProcessor(Repository repository); } diff --git a/scm-core/src/main/java/sonia/scm/repository/PreProcessor.java b/scm-core/src/main/java/sonia/scm/repository/PreProcessor.java new file mode 100644 index 0000000000..992f5b07e6 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/PreProcessor.java @@ -0,0 +1,54 @@ +/** + * 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.repository; + +/** + * A pre processor is able to modify a object before it is delivered + * to the user interface. + * + * @author Sebastian Sdorra + * @since 1.17 + * + * @param object type + */ +public interface PreProcessor +{ + + /** + * Process the given object. + * + * + * @param item object to process + */ + public void process(T item); +} diff --git a/scm-core/src/main/java/sonia/scm/repository/PreProcessorFactory.java b/scm-core/src/main/java/sonia/scm/repository/PreProcessorFactory.java new file mode 100644 index 0000000000..91a452d1bc --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/PreProcessorFactory.java @@ -0,0 +1,57 @@ +/** + * 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.repository; + +/** + * A pre processor factory creates a specific {@link PreProcessor} for + * the given repository. + * + * @author Sebastian Sdorra + * + * @param object type for the {@link PreProcessor} + * @since 1.17 + */ +public interface PreProcessorFactory +{ + + /** + * Create a new {@link PreProcessor} for the given repository. + * + * + * @param repository repository + * + * @return {@link PreProcessor} for the given repository + */ + public PreProcessor createPreProcessor(Repository repository); +} diff --git a/scm-core/src/main/java/sonia/scm/repository/PreProcessorUtil.java b/scm-core/src/main/java/sonia/scm/repository/PreProcessorUtil.java new file mode 100644 index 0000000000..89d8099996 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/PreProcessorUtil.java @@ -0,0 +1,628 @@ +/** + * 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.repository; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Function; +import com.google.common.collect.Collections2; +import com.google.inject.Inject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.util.Collection; +import java.util.Set; + +/** + * + * @author Sebastian Sdorra + * @since 1.17 + */ +public class PreProcessorUtil +{ + + /** + * the logger for PreProcessorUtil + */ + private static final Logger logger = + LoggerFactory.getLogger(PreProcessorUtil.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param changesetPreProcessorSet + * @param changesetPreProcessorFactorySet + * @param fileObjectPreProcessorSet + * @param fileObjectPreProcessorFactorySet + * @param blameLinePreProcessorSet + * @param blameLinePreProcessorFactorySet + */ + @Inject + public PreProcessorUtil( + Set changesetPreProcessorSet, + Set changesetPreProcessorFactorySet, + Set fileObjectPreProcessorSet, + Set fileObjectPreProcessorFactorySet, + Set blameLinePreProcessorSet, + Set blameLinePreProcessorFactorySet) + { + this.changesetPreProcessorSet = + Collections2.transform(changesetPreProcessorSet, + new Function() + { + @Override + public ChangesetPreProcessorWrapper apply(ChangesetPreProcessor input) + { + return new ChangesetPreProcessorWrapper(input); + } + }); + this.changesetPreProcessorFactorySet = + Collections2.transform(changesetPreProcessorFactorySet, + new Function() + { + @Override + public ChangesetPreProcessorFactoryWrapper apply( + ChangesetPreProcessorFactory input) + { + return new ChangesetPreProcessorFactoryWrapper(input); + } + }); + this.fileObjectPreProcessorSet = + Collections2.transform(fileObjectPreProcessorSet, + new Function() + { + @Override + public FileObjectPreProcessorWrapper apply(FileObjectPreProcessor input) + { + return new FileObjectPreProcessorWrapper(input); + } + }); + this.fileObjectPreProcessorFactorySet = + Collections2.transform(fileObjectPreProcessorFactorySet, + new Function() + { + @Override + public FileObjectPreProcessorFactoryWrapper apply( + FileObjectPreProcessorFactory input) + { + return new FileObjectPreProcessorFactoryWrapper(input); + } + }); + this.blameLinePreProcessorSet = blameLinePreProcessorSet; + this.blameLinePreProcessorFactorySet = blameLinePreProcessorFactorySet; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param repository + * @param blameLine + */ + public void prepareForReturn(Repository repository, BlameLine blameLine) + { + if (logger.isTraceEnabled()) + { + logger.trace("prepare blame line {} of repository {} for return", + blameLine.getLineNumber(), repository.getName()); + } + + EscapeUtil.escape(blameLine); + + PreProcessorHandler handler = + new PreProcessorHandler(blameLinePreProcessorFactorySet, + blameLinePreProcessorSet, repository); + + handler.callPreProcessors(blameLine); + handler.callPreProcessorFactories(blameLine); + } + + /** + * Method description + * + * + * @param repository + * @param blameResult + */ + public void prepareForReturn(Repository repository, BlameResult blameResult) + { + if (logger.isTraceEnabled()) + { + logger.trace("prepare blame result of repository {} for return", + repository.getName()); + } + + EscapeUtil.escape(blameResult); + + PreProcessorHandler handler = + new PreProcessorHandler(blameLinePreProcessorFactorySet, + blameLinePreProcessorSet, repository); + + handler.callPreProcessors(blameResult.getBlameLines()); + handler.callPreProcessorFactories(blameResult.getBlameLines()); + } + + /** + * Method description + * + * + * @param repository + * @param changeset + */ + public void prepareForReturn(Repository repository, Changeset changeset) + { + if (logger.isTraceEnabled()) + { + logger.trace("prepare changeset {} of repository {} for return", + changeset.getId(), repository.getName()); + } + + EscapeUtil.escape(changeset); + + PreProcessorHandler handler = + new PreProcessorHandler(changesetPreProcessorFactorySet, + changesetPreProcessorSet, repository); + + handler.callPreProcessors(changeset); + handler.callPreProcessorFactories(changeset); + } + + /** + * Method description + * + * + * @param repository + * @param changeset + * @param result + */ + public void prepareForReturn(Repository repository, BrowserResult result) + { + if (logger.isTraceEnabled()) + { + logger.trace("prepare browser result of repository {} for return", + repository.getName()); + } + + EscapeUtil.escape(result); + + PreProcessorHandler handler = + new PreProcessorHandler(fileObjectPreProcessorFactorySet, + fileObjectPreProcessorSet, repository); + + handler.callPreProcessors(result); + handler.callPreProcessorFactories(result); + } + + /** + * Method description + * + * + * @param repository + * @param result + */ + public void prepareForReturn(Repository repository, + ChangesetPagingResult result) + { + if (logger.isTraceEnabled()) + { + logger.trace("prepare changesets of repository {} for return", + repository.getName()); + } + + EscapeUtil.escape(result); + + PreProcessorHandler handler = + new PreProcessorHandler(changesetPreProcessorFactorySet, + changesetPreProcessorSet, repository); + + handler.callPreProcessors(result); + handler.callPreProcessorFactories(result); + } + + //~--- inner classes -------------------------------------------------------- + + /** + * Class description + * + * + * @version Enter version here..., 12/06/16 + * @author Enter your name here... + */ + private static class ChangesetPreProcessorFactoryWrapper + implements PreProcessorFactory + { + + /** + * Constructs ... + * + * + * @param preProcessorFactory + */ + public ChangesetPreProcessorFactoryWrapper( + ChangesetPreProcessorFactory preProcessorFactory) + { + this.preProcessorFactory = preProcessorFactory; + } + + //~--- methods ------------------------------------------------------------ + + /** + * Method description + * + * + * @param repository + * + * @return + */ + @Override + public PreProcessor createPreProcessor(Repository repository) + { + PreProcessor preProcessor = null; + ChangesetPreProcessor changesetPreProcessor = + preProcessorFactory.createPreProcessor(repository); + + if (changesetPreProcessor != null) + { + preProcessor = new ChangesetPreProcessorWrapper(changesetPreProcessor); + } + + return preProcessor; + } + + //~--- fields ------------------------------------------------------------- + + /** Field description */ + private ChangesetPreProcessorFactory preProcessorFactory; + } + + + /** + * Class description + * + * + * @version Enter version here..., 12/06/16 + * @author Enter your name here... + */ + private static class ChangesetPreProcessorWrapper + implements PreProcessor + { + + /** + * Constructs ... + * + * + * @param preProcessor + */ + public ChangesetPreProcessorWrapper(ChangesetPreProcessor preProcessor) + { + this.preProcessor = preProcessor; + } + + //~--- methods ------------------------------------------------------------ + + /** + * Method description + * + * + * @param item + */ + @Override + public void process(Changeset item) + { + preProcessor.process(item); + } + + //~--- fields ------------------------------------------------------------- + + /** Field description */ + private ChangesetPreProcessor preProcessor; + } + + + /** + * Class description + * + * + * @version Enter version here..., 12/06/16 + * @author Enter your name here... + */ + private static class FileObjectPreProcessorFactoryWrapper + implements PreProcessorFactory + { + + /** + * Constructs ... + * + * + * @param preProcessorFactory + */ + public FileObjectPreProcessorFactoryWrapper( + FileObjectPreProcessorFactory preProcessorFactory) + { + this.preProcessorFactory = preProcessorFactory; + } + + //~--- methods ------------------------------------------------------------ + + /** + * Method description + * + * + * @param repository + * + * @return + */ + @Override + public PreProcessor createPreProcessor(Repository repository) + { + PreProcessor preProcessor = null; + FileObjectPreProcessor fileObjectPreProcessor = + preProcessorFactory.createPreProcessor(repository); + + if (fileObjectPreProcessor != null) + { + preProcessor = + new FileObjectPreProcessorWrapper(fileObjectPreProcessor); + } + + return preProcessor; + } + + //~--- fields ------------------------------------------------------------- + + /** Field description */ + private FileObjectPreProcessorFactory preProcessorFactory; + } + + + /** + * Class description + * + * + * @version Enter version here..., 12/06/16 + * @author Enter your name here... + */ + private static class FileObjectPreProcessorWrapper + implements PreProcessor + { + + /** + * Constructs ... + * + * + * @param preProcessor + */ + public FileObjectPreProcessorWrapper(FileObjectPreProcessor preProcessor) + { + this.preProcessor = preProcessor; + } + + //~--- methods ------------------------------------------------------------ + + /** + * Method description + * + * + * @param item + */ + @Override + public void process(FileObject item) + { + preProcessor.process(item); + } + + //~--- fields ------------------------------------------------------------- + + /** Field description */ + private FileObjectPreProcessor preProcessor; + } + + + /** + * Class description + * + * + * @param + * + * @version Enter version here..., 12/06/16 + * @author Enter your name here... + */ + private static class PreProcessorHandler + { + + /** + * Constructs ... + * + * + * @param preProcessorFactorySet + * @param preProcessorSet + * @param repository + */ + public PreProcessorHandler( + Collection> preProcessorFactorySet, + Collection> preProcessorSet, + Repository repository) + { + this.preProcessorFactorySet = preProcessorFactorySet; + this.preProcessorSet = preProcessorSet; + this.repository = repository; + } + + //~--- methods ------------------------------------------------------------ + + /** + * Method description + * + * + * + * + * @param preProcessorFactorySet + * @param repository + * @param changesets + * @param items + * @param + */ + public void callPreProcessorFactories(Iterable items) + { + if (Util.isNotEmpty(preProcessorFactorySet)) + { + for (PreProcessorFactory factory : preProcessorFactorySet) + { + PreProcessor preProcessor = factory.createPreProcessor(repository); + + if (preProcessor != null) + { + for (T item : items) + { + preProcessor.process(item); + } + } + } + } + } + + /** + * Method description + * + * + * + * @param preProcessorFactorySet + * @param repository + * @param item + * @param + */ + public void callPreProcessorFactories(T item) + { + if (Util.isNotEmpty(preProcessorFactorySet)) + { + for (PreProcessorFactory factory : preProcessorFactorySet) + { + PreProcessor cpp = factory.createPreProcessor(repository); + + if (cpp != null) + { + cpp.process(item); + } + } + } + } + + /** + * Method description + * + * + * @param changesets + * + * @param preProcessorSet + * @param items + * @param + */ + public void callPreProcessors(Iterable items) + { + if (Util.isNotEmpty(preProcessorSet)) + { + for (T item : items) + { + callPreProcessors(item); + } + } + } + + /** + * Method description + * + * + * @param c + * + * @param preProcessorSet + * @param item + * @param + */ + public void callPreProcessors(T item) + { + if (Util.isNotEmpty(preProcessorSet)) + { + for (PreProcessor preProcessor : preProcessorSet) + { + preProcessor.process(item); + } + } + } + + //~--- fields ------------------------------------------------------------- + + /** Field description */ + private Collection> preProcessorFactorySet; + + /** Field description */ + private Collection> preProcessorSet; + + /** Field description */ + private Repository repository; + } + + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private Collection blameLinePreProcessorFactorySet; + + /** Field description */ + private Collection blameLinePreProcessorSet; + + /** Field description */ + private Collection changesetPreProcessorFactorySet; + + /** Field description */ + private Collection changesetPreProcessorSet; + + /** Field description */ + private Collection fileObjectPreProcessorFactorySet; + + /** Field description */ + private Collection fileObjectPreProcessorSet; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/Repository.java b/scm-core/src/main/java/sonia/scm/repository/Repository.java index 965f601d65..ea022d4538 100644 --- a/scm-core/src/main/java/sonia/scm/repository/Repository.java +++ b/scm-core/src/main/java/sonia/scm/repository/Repository.java @@ -39,6 +39,7 @@ import com.google.common.base.Objects; import sonia.scm.BasicPropertiesAware; import sonia.scm.ModelObject; +import sonia.scm.util.HttpUtil; import sonia.scm.util.Util; import sonia.scm.util.ValidationUtil; @@ -164,6 +165,22 @@ public class Repository extends BasicPropertiesAware implements ModelObject repository.setArchived(archived); } + /** + * Creates the url of the repository. + * + * + * @param baseUrl base url of the server including the context path + * + * @return url of the repository + * @since 1.17 + */ + public String createUrl(String baseUrl) + { + String url = HttpUtil.append(baseUrl, type); + + return HttpUtil.append(url, name); + } + /** * Returns true if the {@link Repository} is the same as the obj argument. * @@ -343,7 +360,9 @@ public class Repository extends BasicPropertiesAware implements ModelObject * * * @return base url + * @deprecated use {@link #createUrl(String)} */ + @Deprecated public String getUrl() { return url; @@ -511,7 +530,9 @@ public class Repository extends BasicPropertiesAware implements ModelObject * * * @param url base url + * @deprecated */ + @Deprecated public void setUrl(String url) { this.url = url; @@ -550,6 +571,8 @@ public class Repository extends BasicPropertiesAware implements ModelObject /** Field description */ private String type; - /** Field description */ + /** + * @deprecated use {@link #createUrl(java.lang.String)} instead + */ private String url; } diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowser.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowser.java index abf137dbfd..35e36de289 100644 --- a/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowser.java +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowser.java @@ -33,6 +33,10 @@ package sonia.scm.repository; +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.repository.api.RepositoryService; + //~--- JDK imports ------------------------------------------------------------ import java.io.IOException; @@ -42,7 +46,10 @@ import java.io.OutputStream; * * @author Sebastian Sdorra * @since 1.5 + * + * @deprecated use {@link RepositoryService#getBrowseCommand()} instead. */ +@Deprecated public interface RepositoryBrowser { diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowserProvider.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowserProvider.java index b87d3481d0..cf017fd168 100644 --- a/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowserProvider.java +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowserProvider.java @@ -33,11 +33,18 @@ package sonia.scm.repository; +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.repository.api.RepositoryService; + /** * * @author Sebastian Sdorra * @since 1.5 + * + * @deprecated use {@link RepositoryService#getBrowseCommand()} instead. */ +@Deprecated public interface RepositoryBrowserProvider { diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowserUtil.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowserUtil.java index db31d17287..77abb191d1 100644 --- a/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowserUtil.java +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowserUtil.java @@ -44,6 +44,7 @@ import org.slf4j.LoggerFactory; import sonia.scm.NotSupportedFeatuerException; import sonia.scm.cache.Cache; import sonia.scm.cache.CacheManager; +import sonia.scm.repository.api.RepositoryService; import sonia.scm.util.AssertUtil; import sonia.scm.util.Util; @@ -59,8 +60,11 @@ import java.util.Set; * * @author Sebastian Sdorra * @since 1.6 + * + * @deprecated use {@link RepositoryService#getBrowseCommand()} instead. */ @Singleton +@Deprecated public class RepositoryBrowserUtil extends PartCacheClearHook { diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryCacheKeyFilter.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryCacheKeyFilter.java new file mode 100644 index 0000000000..c2c2c41b67 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryCacheKeyFilter.java @@ -0,0 +1,81 @@ +/** + * 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.repository; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.Filter; + +/** + * + * @author Sebastian Sdorra + * @since 1.17 + * + * @param + */ +public class RepositoryCacheKeyFilter + implements Filter +{ + + /** + * Constructs ... + * + * + * @param repositoryId + */ + public RepositoryCacheKeyFilter(String repositoryId) + { + this.repositoryId = repositoryId; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param item + * + * @return + */ + @Override + public boolean accept(T item) + { + return repositoryId.equals(item.getRepositoryId()); + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private String repositoryId; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryHookSupport.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryHookSupport.java index 63452822ef..3fced455cf 100644 --- a/scm-core/src/main/java/sonia/scm/repository/RepositoryHookSupport.java +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryHookSupport.java @@ -62,9 +62,8 @@ public interface RepositoryHookSupport /** * Fires a post receive hook event. This methods calls the - * {@link PostReceiveHook#onPostReceive(Repository, List)} of each registered - * {@link PostReceiveHook}. - * + * {@link PostReceiveRepositoryHook#onPostReceive(Repository, List)} + * of each registered {@link PostReceiveRepositoryHook}. * * @param repository that has changed * @param event @@ -73,8 +72,8 @@ public interface RepositoryHookSupport /** * Fires a post receive hook event. This methods calls the - * {@link PostReceiveHook#onPostReceive(Repository, List)} of each registered - * {@link PostReceiveHook}. + * {@link PostReceiveRepositoryHook#onPostReceive(Repository, List)} + * of each registered {@link PostReceiveRepositoryHook}. * * * @param type of the repository diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryTypePredicate.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryTypePredicate.java index 7b6eb0b302..ac7d389a60 100644 --- a/scm-core/src/main/java/sonia/scm/repository/RepositoryTypePredicate.java +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryTypePredicate.java @@ -1,34 +1,35 @@ /** - * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * 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 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. + * 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.repository; //~--- non-JDK imports -------------------------------------------------------- diff --git a/scm-core/src/main/java/sonia/scm/repository/SubRepository.java b/scm-core/src/main/java/sonia/scm/repository/SubRepository.java index a00784cae3..3c8acc4831 100644 --- a/scm-core/src/main/java/sonia/scm/repository/SubRepository.java +++ b/scm-core/src/main/java/sonia/scm/repository/SubRepository.java @@ -39,6 +39,8 @@ import com.google.common.base.Objects; //~--- JDK imports ------------------------------------------------------------ +import java.io.Serializable; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; @@ -50,9 +52,14 @@ import javax.xml.bind.annotation.XmlRootElement; */ @XmlRootElement(name = "subrepository") @XmlAccessorType(XmlAccessType.FIELD) -public class SubRepository +public class SubRepository implements Serializable { + /** Field description */ + private static final long serialVersionUID = 6960065820378492531L; + + //~--- constructors --------------------------------------------------------- + /** * Constructs ... * diff --git a/scm-core/src/main/java/sonia/scm/repository/api/BlameCommandBuilder.java b/scm-core/src/main/java/sonia/scm/repository/api/BlameCommandBuilder.java new file mode 100644 index 0000000000..0d0b5158e1 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/api/BlameCommandBuilder.java @@ -0,0 +1,366 @@ +/** + * 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.repository.api; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Objects; +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sonia.scm.cache.Cache; +import sonia.scm.cache.CacheManager; +import sonia.scm.repository.BlameResult; +import sonia.scm.repository.PreProcessorUtil; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryCacheKey; +import sonia.scm.repository.RepositoryException; +import sonia.scm.repository.spi.BlameCommand; +import sonia.scm.repository.spi.BlameCommandRequest; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; +import java.io.Serializable; + +/** + * Shows changeset information by line for a given file. + * Blame is also known as annotate in some SCM systems.
+ *
+ * Sample: + *
+ *
+ * Print each line number and code of the file scm-core/pom.xml at + * revision 60c2f2783368:
+ *

+ * BlameCommandBuilder blame = repositoryService.getBlameCommand();
+ * BlameResult result = blame.setRevision("60c2f2783368")
+ *                           .getBlameResult("scm-core/pom.xml");
+ *
+ * for ( BlameLine line : result ){
+ *   System.out.println(line.getLineNumber() + ": " + line.getCode());
+ * }
+ * 
+ * + * @author Sebastian Sdorra + * @since 1.17 + */ +public final class BlameCommandBuilder +{ + + /** name of the cache */ + static final String CACHE_NAME = "sonia.cache.cmd.blame"; + + /** + * the logger for BlameCommandBuilder + */ + private static final Logger logger = + LoggerFactory.getLogger(BlameCommandBuilder.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs a new {@link BlameCommandBuilder}, this constructor should + * only be called from the {@link RepositoryService}. + * + * @param cacheManager cache manager + * @param blameCommand implementation of the {@link BlameCommand} + * @param repository repository to query + * @param preProcessorUtil + */ + BlameCommandBuilder(CacheManager cacheManager, BlameCommand blameCommand, + Repository repository, PreProcessorUtil preProcessorUtil) + { + this.cache = cacheManager.getCache(CacheKey.class, BlameResult.class, + CACHE_NAME); + this.blameCommand = blameCommand; + this.repository = repository; + this.preProcessorUtil = preProcessorUtil; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Reset each parameter to its default value. + * + * @return {@code this} + */ + public BlameCommandBuilder reset() + { + request.reset(); + this.disableCache = false; + this.disablePreProcessors = false; + + return this; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Returns changeset informations by line for the given file. + * + * @param path path of the file + * @return changeset informations by line for the given file + * + * @throws IllegalArgumentException if the path is null or empty + * + * @throws IOException + * @throws RepositoryException + */ + public BlameResult getBlameResult(String path) + throws IOException, RepositoryException + { + Preconditions.checkArgument(!Strings.isNullOrEmpty(path), + "path is required"); + + BlameCommandRequest requestClone = request.clone(); + + requestClone.setPath(path); + + BlameResult result = null; + + if (disableCache) + { + if (logger.isDebugEnabled()) + { + logger.debug("create blame for {} with disabled cache", requestClone); + } + + result = blameCommand.getBlameResult(requestClone); + } + else + { + CacheKey key = new CacheKey(repository, request); + + result = cache.get(key); + + if (result == null) + { + if (logger.isDebugEnabled()) + { + logger.debug("create blame for {}", requestClone); + } + + result = blameCommand.getBlameResult(requestClone); + + if (result != null) + { + cache.put(key, result); + } + } + else if (logger.isDebugEnabled()) + { + logger.debug("retrive blame from cache for {}", requestClone); + } + } + + if (!disablePreProcessors && (result != null)) + { + preProcessorUtil.prepareForReturn(repository, result); + } + + return result; + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Disables the cache. This means that every {@link BlameResult} + * is directly retrieved from the {@link Repository}. Note: Disabling + * the cache cost a lot of performance and could be much more slower. + * + * + * @param disableCache true to disable the cache + * + * @return {@code this} + */ + public BlameCommandBuilder setDisableCache(boolean disableCache) + { + this.disableCache = disableCache; + + return this; + } + + /** + * Disable the execution of pre processors. + * + * + * @param disablePreProcessors true to disable the pre processors execution + * + * @return {@code this} + */ + public BlameCommandBuilder setDisablePreProcessors( + boolean disablePreProcessors) + { + this.disablePreProcessors = disablePreProcessors; + + return this; + } + + /** + * Sets the start revision for the blame. + * + * + * @param revision revision to start from + * + * @return {@code this} + */ + public BlameCommandBuilder setRevision(String revision) + { + request.setRevision(revision); + + return this; + } + + //~--- inner classes -------------------------------------------------------- + + /** + * Key for cache. + * + * + * @version Enter version here..., 12/06/05 + * @author Enter your name here... + */ + static class CacheKey implements RepositoryCacheKey, Serializable + { + + /** Field description */ + private static final long serialVersionUID = 8373766042131887789L; + + //~--- constructors ------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param repository + * @param request + */ + public CacheKey(Repository repository, BlameCommandRequest request) + { + this.repositoryId = repository.getId(); + this.request = request; + } + + //~--- methods ------------------------------------------------------------ + + /** + * Method description + * + * + * @param obj + * + * @return + */ + @Override + public boolean equals(Object obj) + { + if (obj == null) + { + return false; + } + + if (getClass() != obj.getClass()) + { + return false; + } + + final CacheKey other = (CacheKey) obj; + + return Objects.equal(repositoryId, other.repositoryId) + && Objects.equal(request, other.request); + } + + /** + * Method description + * + * + * @return + */ + @Override + public int hashCode() + { + return Objects.hashCode(repositoryId, request); + } + + //~--- get methods -------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + public String getRepositoryId() + { + return repositoryId; + } + + //~--- fields ------------------------------------------------------------- + + /** Field description */ + private String repositoryId; + + /** Field description */ + private BlameCommandRequest request; + } + + + //~--- fields --------------------------------------------------------------- + + /** implementation of the blame command */ + private BlameCommand blameCommand; + + /** the cache */ + private Cache cache; + + /** disable change */ + private boolean disableCache = false; + + /** disable the execution of pre processors */ + private boolean disablePreProcessors = false; + + /** Field description */ + private PreProcessorUtil preProcessorUtil; + + /** the repository */ + private Repository repository; + + /** request for the blame command implementation */ + private BlameCommandRequest request = new BlameCommandRequest(); +} diff --git a/scm-core/src/main/java/sonia/scm/repository/api/BrowseCommandBuilder.java b/scm-core/src/main/java/sonia/scm/repository/api/BrowseCommandBuilder.java new file mode 100644 index 0000000000..e3eb0a0be9 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/api/BrowseCommandBuilder.java @@ -0,0 +1,384 @@ +/** + * 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.repository.api; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Objects; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sonia.scm.cache.Cache; +import sonia.scm.cache.CacheManager; +import sonia.scm.repository.BrowserResult; +import sonia.scm.repository.FileObject; +import sonia.scm.repository.FileObjectNameComparator; +import sonia.scm.repository.PreProcessorUtil; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryCacheKey; +import sonia.scm.repository.RepositoryException; +import sonia.scm.repository.spi.BrowseCommand; +import sonia.scm.repository.spi.BrowseCommandRequest; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; +import java.io.Serializable; + +import java.util.Collections; +import java.util.List; + +/** + * BrowseCommandBuilder is able to browse the files of a {@link Repository}. + *

+ * Sample: + *
+ *
+ * Print all paths from folder scm-core at revision 11aeec7db845:
+ *

+ * BrowseCommandBuilder browse = repositoryService.getBrowseCommand();
+ * BrowserResult result = browse.setPath("scm-core")
+ *                              .setRevision("11aeec7db845")
+ *                              .getBrowserResult();
+ *
+ * for ( FileObject fo : result ){
+ *   System.out.println( fo.getPath() );
+ * }
+ * 
+ * + * @author Sebastian Sdorra + * @since 1.17 + */ +public final class BrowseCommandBuilder +{ + + /** Name of the cache */ + static final String CACHE_NAME = "sonia.cache.cmd.browse"; + + /** + * the logger for BrowseCommandBuilder + */ + private static final Logger logger = + LoggerFactory.getLogger(BrowseCommandBuilder.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs a new {@link LogCommandBuilder}, this constructor should + * only be called from the {@link RepositoryService}. + * + * @param cacheManager cache manager + * @param logCommand implementation of the {@link LogCommand} + * @param browseCommand + * @param repository repository to query + * @param preProcessorUtil + */ + BrowseCommandBuilder(CacheManager cacheManager, BrowseCommand browseCommand, + Repository repository, PreProcessorUtil preProcessorUtil) + { + this.cache = cacheManager.getCache(CacheKey.class, BrowserResult.class, + CACHE_NAME); + this.browseCommand = browseCommand; + this.repository = repository; + this.preProcessorUtil = preProcessorUtil; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Reset each parameter to its default value. + * + * + * @return {@code this} + */ + public BrowseCommandBuilder reset() + { + request.reset(); + this.disableCache = false; + this.disablePreProcessors = false; + + return this; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Return the files for the given parameters. + * + * + * @return files for the given parameters + * + * @throws IOException + * @throws RepositoryException + */ + public BrowserResult getBrowserResult() + throws IOException, RepositoryException + { + BrowserResult result = null; + + if (disableCache) + { + if (logger.isDebugEnabled()) + { + logger.debug("create browser result for {} with disabled cache", + request); + } + + result = browseCommand.getBrowserResult(request); + } + else + { + CacheKey key = new CacheKey(repository, request); + + result = cache.get(key); + + if (result == null) + { + if (logger.isDebugEnabled()) + { + logger.debug("create browser result for {}", request); + } + + result = browseCommand.getBrowserResult(request); + + if (result != null) + { + cache.put(key, result); + } + } + else if (logger.isDebugEnabled()) + { + logger.debug("retrive browser result from cache for {}", request); + } + } + + if (!disablePreProcessors && (result != null)) + { + preProcessorUtil.prepareForReturn(repository, result); + + List fileObjects = result.getFiles(); + + if (fileObjects != null) + { + Collections.sort(fileObjects, FileObjectNameComparator.instance); + result.setFiles(fileObjects); + } + } + + return result; + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Disables the cache. This means that every {@link BrowserResult} + * is directly retrieved from the {@link Repository}. Note: Disabling + * the cache cost a lot of performance and could be much more slower. + * + * + * @param disableCache true to disable the cache + * + * @return {@code this} + */ + public BrowseCommandBuilder setDisableCache(boolean disableCache) + { + this.disableCache = disableCache; + + return this; + } + + /** + * Disable the execution of pre processors. + * + * + * @param disablePreProcessors true to disable the pre processors execution + * + * @return {@code this} + */ + public BrowseCommandBuilder setDisablePreProcessors( + boolean disablePreProcessors) + { + this.disablePreProcessors = disablePreProcessors; + + return this; + } + + /** + * Retrieve only files which are children of the given path. + * This path have to be a directory. + * + * @param path path of the folder + * + * @return {@code this} + */ + public BrowseCommandBuilder setPath(String path) + { + request.setPath(path); + + return this; + } + + /** + * Retrieve only files of the given revision. + * + * @param revision revision for the files + * + * @return {@code this} + */ + public BrowseCommandBuilder setRevision(String revision) + { + request.setRevision(revision); + + return this; + } + + //~--- inner classes -------------------------------------------------------- + + /** + * Key for cache. + * + * + * @version Enter version here..., 12/06/05 + * @author Enter your name here... + */ + static class CacheKey implements RepositoryCacheKey, Serializable + { + + /** Field description */ + private static final long serialVersionUID = 8078650026812373524L; + + //~--- constructors ------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param repository + * @param request + */ + public CacheKey(Repository repository, BrowseCommandRequest request) + { + this.repositoryId = repository.getId(); + this.request = request; + } + + //~--- methods ------------------------------------------------------------ + + /** + * Method description + * + * + * @param obj + * + * @return + */ + @Override + public boolean equals(Object obj) + { + if (obj == null) + { + return false; + } + + if (getClass() != obj.getClass()) + { + return false; + } + + final CacheKey other = (CacheKey) obj; + + return Objects.equal(repositoryId, other.repositoryId) + && Objects.equal(request, other.request); + } + + /** + * Method description + * + * + * @return + */ + @Override + public int hashCode() + { + return Objects.hashCode(repositoryId, request); + } + + //~--- get methods -------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + public String getRepositoryId() + { + return repositoryId; + } + + //~--- fields ------------------------------------------------------------- + + /** Field description */ + private String repositoryId; + + /** Field description */ + private BrowseCommandRequest request; + } + + + //~--- fields --------------------------------------------------------------- + + /** implementation of the browse command */ + private BrowseCommand browseCommand; + + /** cache */ + private Cache cache; + + /** disables the cache */ + private boolean disableCache = false; + + /** disables the execution of pre processors */ + private boolean disablePreProcessors = false; + + /** Field description */ + private PreProcessorUtil preProcessorUtil; + + /** the repsitory */ + private Repository repository; + + /** request for the command */ + private BrowseCommandRequest request = new BrowseCommandRequest(); +} diff --git a/scm-core/src/main/java/sonia/scm/repository/api/CatCommandBuilder.java b/scm-core/src/main/java/sonia/scm/repository/api/CatCommandBuilder.java new file mode 100644 index 0000000000..546da6c167 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/api/CatCommandBuilder.java @@ -0,0 +1,213 @@ +/** + * 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.repository.api; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; +import com.google.common.io.Closeables; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryException; +import sonia.scm.repository.spi.CatCommand; +import sonia.scm.repository.spi.CatCommandRequest; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * Shows the content of a file in the {@link Repository}.
+ *
+ * Sample: + *
+ *
+ * Print the content of the file core/pom.xml from revision 46a23689ac91:
+ *

+ * CatCommandBuilder cat = repositoryService.getCatCommand();
+ * String content = cat.setRevision("46a23689ac91").getContent("core/pom.xml");
+ * System.out.println(content);
+ * 
+ * + * @author Sebastian Sdorra + * @since 1.17 + */ +public final class CatCommandBuilder +{ + + /** + * the logger for CatCommandBuilder + */ + private static final Logger logger = + LoggerFactory.getLogger(CatCommandBuilder.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs a new {@link CatCommandBuilder}, this constructor should + * only be called from the {@link RepositoryService}. + * + * @param catCommand implementation of the {@link CatCommand} + */ + CatCommandBuilder(CatCommand catCommand) + { + this.catCommand = catCommand; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Reset each parameter to its default value. + * + * @return {@code this} + */ + public CatCommandBuilder reset() + { + request.reset(); + + return this; + } + + /** + * Passes the content of the given file to the outputstream. + * + * @param outputStream outputstream for the content + * @param path file path + * + * @return {@code this} + * + * @throws IOException + * @throws RepositoryException + */ + public CatCommandBuilder retriveContent(OutputStream outputStream, + String path) + throws IOException, RepositoryException + { + getCatResult(outputStream, path); + + return this; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Returns the content of the given file. + * + * @param path file path + * @return content of the file + * + * @throws IOException + * @throws RepositoryException + */ + public String getContent(String path) throws IOException, RepositoryException + { + String content = null; + ByteArrayOutputStream baos = null; + + try + { + baos = new ByteArrayOutputStream(); + getCatResult(baos, path); + content = baos.toString(); + } + finally + { + Closeables.closeQuietly(baos); + } + + return content; + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Sets the revision of the file. + * + * + * @param revision revision of the file + * + * @return {@code this} + */ + public CatCommandBuilder setRevision(String revision) + { + request.setRevision(revision); + + return this; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Executes the cat command. + * + * + * @param outputStream the outputstream for the content + * @param path path of the file + * + * @throws IOException + * @throws RepositoryException + */ + private void getCatResult(OutputStream outputStream, String path) + throws IOException, RepositoryException + { + Preconditions.checkNotNull(outputStream, "OutputStream is required"); + Preconditions.checkArgument(!Strings.isNullOrEmpty(path), + "path is required"); + + CatCommandRequest requestClone = request.clone(); + + requestClone.setPath(path); + + if (logger.isDebugEnabled()) + { + logger.debug("create cat for {}", requestClone); + } + + catCommand.getCatResult(requestClone, outputStream); + } + + //~--- fields --------------------------------------------------------------- + + /** implementation of the cat command */ + private CatCommand catCommand; + + /** request for the cat command */ + private CatCommandRequest request = new CatCommandRequest(); +} diff --git a/scm-core/src/main/java/sonia/scm/repository/api/Command.java b/scm-core/src/main/java/sonia/scm/repository/api/Command.java new file mode 100644 index 0000000000..5caba59440 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/api/Command.java @@ -0,0 +1,45 @@ +/** + * 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.repository.api; + +/** + * Enumeration of available commands. + * + * @author Sebastian Sdorra + * @since 1.17 + */ +public enum Command +{ + LOG, BROWSE, CAT, DIFF, BLAME +} diff --git a/scm-core/src/main/java/sonia/scm/repository/api/CommandNotSupportedException.java b/scm-core/src/main/java/sonia/scm/repository/api/CommandNotSupportedException.java new file mode 100644 index 0000000000..3b51254659 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/api/CommandNotSupportedException.java @@ -0,0 +1,94 @@ +/** + * 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.repository.api; + +/** + * This exception is thrown if the {@link RepositoryService} does not support + * the requested command. + * + * @author Sebastian Sdorra + * @since 1.17 + */ +public final class CommandNotSupportedException extends RuntimeException +{ + + /** + * Constructs a new {@link CommandNotSupportedException}. + * + * + * @param command not supported command + */ + public CommandNotSupportedException(Command command) + { + //J- + this( + command, + "The requested feature " + .concat(command.toString()) + .concat(" is not supported") + ); + //J+ + } + + /** + * Constructs a new {@link CommandNotSupportedException}. + * + * + * @param command not supported command + * @param message message to be shown + */ + public CommandNotSupportedException(Command command, String message) + { + super(message); + this.command = command; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Returns the command which is not supported. + * + * + * @return not supported command + */ + public Command getCommand() + { + return command; + } + + //~--- fields --------------------------------------------------------------- + + /** not supported command */ + private Command command; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/api/DiffCommandBuilder.java b/scm-core/src/main/java/sonia/scm/repository/api/DiffCommandBuilder.java new file mode 100644 index 0000000000..dfe874813e --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/api/DiffCommandBuilder.java @@ -0,0 +1,215 @@ +/** + * 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.repository.api; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Preconditions; +import com.google.common.io.Closeables; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sonia.scm.repository.RepositoryException; +import sonia.scm.repository.spi.DiffCommand; +import sonia.scm.repository.spi.DiffCommandRequest; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * Shows differences between revisions for a specified file or + * the entire revision.
+ * Note: One of the parameter path or revision have to be set.
+ *
+ * Sample: + *
+ *
+ * Print the differences from revision 33b93c443867:
+ *

+ * DiffCommandBuilder diff = repositoryService.getDiffCommand();
+ * String content = diff.setRevision("33b93c443867").getContent();
+ * System.out.println(content);
+ * 
+ * + * + * TODO check current behavior. + * + * @author Sebastian Sdorra + * @since 1.17 + */ +public final class DiffCommandBuilder +{ + + /** + * the logger for DiffCommandBuilder + */ + private static final Logger logger = + LoggerFactory.getLogger(DiffCommandBuilder.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs a new {@link DiffCommandBuilder}, this constructor should + * only be called from the {@link RepositoryService}. + * + * @param implementation of {@link DiffCommand} + * + * @param diffCommand + */ + DiffCommandBuilder(DiffCommand diffCommand) + { + this.diffCommand = diffCommand; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Passes the difference of the given parameter to the outputstream. + * + * + * @param outputStream outputstream for the difference + * + * @return {@code this} + * + * @throws IOException + * @throws RepositoryException + */ + public DiffCommandBuilder retriveContent(OutputStream outputStream) + throws IOException, RepositoryException + { + getDiffResult(outputStream); + + return this; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Returns the content of the difference as string. + * + * @return content of the difference + * + * @throws IOException + * @throws RepositoryException + */ + public String getContent() throws IOException, RepositoryException + { + String content = null; + ByteArrayOutputStream baos = null; + + try + { + baos = new ByteArrayOutputStream(); + getDiffResult(baos); + content = baos.toString(); + } + finally + { + Closeables.closeQuietly(baos); + } + + return content; + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Show the difference only for the given path. + * + * + * @param path path for difference + * + * @return {@code this} + */ + public DiffCommandBuilder setPath(String path) + { + request.setPath(path); + + return this; + } + + /** + * Show the difference only for the given revision. + * + * + * @param revision revision for difference + * + * @return {@code this} + */ + public DiffCommandBuilder setRevision(String revision) + { + request.setRevision(revision); + + return this; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param outputStream + * @param path + * + * @throws IOException + * @throws RepositoryException + */ + private void getDiffResult(OutputStream outputStream) + throws IOException, RepositoryException + { + Preconditions.checkNotNull(outputStream, "OutputStream is required"); + Preconditions.checkArgument(request.isValid(), + "path and/or revision is required"); + + if (logger.isDebugEnabled()) + { + logger.debug("create diff for {}", request); + } + + diffCommand.getDiffResult(request, outputStream); + } + + //~--- fields --------------------------------------------------------------- + + /** implementation of the diff command */ + private DiffCommand diffCommand; + + /** request for the diff command implementation */ + private DiffCommandRequest request = new DiffCommandRequest(); +} diff --git a/scm-core/src/main/java/sonia/scm/repository/api/LogCommandBuilder.java b/scm-core/src/main/java/sonia/scm/repository/api/LogCommandBuilder.java new file mode 100644 index 0000000000..e39c3ced14 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/api/LogCommandBuilder.java @@ -0,0 +1,528 @@ +/** + * 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.repository.api; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Objects; +import com.google.common.collect.ImmutableList; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sonia.scm.cache.Cache; +import sonia.scm.cache.CacheManager; +import sonia.scm.repository.Changeset; +import sonia.scm.repository.ChangesetPagingResult; +import sonia.scm.repository.PreProcessorUtil; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryCacheKey; +import sonia.scm.repository.RepositoryException; +import sonia.scm.repository.spi.LogCommand; +import sonia.scm.repository.spi.LogCommandRequest; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; +import java.io.Serializable; + +/** + * LogCommandBuilder is able to show the history of a file in a + * {@link Repository} or the entire history of a {@link Repository}. + * This class could be used to retrieve a single {@link Changeset} by its id + * or to get a list of changesets in a {@link ChangesetPagingResult} + * which can be used for paging.
+ *
+ * Samples: + *
+ *
+ * Retrieve a single {@link Changeset}:
+ *

+ * LogCommand log = repositoryService.getLogCommand();
+ * Changeset changeset = log.getChangeset("id-of-the-commit");
+ * 
+ * + * Retrieve changesets of a {@link Repository} with paging:
+ *

+ * LogCommand log = repositoryService.getLogCommand();
+ * ChangesetPagingResult changesetPagingResult =
+ *          log.setPagingStart(25).setPagingLimit(25).getChangesets();
+ * 
+ * + * Retrieve all changesets of a file in a {@link Repository}:
+ *

+ * LogCommand log = repositoryService.getLogCommand();
+ * ChangesetPagingResult changesetPagingResult =
+ *          log.setPath("pom.xml").disablePagingLimit().getChangesets();
+ * 
+ * + * @author Sebastian Sdorra + * @since 1.17 + */ +public final class LogCommandBuilder +{ + + /** name of the cache */ + static final String CACHE_NAME = "sonia.cache.cmd.log"; + + /** + * the logger for LogCommandBuilder + */ + private static final Logger logger = + LoggerFactory.getLogger(LogCommandBuilder.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs a new {@link LogCommandBuilder}, this constructor should + * only be called from the {@link RepositoryService}. + * + * @param cacheManager cache manager + * @param logCommand implementation of the {@link LogCommand} + * @param repository repository to query + * @param preProcessorUtil + */ + LogCommandBuilder(CacheManager cacheManager, LogCommand logCommand, + Repository repository, PreProcessorUtil preProcessorUtil) + { + this.cache = cacheManager.getCache(CacheKey.class, + ChangesetPagingResult.class, CACHE_NAME); + this.logCommand = logCommand; + this.repository = repository; + this.preProcessorUtil = preProcessorUtil; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Disable paging limit all available changesets will be retrieved. + * This method does the same as {@link #setPagingLimit(int)} + * with a value of -1. + * + * + * @return {@code this} + */ + public LogCommandBuilder disablePagingLimit() + { + request.setPagingLimit(-1); + + return this; + } + + /** + * Reset each parameter to its default value. + * + * + * @return {@code this} + */ + public LogCommandBuilder reset() + { + request.reset(); + this.disableCache = false; + this.disablePreProcessors = false; + + return this; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Returns the {@link Changeset} with the given id or null if the + * {@link Changeset} could not be found in the {@link Repository}. + * + * + * @param id id of the {@link Changeset} + * + * @return the {@link Changeset} with the given id or null + * + * @throws IOException + * @throws RepositoryException + */ + public Changeset getChangeset(String id) + throws IOException, RepositoryException + { + Changeset changeset = null; + + if (disableCache) + { + if (logger.isDebugEnabled()) + { + logger.debug("get changeset for {} with disabled cache", id); + } + + changeset = logCommand.getChangeset(id); + } + else + { + CacheKey key = new CacheKey(repository, id); + ChangesetPagingResult cpr = cache.get(key); + + if (cpr == null) + { + if (logger.isDebugEnabled()) + { + logger.debug("get changeset for {}", id); + } + + changeset = logCommand.getChangeset(id); + + if (changeset != null) + { + cpr = new ChangesetPagingResult(1, ImmutableList.of(changeset)); + cache.put(key, cpr); + } + } + else + { + if (logger.isDebugEnabled()) + { + logger.debug("get changeset {} from cache", id); + } + + changeset = cpr.iterator().next(); + } + } + + if (!disablePreProcessors && (changeset != null)) + { + preProcessorUtil.prepareForReturn(repository, changeset); + } + + return changeset; + } + + /** + * Return all changesets with the given parameters. + * + * + * @return all changesets with the given parameters + * + * @throws IOException + * @throws RepositoryException + */ + public ChangesetPagingResult getChangesets() + throws IOException, RepositoryException + { + ChangesetPagingResult cpr = null; + + if (disableCache) + { + if (logger.isDebugEnabled()) + { + logger.debug("get changesets for {} with disabled cache", request); + } + + cpr = logCommand.getChangesets(request); + } + else + { + CacheKey key = new CacheKey(repository, request); + + cpr = cache.get(key); + + if (cpr == null) + { + if (logger.isDebugEnabled()) + { + logger.debug("get changesets for {}", request); + } + + cpr = logCommand.getChangesets(request); + + if (cpr != null) + { + cache.put(key, cpr); + } + } + else if (logger.isDebugEnabled()) + { + logger.debug("get changesets from cache for {}", request); + } + } + + if (!disablePreProcessors && (cpr != null)) + { + preProcessorUtil.prepareForReturn(repository, cpr); + } + + return cpr; + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Disables the cache for changesets. This means that every {@link Changeset} + * is directly retrieved from the {@link Repository}. Note: Disabling + * the cache cost a lot of performance and could be much more slower. + * + * + * @param disableCache true to disable the cache + * + * @return {@code this} + */ + public LogCommandBuilder setDisableCache(boolean disableCache) + { + this.disableCache = disableCache; + + return this; + } + + /** + * Disable the execution of pre processors. + * + * + * @param disablePreProcessors true to disable the pre processors execution + * + * @return {@code this} + */ + public LogCommandBuilder setDisablePreProcessors(boolean disablePreProcessors) + { + this.disablePreProcessors = disablePreProcessors; + + return this; + } + + /** + * Retrieve changesets until the given the {@link Changeset} + * with the given id. + * + * + * @param endChangeset id of the end {@link Changeset} + * + * @return {@code this} + */ + public LogCommandBuilder setEndChangeset(String endChangeset) + { + request.setEndChangeset(endChangeset); + + return this; + } + + /** + * Set the limit for the returned changesets. The default value is 20. + * Setting the value to -1 means to disable the limit. + * + * + * @param pagingLimit limit for returned changesets + * + * @return {@code this} + */ + public LogCommandBuilder setPagingLimit(int pagingLimit) + { + request.setPagingLimit(pagingLimit); + + return this; + } + + /** + * Sets the start value for paging. The value is 0. + * + * + * @param pagingStart start value for paging + * + * @return {@code this} + */ + public LogCommandBuilder setPagingStart(int pagingStart) + { + request.setPagingStart(pagingStart); + + return this; + } + + /** + * Retrieve only changesets which are affect the given path. + * + * + * @param path file path in the {@link Repository}. + * + * @return {@code this} + */ + public LogCommandBuilder setPath(String path) + { + request.setPath(path); + + return this; + } + + /** + * Start at the given {@link Changeset}. + * + * + * @param startChangeset changeset id to start with + * + * @return {@code this} + */ + public LogCommandBuilder setStartChangeset(String startChangeset) + { + request.setStartChangeset(startChangeset); + + return this; + } + + //~--- inner classes -------------------------------------------------------- + + /** + * Class description + * + * + * @version Enter version here..., 12/06/05 + * @author Enter your name here... + */ + static class CacheKey implements RepositoryCacheKey, Serializable + { + + /** Field description */ + private static final long serialVersionUID = 5701675009949268863L; + + //~--- constructors ------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param repository + * @param request + */ + public CacheKey(Repository repository, LogCommandRequest request) + { + this.repositoryId = repository.getId(); + this.request = request; + } + + /** + * Constructs ... + * + * + * + * @param repository + * @param changesetId + */ + public CacheKey(Repository repository, String changesetId) + { + this.repositoryId = repository.getId(); + this.changesetId = changesetId; + } + + //~--- methods ------------------------------------------------------------ + + /** + * Method description + * + * + * @param obj + * + * @return + */ + @Override + public boolean equals(Object obj) + { + if (obj == null) + { + return false; + } + + if (getClass() != obj.getClass()) + { + return false; + } + + final CacheKey other = (CacheKey) obj; + + return Objects.equal(repositoryId, other.repositoryId) + && Objects.equal(changesetId, other.changesetId) + && Objects.equal(request, other.request); + } + + /** + * Method description + * + * + * @return + */ + @Override + public int hashCode() + { + return Objects.hashCode(repositoryId, changesetId, request); + } + + //~--- get methods -------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + public String getRepositoryId() + { + return repositoryId; + } + + //~--- fields ------------------------------------------------------------- + + /** Field description */ + private String changesetId; + + /** Field description */ + private String repositoryId; + + /** Field description */ + private LogCommandRequest request; + } + + + //~--- fields --------------------------------------------------------------- + + /** cache for changesets */ + private Cache cache; + + /** disable cache */ + private boolean disableCache = false; + + /** disable the execution of pre processors */ + private boolean disablePreProcessors = false; + + /** Implementation of the log command */ + private LogCommand logCommand; + + /** Field description */ + private PreProcessorUtil preProcessorUtil; + + /** repository to query */ + private Repository repository; + + /** request for the log command */ + private LogCommandRequest request = new LogCommandRequest(); +} diff --git a/scm-core/src/main/java/sonia/scm/repository/api/RepositoryService.java b/scm-core/src/main/java/sonia/scm/repository/api/RepositoryService.java new file mode 100644 index 0000000000..8c77eb83f8 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/api/RepositoryService.java @@ -0,0 +1,271 @@ +/** + * 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.repository.api; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sonia.scm.cache.CacheManager; +import sonia.scm.repository.PreProcessorUtil; +import sonia.scm.repository.Repository; +import sonia.scm.repository.spi.RepositoryServiceProvider; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.Closeable; +import java.io.IOException; + +/** + * From the {@link RepositoryService} it is possible to access all commands for + * a single {@link Repository}. The {@link RepositoryService} is only access + * able from the {@link RepositoryServiceFactory}.
+ *
+ * + * Note: Not every {@link RepositoryService} supports every command. If + * the command is not supported the method will trow a + * {@link CommandNotSupportedException}. It is possible to check if the command + * is supported by the {@link RepositoryService} with the + * {@link RepositoryService#isSupported(Command)} method.
+ *
+ * + * Warning: You should always close the connection to the repository + * after work is finished. For closing the connection to the repository use the + * {@link #close()} method. + * + * @author Sebastian Sdorra + * @since 1.17 + * + * @apiviz.uses sonia.scm.repository.api.Command + * @apiviz.uses sonia.scm.repository.api.BlameCommandBuilder + * @apiviz.uses sonia.scm.repository.api.BrowseCommandBuilder + * @apiviz.uses sonia.scm.repository.api.CatCommandBuilder + * @apiviz.uses sonia.scm.repository.api.DiffCommandBuilder + * @apiviz.uses sonia.scm.repository.api.LogCommandBuilder + */ +public final class RepositoryService implements Closeable +{ + + /** + * the logger for RepositoryService + */ + private static final Logger logger = + LoggerFactory.getLogger(RepositoryService.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs a new {@link RepositoryService}. This constructor should only + * be called from the {@link RepositoryServiceFactory}. + * + * @param cacheManager cache manager + * @param provider implementation for {@link RepositoryServiceProvider} + * @param repository the repository + * @param preProcessorUtil + */ + RepositoryService(CacheManager cacheManager, + RepositoryServiceProvider provider, Repository repository, + PreProcessorUtil preProcessorUtil) + { + this.cacheManager = cacheManager; + this.provider = provider; + this.repository = repository; + this.preProcessorUtil = preProcessorUtil; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Closes the connection to the repository and releases all locks + * and resources. This method should be called in a finally block e.g.: + * + *

+   * RepositoryService service = null;
+   * try {
+   *   service = factory.create("repositoryId");
+   *   // do something with the service
+   * } finally {
+   *   if ( service != null ){
+   *     service.close();
+   *   }
+   * }
+   * 
+ */ + @Override + public void close() + { + try + { + provider.close(); + } + catch (IOException ex) + { + logger.error("cound not close repository service provider", ex); + } + } + + //~--- get methods ---------------------------------------------------------- + + /** + * The blame command shows changeset information by line for a given file. + * + * @return instance of {@link BlameCommandBuilder} + * @throws CommandNotSupportedException if the command is not supported + * by the implementation of the repository service provider. + */ + public BlameCommandBuilder getBlameCommand() + { + if (logger.isDebugEnabled()) + { + logger.debug("create blame command for repository {}", + repository.getName()); + } + + return new BlameCommandBuilder(cacheManager, provider.getBlameCommand(), + repository, preProcessorUtil); + } + + /** + * The browse command allows browsing of a repository. + * + * @return instance of {@link BrowseCommandBuilder} + * @throws CommandNotSupportedException if the command is not supported + * by the implementation of the repository service provider. + */ + public BrowseCommandBuilder getBrowseCommand() + { + if (logger.isDebugEnabled()) + { + logger.debug("create browse command for repository {}", + repository.getName()); + } + + return new BrowseCommandBuilder(cacheManager, provider.getBrowseCommand(), + repository, preProcessorUtil); + } + + /** + * The cat command show the content of a given file. + * + * @return instance of {@link CatCommandBuilder} + * @throws CommandNotSupportedException if the command is not supported + * by the implementation of the repository service provider. + */ + public CatCommandBuilder getCatCommand() + { + if (logger.isDebugEnabled()) + { + logger.debug("create cat command for repository {}", + repository.getName()); + } + + return new CatCommandBuilder(provider.getCatCommand()); + } + + /** + * The diff command shows differences between revisions for a specified file + * or the entire revision. + * + * @return instance of {@link DiffCommandBuilder} + * @throws CommandNotSupportedException if the command is not supported + * by the implementation of the repository service provider. + */ + public DiffCommandBuilder getDiffCommand() + { + if (logger.isDebugEnabled()) + { + logger.debug("create diff command for repository {}", + repository.getName()); + } + + return new DiffCommandBuilder(provider.getDiffCommand()); + } + + /** + * The log command shows revision history of entire repository or files. + * + * @return instance of {@link LogCommandBuilder} + * @throws CommandNotSupportedException if the command is not supported + * by the implementation of the repository service provider. + */ + public LogCommandBuilder getLogCommand() + { + if (logger.isDebugEnabled()) + { + logger.debug("create log command for repository {}", + repository.getName()); + } + + return new LogCommandBuilder(cacheManager, provider.getLogCommand(), + repository, preProcessorUtil); + } + + /** + * Returns the repository of this service. + * + * @return repository of this service + */ + public Repository getRepository() + { + return repository; + } + + /** + * Returns true if the command is supported by the repository service. + * + * + * @param command command + * + * @return true if the command is supported + */ + public boolean isSupported(Command command) + { + return provider.getSupportedCommands().contains(command); + } + + //~--- fields --------------------------------------------------------------- + + /** cache manager */ + private CacheManager cacheManager; + + /** Field description */ + private PreProcessorUtil preProcessorUtil; + + /** implementation of the repository service provider */ + private RepositoryServiceProvider provider; + + /** the repository */ + private Repository repository; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/api/RepositoryServiceFactory.java b/scm-core/src/main/java/sonia/scm/repository/api/RepositoryServiceFactory.java new file mode 100644 index 0000000000..0b42f0820b --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/api/RepositoryServiceFactory.java @@ -0,0 +1,406 @@ +/** + * 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.repository.api; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.google.inject.Singleton; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sonia.scm.HandlerEvent; +import sonia.scm.cache.Cache; +import sonia.scm.cache.CacheManager; +import sonia.scm.repository.BlameResult; +import sonia.scm.repository.BrowserResult; +import sonia.scm.repository.ChangesetPagingResult; +import sonia.scm.repository.PermissionType; +import sonia.scm.repository.PermissionUtil; +import sonia.scm.repository.PostReceiveRepositoryHook; +import sonia.scm.repository.PreProcessorUtil; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryCacheKeyFilter; +import sonia.scm.repository.RepositoryHookEvent; +import sonia.scm.repository.RepositoryListener; +import sonia.scm.repository.RepositoryManager; +import sonia.scm.repository.RepositoryNotFoundException; +import sonia.scm.repository.spi.RepositoryServiceProvider; +import sonia.scm.repository.spi.RepositoryServiceResolver; +import sonia.scm.security.ScmSecurityException; +import sonia.scm.web.security.WebSecurityContext; + +//~--- JDK imports ------------------------------------------------------------ + +import java.util.Set; + +/** + * The {@link RepositoryServiceFactory} is the entrypoint of the repository api. + * You could create {@link RepositoryService} from a {@link Repository} and + * with the {@link RepositoryService} you could browse and control the entire + * {@link Repository}. + *

 

+ * Simple usage example: + * + *

+ * public class Sample {
+ *
+ *   private final RepositoryServiceFactory factory;
+ *
+ *   {@literal @}Inject
+ *   public Sample(RepositoryServiceFactory factory){
+ *     this.factory = factory;
+ *   }
+ *
+ *   public Changeset getChangeset(String repositoryId, String commitId){
+ *     Changeset changeset = null;
+ *     RepositoryService service = null;
+ *     try {
+ *       service = factory.create(repositoryId);
+ *       changeset = service.getLogCommand().getChangeset(commitId);
+ *     } finally {
+ *       if ( service != null ){
+ *         service.close();
+ *       }
+ *     }
+ *     return changeset;
+ *   }
+ *
+ * }
+ * 
+ * + * @author Sebastian Sdorra + * @since 1.17 + * + * @apiviz.landmark + * @apiviz.uses sonia.scm.repository.api.RepositoryService + */ +@Singleton +public final class RepositoryServiceFactory +{ + + /** + * the logger for RepositoryServiceFactory + */ + private static final Logger logger = + LoggerFactory.getLogger(RepositoryServiceFactory.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs a new {@link RepositoryServiceFactory}. This constructor + * should not be called manually, it should only be used by the injection + * container. + * + * @param cacheManager cache manager + * @param repositoryManager manager for repositories + * @param securityContextProvider provider for the current security context + * @param resolvers a set of {@link RepositoryServiceResolver} + * @param preProcessorUtil helper object for pre processor handling + */ + @Inject + public RepositoryServiceFactory( + CacheManager cacheManager, RepositoryManager repositoryManager, + Provider securityContextProvider, + Set resolvers, + PreProcessorUtil preProcessorUtil) + { + this.cacheManager = cacheManager; + this.repositoryManager = repositoryManager; + this.securityContextProvider = securityContextProvider; + this.resolvers = resolvers; + this.preProcessorUtil = preProcessorUtil; + + CacheClearHook cch = new CacheClearHook(cacheManager); + + repositoryManager.addHook(cch); + repositoryManager.addListener(cch); + } + + //~--- methods -------------------------------------------------------------- + + /** + * Creates a new RepositoryService for the given repository. + * + * + * @param repositoryId id of the repository + * + * @return a implementation of RepositoryService + * for the given type of repository + * + * @throws RepositoryNotFoundException if no repository + * with the given id is available + * @throws RepositoryServiceNotFoundException if no repository service + * implementation for this kind of repository is available + * @throws IllegalArgumentException if the repository id is null or empty + * @throws ScmSecurityException if current user has not read permissions + * for that repository + */ + public RepositoryService create(String repositoryId) + throws RepositoryNotFoundException + { + Preconditions.checkArgument(!Strings.isNullOrEmpty(repositoryId), + "a non empty repositoryId is required"); + + Repository repository = repositoryManager.get(repositoryId); + + if (repository == null) + { + throw new RepositoryNotFoundException( + "could not find a repository with id ".concat(repositoryId)); + } + + return create(repository); + } + + /** + * Creates a new RepositoryService for the given repository. + * + * + * @param type type of the repository + * @param name name of the repository + * + * @return a implementation of RepositoryService + * for the given type of repository + * + * @throws RepositoryNotFoundException if no repository + * with the given id is available + * @throws RepositoryServiceNotFoundException if no repository service + * implementation for this kind of repository is available + * @throws IllegalArgumentException if one of the parameters is null or empty + * @throws ScmSecurityException if current user has not read permissions + * for that repository + */ + public RepositoryService create(String type, String name) + throws RepositoryNotFoundException + { + Preconditions.checkArgument(!Strings.isNullOrEmpty(type), + "a non empty type is required"); + Preconditions.checkArgument(!Strings.isNullOrEmpty(name), + "a non empty name is required"); + + Repository repository = repositoryManager.get(type, name); + + if (repository == null) + { + StringBuilder msg = + new StringBuilder("could not find a repository with type "); + + msg.append(type).append(" and name ").append(name); + + throw new RepositoryNotFoundException(msg.toString()); + } + + return create(repository); + } + + /** + * Creates a new RepositoryService for the given repository. + * + * + * @param repository the repository + * + * @return a implementation of RepositoryService + * for the given type of repository + * + * @throws RepositoryServiceNotFoundException if no repository service + * implementation for this kind of repository is available + * @throws NullPointerException if the repository is null + * @throws ScmSecurityException if current user has not read permissions + * for that repository + */ + public RepositoryService create(Repository repository) + { + Preconditions.checkNotNull(repository, "repository is required"); + + // check for read permissions of current user + PermissionUtil.assertPermission(repository, securityContextProvider, + PermissionType.READ); + + RepositoryService service = null; + + for (RepositoryServiceResolver resolver : resolvers) + { + RepositoryServiceProvider provider = resolver.reslove(repository); + + if (provider != null) + { + if (logger.isDebugEnabled()) + { + logger.debug( + "create new repository service for repository {} of type {}", + repository.getName(), repository.getType()); + } + + service = new RepositoryService(cacheManager, provider, repository, + preProcessorUtil); + + break; + } + } + + if (service == null) + { + throw new RepositoryServiceNotFoundException(repository); + } + + return service; + } + + //~--- inner classes -------------------------------------------------------- + + /** + * TODO find a more elegant way + * + * + * @version Enter version here..., 12/06/16 + * @author Enter your name here... + */ + private static class CacheClearHook extends PostReceiveRepositoryHook + implements RepositoryListener + { + + /** + * Constructs ... + * + * + * @param cacheManager + */ + public CacheClearHook(CacheManager cacheManager) + { + this.blameCache = + cacheManager.getCache(BlameCommandBuilder.CacheKey.class, + BlameResult.class, + BlameCommandBuilder.CACHE_NAME); + this.browseCache = + cacheManager.getCache(BrowseCommandBuilder.CacheKey.class, + BrowserResult.class, + BrowseCommandBuilder.CACHE_NAME); + this.logCache = cacheManager.getCache(LogCommandBuilder.CacheKey.class, + ChangesetPagingResult.class, LogCommandBuilder.CACHE_NAME); + } + + //~--- methods ------------------------------------------------------------ + + /** + * Method description + * + * + * @param event + */ + @Override + public void onEvent(RepositoryHookEvent event) + { + Repository repository = event.getRepository(); + + if (repository != null) + { + String id = repository.getId(); + + clearCaches(id); + } + } + + /** + * Method description + * + * + * @param repository + * @param event + */ + @Override + public void onEvent(Repository repository, HandlerEvent event) + { + if (event == HandlerEvent.DELETE) + { + clearCaches(repository.getId()); + } + } + + /** + * Method description + * + * + * @param repositoryId + */ + @SuppressWarnings("unchecked") + private void clearCaches(final String repositoryId) + { + if (logger.isDebugEnabled()) + { + logger.debug("clear caches for repository id {}", repositoryId); + } + + RepositoryCacheKeyFilter filter = + new RepositoryCacheKeyFilter(repositoryId); + + blameCache.removeAll(filter); + browseCache.removeAll(filter); + logCache.removeAll(filter); + } + + //~--- fields ------------------------------------------------------------- + + /** Field description */ + private Cache blameCache; + + /** Field description */ + private Cache browseCache; + + /** Field description */ + private Cache logCache; + } + + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private CacheManager cacheManager; + + /** Field description */ + private PreProcessorUtil preProcessorUtil; + + /** Field description */ + private RepositoryManager repositoryManager; + + /** Field description */ + private Set resolvers; + + /** Field description */ + private Provider securityContextProvider; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/api/RepositoryServiceNotFoundException.java b/scm-core/src/main/java/sonia/scm/repository/api/RepositoryServiceNotFoundException.java new file mode 100644 index 0000000000..09d6b43a4d --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/api/RepositoryServiceNotFoundException.java @@ -0,0 +1,80 @@ +/** + * 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.repository.api; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.repository.Repository; + +/** + * This exception is throw if no {@link RepositoryService} + * is available for the given {@link Repository}. + * + * @author Sebastian Sdorra + * @since 1.17 + */ +public final class RepositoryServiceNotFoundException extends RuntimeException +{ + + /** + * Constructs a new {@link RepositoryServiceNotFoundException}. + * + * + * @param repository unsupported repository + */ + public RepositoryServiceNotFoundException(Repository repository) + { + super("could not find a repository service provider implementation for repository " + .concat(repository.getName())); + this.repository = repository; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Returns the unsupported repository. + * + * + * @return unsupported repository + */ + public Repository getRepository() + { + return repository; + } + + //~--- fields --------------------------------------------------------------- + + /** unsupported repository */ + private Repository repository; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/api/package-info.java b/scm-core/src/main/java/sonia/scm/repository/api/package-info.java new file mode 100644 index 0000000000..a1713ee6a9 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/api/package-info.java @@ -0,0 +1,37 @@ +/** + * 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 + * + */ + + + +/** + * API for repository access. + */ +package sonia.scm.repository.api; diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/BlameCommand.java b/scm-core/src/main/java/sonia/scm/repository/spi/BlameCommand.java new file mode 100644 index 0000000000..80c155a534 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/spi/BlameCommand.java @@ -0,0 +1,66 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.repository.BlameResult; +import sonia.scm.repository.RepositoryException; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + * @since 1.17 + */ +public interface BlameCommand +{ + + /** + * Method description + * + * + * @param request + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + public BlameResult getBlameResult(BlameCommandRequest request) + throws IOException, RepositoryException; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/BlameCommandRequest.java b/scm-core/src/main/java/sonia/scm/repository/spi/BlameCommandRequest.java new file mode 100644 index 0000000000..f7df5a4371 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/spi/BlameCommandRequest.java @@ -0,0 +1,68 @@ +/** + * 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.repository.spi; + +/** + * + * @author Sebastian Sdorra + * @since 1.17 + */ +public final class BlameCommandRequest extends FileBaseCommandRequest +{ + + /** + * Method description + * + * + * @return + */ + @Override + public BlameCommandRequest clone() + { + BlameCommandRequest clone = null; + + try + { + clone = (BlameCommandRequest) super.clone(); + } + catch (CloneNotSupportedException e) + { + + // this shouldn't happen, since we are Cloneable + throw new InternalError("BlameCommandRequest seems not to be cloneable"); + } + + return clone; + } +} diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/BrowseCommand.java b/scm-core/src/main/java/sonia/scm/repository/spi/BrowseCommand.java new file mode 100644 index 0000000000..4afc02b125 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/spi/BrowseCommand.java @@ -0,0 +1,66 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.repository.BrowserResult; +import sonia.scm.repository.RepositoryException; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + * @since 1.17 + */ +public interface BrowseCommand +{ + + /** + * Method description + * + * + * @param request + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + public BrowserResult getBrowserResult(BrowseCommandRequest request) + throws IOException, RepositoryException; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/BrowseCommandRequest.java b/scm-core/src/main/java/sonia/scm/repository/spi/BrowseCommandRequest.java new file mode 100644 index 0000000000..52fbf96a0d --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/spi/BrowseCommandRequest.java @@ -0,0 +1,46 @@ +/** + * 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.repository.spi; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.Serializable; + +/** + * + * @author Sebastian Sdorra + * @since 1.17 + */ +public final class BrowseCommandRequest extends FileBaseCommandRequest + implements Resetable, Serializable {} diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/CatCommand.java b/scm-core/src/main/java/sonia/scm/repository/spi/CatCommand.java new file mode 100644 index 0000000000..b9a6f52ab0 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/spi/CatCommand.java @@ -0,0 +1,65 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.repository.RepositoryException; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; +import java.io.OutputStream; + +/** + * + * @author Sebastian Sdorra + * @since 1.17 + */ +public interface CatCommand +{ + + /** + * Method description + * + * + * @param request + * @param output + * + * @throws IOException + * @throws RepositoryException + */ + public void getCatResult(CatCommandRequest request, OutputStream output) + throws IOException, RepositoryException; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/CatCommandRequest.java b/scm-core/src/main/java/sonia/scm/repository/spi/CatCommandRequest.java new file mode 100644 index 0000000000..1673204b1a --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/spi/CatCommandRequest.java @@ -0,0 +1,69 @@ +/** + * 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.repository.spi; + +/** + * + * @author Sebastian Sdorra + * @since 1.17 + */ +public final class CatCommandRequest extends FileBaseCommandRequest + implements Cloneable +{ + + /** + * Method description + * + * + * @return + */ + @Override + public CatCommandRequest clone() + { + CatCommandRequest clone = null; + + try + { + clone = (CatCommandRequest) super.clone(); + } + catch (CloneNotSupportedException e) + { + + // this shouldn't happen, since we are Cloneable + throw new InternalError("CatCommandRequest seems not to be cloneable"); + } + + return clone; + } +} diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/DiffCommand.java b/scm-core/src/main/java/sonia/scm/repository/spi/DiffCommand.java new file mode 100644 index 0000000000..a4d0c24444 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/spi/DiffCommand.java @@ -0,0 +1,66 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.repository.RepositoryException; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; +import java.io.OutputStream; + +/** + * + * @author Sebastian Sdorra + * @since 1.17 + */ +public interface DiffCommand +{ + + /** + * Method description + * + * + * @param request + * @param output + * + * @throws IOException + * @throws RuntimeException + * @throws RepositoryException + */ + public void getDiffResult(DiffCommandRequest request, OutputStream output) + throws IOException, RepositoryException; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/DiffCommandRequest.java b/scm-core/src/main/java/sonia/scm/repository/spi/DiffCommandRequest.java new file mode 100644 index 0000000000..daca399877 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/spi/DiffCommandRequest.java @@ -0,0 +1,90 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Strings; + +import sonia.scm.Validateable; + +/** + * + * @author Sebastian Sdorra + * @since 1.17 + */ +public final class DiffCommandRequest extends FileBaseCommandRequest + implements Cloneable, Validateable +{ + + /** + * Method description + * + * + * @return + */ + @Override + public DiffCommandRequest clone() + { + DiffCommandRequest clone = null; + + try + { + clone = (DiffCommandRequest) super.clone(); + } + catch (CloneNotSupportedException e) + { + + // this shouldn't happen, since we are Cloneable + throw new InternalError("DiffCommandRequest seems not to be cloneable"); + } + + return clone; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + public boolean isValid() + { + return !Strings.isNullOrEmpty(getPath()) + ||!Strings.isNullOrEmpty(getRevision()); + } +} diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/FileBaseCommandRequest.java b/scm-core/src/main/java/sonia/scm/repository/spi/FileBaseCommandRequest.java new file mode 100644 index 0000000000..83491a4b22 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/spi/FileBaseCommandRequest.java @@ -0,0 +1,205 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Objects; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.Serializable; + +/** + * + * @author Sebastian Sdorra + * @since 1.17 + */ +public abstract class FileBaseCommandRequest + implements Resetable, Serializable, Cloneable +{ + + /** + * Method description + * + * + * @param obj + * + * @return + */ + @Override + public boolean equals(Object obj) + { + if (obj == null) + { + return false; + } + + if (getClass() != obj.getClass()) + { + return false; + } + + final FileBaseCommandRequest other = (FileBaseCommandRequest) obj; + + return Objects.equal(path, other.path) + && Objects.equal(revision, other.revision); + } + + /** + * Method description + * + * + * @return + */ + @Override + public int hashCode() + { + return Objects.hashCode(path, revision); + } + + /** + * Method description + * + */ + @Override + public void reset() + { + path = null; + revision = null; + } + + /** + * Method description + * + * + * @return + */ + @Override + public String toString() + { + //J- + return Objects.toStringHelper(this) + .add("path", path) + .add("revision", revision) + .toString(); + //J+ + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param path + */ + public void setPath(String path) + { + this.path = path; + } + + /** + * Method description + * + * + * @param revision + */ + public void setRevision(String revision) + { + this.revision = revision; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + String getPath() + { + return path; + } + + /** + * Method description + * + * + * @return + */ + String getRevision() + { + return revision; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @return + * + * @throws CloneNotSupportedException + */ + @Override + protected FileBaseCommandRequest clone() throws CloneNotSupportedException + { + FileBaseCommandRequest clone = null; + + try + { + clone = (FileBaseCommandRequest) super.clone(); + } + catch (CloneNotSupportedException e) + { + + // this shouldn't happen, since we are Cloneable + throw new InternalError( + "FileBaseCommandRequest seems not to be cloneable"); + } + + return clone; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private String path; + + /** Field description */ + private String revision; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/LogCommand.java b/scm-core/src/main/java/sonia/scm/repository/spi/LogCommand.java new file mode 100644 index 0000000000..168c279c19 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/spi/LogCommand.java @@ -0,0 +1,81 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.repository.Changeset; +import sonia.scm.repository.ChangesetPagingResult; +import sonia.scm.repository.RepositoryException; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + * @since 1.17 + */ +public interface LogCommand +{ + + /** + * Method description + * + * + * @param id + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + public Changeset getChangeset(String id) + throws IOException, RepositoryException; + + /** + * Method description + * + * + * @param request + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + public ChangesetPagingResult getChangesets(LogCommandRequest request) + throws IOException, RepositoryException; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/LogCommandRequest.java b/scm-core/src/main/java/sonia/scm/repository/spi/LogCommandRequest.java new file mode 100644 index 0000000000..f1ec3e206c --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/spi/LogCommandRequest.java @@ -0,0 +1,270 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Objects; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.Serializable; + +/** + * + * @author Sebastian Sdorra + * @since 1.17 + */ +public final class LogCommandRequest implements Serializable, Resetable +{ + + /** + * Method description + * + * + * @param obj + * + * @return + */ + @Override + public boolean equals(Object obj) + { + if (obj == null) + { + return false; + } + + if (getClass() != obj.getClass()) + { + return false; + } + + final LogCommandRequest other = (LogCommandRequest) obj; + + return Objects.equal(startChangeset, other.startChangeset) + && Objects.equal(endChangeset, other.endChangeset) + && Objects.equal(pagingStart, other.pagingStart) + && Objects.equal(pagingLimit, other.pagingLimit) + && Objects.equal(path, other.path); + } + + /** + * Method description + * + * + * @return + */ + @Override + public int hashCode() + { + return Objects.hashCode(startChangeset, endChangeset, pagingStart, + pagingLimit, path); + } + + /** + * Method description + * + */ + @Override + public void reset() + { + startChangeset = null; + endChangeset = null; + pagingStart = 0; + pagingLimit = 20; + path = null; + } + + /** + * Method description + * + * + * @return + */ + @Override + public String toString() + { + //J- + return Objects.toStringHelper(this) + .add("startChangeset", startChangeset) + .add("endChangeset", endChangeset) + .add("pagingStart", pagingStart) + .add("pagingLimit", pagingLimit) + .add("path", path) + .toString(); + //J+ + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param endChangeset + */ + public void setEndChangeset(String endChangeset) + { + this.endChangeset = endChangeset; + } + + /** + * Method description + * + * + * @param pagingLimit + */ + public void setPagingLimit(int pagingLimit) + { + this.pagingLimit = pagingLimit; + } + + /** + * Method description + * + * + * @param pagingStart + */ + public void setPagingStart(int pagingStart) + { + this.pagingStart = pagingStart; + } + + /** + * Method description + * + * + * @param path + */ + public void setPath(String path) + { + this.path = path; + } + + /** + * Method description + * + * + * @param startChangeset + */ + public void setStartChangeset(String startChangeset) + { + this.startChangeset = startChangeset; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + String getEndChangeset() + { + return endChangeset; + } + + /** + * Method description + * + * + * @return + */ + int getPagingLimit() + { + return pagingLimit; + } + + /** + * Method description + * + * + * @return + */ + int getPagingStart() + { + return pagingStart; + } + + /** + * Method description + * + * + * @return + */ + String getPath() + { + return path; + } + + /** + * Method description + * + * + * @return + */ + String getStartChangeset() + { + return startChangeset; + } + + /** + * Method description + * + * + * @return + */ + boolean isPagingUnlimited() + { + return pagingLimit < 0; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private String endChangeset; + + /** Field description */ + private int pagingLimit = 20; + + /** Field description */ + private int pagingStart = 0; + + /** Field description */ + private String path; + + /** Field description */ + private String startChangeset; +} diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java b/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java new file mode 100644 index 0000000000..8fbc820d04 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java @@ -0,0 +1,137 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.repository.api.Command; +import sonia.scm.repository.api.CommandNotSupportedException; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.Closeable; +import java.io.IOException; + +import java.util.Set; + +/** + * + * @author Sebastian Sdorra + * @since 1.17 + */ +public abstract class RepositoryServiceProvider implements Closeable +{ + + /** + * Method description + * + * + * @return + */ + public abstract Set getSupportedCommands(); + + //~--- methods -------------------------------------------------------------- + + /** + * The default implementation of this method does nothing. If you need to + * free resources, close connections or release locks than you have to + * override this method. + * + * + * @throws IOException + */ + @Override + public void close() throws IOException + { + + // should be implmentented from a service provider + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + public BlameCommand getBlameCommand() + { + throw new CommandNotSupportedException(Command.BLAME); + } + + /** + * Method description + * + * + * @return + */ + public BrowseCommand getBrowseCommand() + { + throw new CommandNotSupportedException(Command.BROWSE); + } + + /** + * Method description + * + * + * @return + */ + public CatCommand getCatCommand() + { + throw new CommandNotSupportedException(Command.CAT); + } + + /** + * Method description + * + * + * @return + */ + public DiffCommand getDiffCommand() + { + throw new CommandNotSupportedException(Command.DIFF); + } + + /** + * Method description + * + * + * @return + */ + public LogCommand getLogCommand() + { + throw new CommandNotSupportedException(Command.LOG); + } +} diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceResolver.java b/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceResolver.java new file mode 100644 index 0000000000..f0ed4c0814 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceResolver.java @@ -0,0 +1,59 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.plugin.ExtensionPoint; +import sonia.scm.repository.Repository; + +/** + * + * @author Sebastian Sdorra + * @since 1.17 + */ +@ExtensionPoint +public interface RepositoryServiceResolver +{ + + /** + * Method description + * + * + * @param repository + * + * @return + */ + public RepositoryServiceProvider reslove(Repository repository); +} diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/Resetable.java b/scm-core/src/main/java/sonia/scm/repository/spi/Resetable.java new file mode 100644 index 0000000000..e438955c54 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/spi/Resetable.java @@ -0,0 +1,49 @@ +/** + * 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.repository.spi; + +/** + * + * @author Sebastian Sdorra + * @since 1.17 + */ +public interface Resetable +{ + + /** + * Method description + * + */ + public void reset(); +} diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/package-info.java b/scm-core/src/main/java/sonia/scm/repository/spi/package-info.java new file mode 100644 index 0000000000..b6a0c7f646 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/spi/package-info.java @@ -0,0 +1,37 @@ +/** + * 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 + * + */ + + + +/** + * SPI for repository access. This package is only for service provider. + */ +package sonia.scm.repository.spi; diff --git a/scm-core/src/main/java/sonia/scm/resources/ResourceNameComparator.java b/scm-core/src/main/java/sonia/scm/resources/ResourceNameComparator.java index 720c374c3e..bd3cbb4960 100644 --- a/scm-core/src/main/java/sonia/scm/resources/ResourceNameComparator.java +++ b/scm-core/src/main/java/sonia/scm/resources/ResourceNameComparator.java @@ -1,34 +1,35 @@ /** - * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * 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 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. + * 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.resources; //~--- non-JDK imports -------------------------------------------------------- diff --git a/scm-core/src/main/java/sonia/scm/store/AbstractListenableStore.java b/scm-core/src/main/java/sonia/scm/store/AbstractListenableStore.java index c31ec49e08..b7263b2f17 100644 --- a/scm-core/src/main/java/sonia/scm/store/AbstractListenableStore.java +++ b/scm-core/src/main/java/sonia/scm/store/AbstractListenableStore.java @@ -1,34 +1,35 @@ /** - * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * 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 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. + * 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.store; //~--- non-JDK imports -------------------------------------------------------- diff --git a/scm-core/src/main/java/sonia/scm/store/ListenableStore.java b/scm-core/src/main/java/sonia/scm/store/ListenableStore.java index 36c9364e76..026f3dc644 100644 --- a/scm-core/src/main/java/sonia/scm/store/ListenableStore.java +++ b/scm-core/src/main/java/sonia/scm/store/ListenableStore.java @@ -1,34 +1,35 @@ /** - * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * 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 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. + * 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.store; //~--- non-JDK imports -------------------------------------------------------- diff --git a/scm-core/src/main/java/sonia/scm/store/ListenableStoreFactory.java b/scm-core/src/main/java/sonia/scm/store/ListenableStoreFactory.java index 0fee1b62ae..abc67352b3 100644 --- a/scm-core/src/main/java/sonia/scm/store/ListenableStoreFactory.java +++ b/scm-core/src/main/java/sonia/scm/store/ListenableStoreFactory.java @@ -1,34 +1,35 @@ /** - * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * 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 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. + * 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.store; /** diff --git a/scm-core/src/main/java/sonia/scm/util/Util.java b/scm-core/src/main/java/sonia/scm/util/Util.java index e8e9cadc3b..bfa109f4ec 100644 --- a/scm-core/src/main/java/sonia/scm/util/Util.java +++ b/scm-core/src/main/java/sonia/scm/util/Util.java @@ -47,6 +47,7 @@ import java.util.Comparator; import java.util.Date; import java.util.Iterator; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.TimeZone; @@ -398,6 +399,23 @@ public class Util return parseDate(dateString, null); } + /** + * Method description + * + * + * @param value + * @param start + * + * @return + * + * @since 1.17 + */ + public static boolean startWithIgnoreCase(String value, String start) + { + return (value != null) && (start != null) + && value.toUpperCase(Locale.ENGLISH).startsWith(start); + } + /** * Method description * diff --git a/scm-core/src/main/java/sonia/scm/web/cgi/CGIStatusCodeHandler.java b/scm-core/src/main/java/sonia/scm/web/cgi/CGIStatusCodeHandler.java index 5efb6fe1e1..d0f8418517 100644 --- a/scm-core/src/main/java/sonia/scm/web/cgi/CGIStatusCodeHandler.java +++ b/scm-core/src/main/java/sonia/scm/web/cgi/CGIStatusCodeHandler.java @@ -1,34 +1,35 @@ /** - * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * 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 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. + * 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.web.cgi; //~--- JDK imports ------------------------------------------------------------ diff --git a/scm-core/src/main/java/sonia/scm/web/filter/BasicAuthenticationFilter.java b/scm-core/src/main/java/sonia/scm/web/filter/BasicAuthenticationFilter.java index db33f7f53c..386f27bcd3 100644 --- a/scm-core/src/main/java/sonia/scm/web/filter/BasicAuthenticationFilter.java +++ b/scm-core/src/main/java/sonia/scm/web/filter/BasicAuthenticationFilter.java @@ -120,18 +120,44 @@ public class BasicAuthenticationFilter extends HttpFilter User user = null; String authentication = request.getHeader(HEADER_AUTHORIZATION); - if (Util.isNotEmpty(authentication) - && authentication.toUpperCase().startsWith(AUTHORIZATION_BASIC_PREFIX)) + if (Util.startWithIgnoreCase(authentication, AUTHORIZATION_BASIC_PREFIX)) { + if (logger.isTraceEnabled()) + { + logger.trace("found basic authorization header, start authentication"); + } + user = authenticate(request, response, securityContext, authentication); + + if (logger.isTraceEnabled()) + { + if (user != null) + { + logger.trace("user {} successfully authenticated", user.getName()); + } + else + { + logger.trace("authentcation failed, user object is null"); + } + } } else if (securityContext.isAuthenticated()) { + if (logger.isTraceEnabled()) + { + logger.trace("user is allready authenticated"); + } + user = securityContext.getUser(); } if (user == null) { + if (logger.isTraceEnabled()) + { + logger.trace("could not find user send unauthorized"); + } + HttpUtil.sendUnauthorized(response); } else @@ -192,6 +218,11 @@ public class BasicAuthenticationFilter extends HttpFilter if (Util.isNotEmpty(username) && Util.isNotEmpty(password)) { + if (logger.isTraceEnabled()) + { + logger.trace("try to authenticate user {}", username); + } + user = securityContext.authenticate(request, response, username, password); } diff --git a/scm-core/src/main/java/sonia/scm/web/filter/LoggingFilter.java b/scm-core/src/main/java/sonia/scm/web/filter/LoggingFilter.java index 6b3e62695e..42a228af9b 100644 --- a/scm-core/src/main/java/sonia/scm/web/filter/LoggingFilter.java +++ b/scm-core/src/main/java/sonia/scm/web/filter/LoggingFilter.java @@ -35,6 +35,8 @@ package sonia.scm.web.filter; //~--- non-JDK imports -------------------------------------------------------- +import com.google.common.base.Strings; +import com.google.common.io.Closeables; import com.google.inject.Singleton; import org.slf4j.Logger; @@ -89,7 +91,7 @@ public class LoggingFilter extends HttpFilter { if (logger.isDebugEnabled()) { - boolean logBody = logger.isTraceEnabled(); + boolean logBody = logger.isTraceEnabled() && isTextRequest(request); BufferedHttpServletRequest bufferedRequest = new BufferedHttpServletRequest(request, logBody); BufferedHttpServletResponse bufferedResponse = @@ -189,7 +191,12 @@ public class LoggingFilter extends HttpFilter if (logger.isTraceEnabled()) { - logger.trace("Content: ".concat(new String(request.getContentBuffer()))); + byte[] contentBuffer = request.getContentBuffer(); + + if ((contentBuffer != null) && (contentBuffer.length > 0)) + { + logger.trace("Content: ".concat(new String(contentBuffer))); + } } } @@ -227,22 +234,68 @@ public class LoggingFilter extends HttpFilter logger.debug("Header: {} = {}", header.getKey(), header.getValue()); } - if (logger.isTraceEnabled()) + if (logger.isTraceEnabled() && isTextRequest(orgResponse)) { byte[] content = response.getContentBuffer(); - ServletOutputStream out = null; - try + if ((content != null) && (content.length > 0)) { - out = orgResponse.getOutputStream(); - out.write(content); - } - finally - { - out.close(); - } + ServletOutputStream out = null; - logger.trace("Content: ".concat(new String(content))); + try + { + out = orgResponse.getOutputStream(); + out.write(content); + } + finally + { + Closeables.closeQuietly(out); + } + + logger.trace("Content: ".concat(new String(content))); + } } } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param request + * + * @return + */ + private boolean isTextRequest(HttpServletRequest request) + { + return isTextRequest(request.getContentType()); + } + + /** + * Method description + * + * + * @param response + * + * @return + */ + private boolean isTextRequest(HttpServletResponse response) + { + return isTextRequest(response.getContentType()); + } + + /** + * Method description + * + * + * @param contentType + * + * @return + */ + private boolean isTextRequest(String contentType) + { + return !Strings.isNullOrEmpty(contentType) + && contentType.toLowerCase().startsWith("text"); + } } diff --git a/scm-core/src/main/java/sonia/scm/web/filter/PermissionFilter.java b/scm-core/src/main/java/sonia/scm/web/filter/PermissionFilter.java index 1e031cead4..fd03813a46 100644 --- a/scm-core/src/main/java/sonia/scm/web/filter/PermissionFilter.java +++ b/scm-core/src/main/java/sonia/scm/web/filter/PermissionFilter.java @@ -151,6 +151,15 @@ public abstract class PermissionFilter extends HttpFilter if (hasPermission(repository, securityContext, writeRequest)) { + if (logger.isTraceEnabled()) + { + logger.trace("{} access to repository {} for user {} granted", + new Object[] { writeRequest + ? "write" + : "read", repository.getName(), + user.getName() }); + } + chain.doFilter(request, response); } else diff --git a/scm-core/src/test/java/sonia/scm/repository/RepositoryTest.java b/scm-core/src/test/java/sonia/scm/repository/RepositoryTest.java new file mode 100644 index 0000000000..98e714b67f --- /dev/null +++ b/scm-core/src/test/java/sonia/scm/repository/RepositoryTest.java @@ -0,0 +1,62 @@ +/** + * 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.repository; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * + * @author Sebastian Sdorra + */ +public class RepositoryTest +{ + + /** + * Method description + * + */ + @Test + public void testCreateUrl() + { + Repository repository = new Repository("123", "hg", "test/repo"); + + assertEquals("http://localhost:8080/scm/hg/test/repo", + repository.createUrl("http://localhost:8080/scm")); + assertEquals("http://localhost:8080/scm/hg/test/repo", + repository.createUrl("http://localhost:8080/scm/")); + } +} diff --git a/scm-core/src/test/java/sonia/scm/util/IOUtilTest.java b/scm-core/src/test/java/sonia/scm/util/IOUtilTest.java index 675fb68b23..d35aab1506 100644 --- a/scm-core/src/test/java/sonia/scm/util/IOUtilTest.java +++ b/scm-core/src/test/java/sonia/scm/util/IOUtilTest.java @@ -1,34 +1,35 @@ /** - * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * 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 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. + * 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.util; //~--- non-JDK imports -------------------------------------------------------- diff --git a/scm-dao-orientdb/pom.xml b/scm-dao-orientdb/pom.xml index 8b51c104eb..16ebe46cf2 100644 --- a/scm-dao-orientdb/pom.xml +++ b/scm-dao-orientdb/pom.xml @@ -6,12 +6,12 @@ sonia.scm scm - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm scm-dao-orientdb - 1.17-SNAPSHOT + 1.18-SNAPSHOT scm-dao-orientdb @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.17-SNAPSHOT + 1.18-SNAPSHOT @@ -52,7 +52,7 @@ sonia.scm scm-test - 1.17-SNAPSHOT + 1.18-SNAPSHOT test diff --git a/scm-dao-xml/pom.xml b/scm-dao-xml/pom.xml index c6d49f47d2..d23f2cfe24 100644 --- a/scm-dao-xml/pom.xml +++ b/scm-dao-xml/pom.xml @@ -6,12 +6,12 @@ sonia.scm scm - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm scm-dao-xml - 1.17-SNAPSHOT + 1.18-SNAPSHOT scm-dao-xml @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.17-SNAPSHOT + 1.18-SNAPSHOT @@ -34,7 +34,7 @@ sonia.scm scm-test - 1.17-SNAPSHOT + 1.18-SNAPSHOT test diff --git a/scm-plugin-backend/pom.xml b/scm-plugin-backend/pom.xml index 0db75ef201..4966149d4a 100644 --- a/scm-plugin-backend/pom.xml +++ b/scm-plugin-backend/pom.xml @@ -6,13 +6,13 @@ scm sonia.scm - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm scm-plugin-backend war - 1.17-SNAPSHOT + 1.18-SNAPSHOT ${project.artifactId} @@ -42,7 +42,7 @@ sonia.scm scm-core - 1.17-SNAPSHOT + 1.18-SNAPSHOT diff --git a/scm-plugins/pom.xml b/scm-plugins/pom.xml index f1917c6cf6..ed7a59bff7 100644 --- a/scm-plugins/pom.xml +++ b/scm-plugins/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm.plugins scm-plugins pom - 1.17-SNAPSHOT + 1.18-SNAPSHOT scm-plugins @@ -26,7 +26,7 @@ sonia.scm scm-core - 1.17-SNAPSHOT + 1.18-SNAPSHOT @@ -59,7 +59,7 @@ sonia.scm.maven scm-maven-plugin - 1.17-SNAPSHOT + 1.18-SNAPSHOT process-resources diff --git a/scm-plugins/scm-git-plugin/pom.xml b/scm-plugins/scm-git-plugin/pom.xml index 41cdd07593..81bc875c00 100644 --- a/scm-plugins/scm-git-plugin/pom.xml +++ b/scm-plugins/scm-git-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm.plugins scm-git-plugin - 1.17-SNAPSHOT + 1.18-SNAPSHOT scm-git-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Git @@ -55,7 +55,7 @@ sonia.scm scm-test - 1.17-SNAPSHOT + 1.18-SNAPSHOT test diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitBlameViewer.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitBlameViewer.java index c6cf493433..6e575db31f 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitBlameViewer.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitBlameViewer.java @@ -37,6 +37,7 @@ package sonia.scm.repository; import org.eclipse.jgit.api.BlameCommand; import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.blame.BlameResult; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.PersonIdent; @@ -123,20 +124,19 @@ public class GitBlameViewer implements BlameViewer List blameLines = new ArrayList(); int total = gitBlameResult.getResultContents().size(); int i = 0; - + for (; i < total; i++) { - RevCommit commit = gitBlameResult.getSourceCommit(i); - - if ( commit != null ) - { + RevCommit commit = gitBlameResult.getSourceCommit(i); + + if (commit != null) + { PersonIdent author = gitBlameResult.getSourceAuthor(i); BlameLine blameLine = new BlameLine(); blameLine.setLineNumber(i + 1); blameLine.setAuthor(new Person(author.getName(), author.getEmailAddress())); - blameLine.setDescription(commit.getShortMessage()); long when = GitUtil.getCommitTime(commit); @@ -151,7 +151,7 @@ public class GitBlameViewer implements BlameViewer blameLine.setCode(content); blameLines.add(blameLine); - } + } } blameResult = new sonia.scm.repository.BlameResult(i, blameLines); @@ -160,6 +160,10 @@ public class GitBlameViewer implements BlameViewer { logger.error("could not open repository", ex); } + catch (GitAPIException ex) + { + logger.error("could not create blame view", ex); + } return blameResult; } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitChangesetConverter.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitChangesetConverter.java index 549b6103a3..c638f992d8 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitChangesetConverter.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitChangesetConverter.java @@ -237,9 +237,9 @@ public class GitChangesetConverter implements Closeable } else { - if (logger.isWarnEnabled()) + if (logger.isTraceEnabled()) { - logger.warn("no parent at position 0 for commit {}", commit); + logger.trace("no parent at position 0 for commit {}", commit); } treeWalk.addTree(new EmptyTreeIterator()); @@ -247,9 +247,9 @@ public class GitChangesetConverter implements Closeable } else { - if (logger.isWarnEnabled()) + if (logger.isTraceEnabled()) { - logger.warn("no parent available for commit {}", commit); + logger.trace("no parent available for commit {}", commit); } treeWalk.addTree(new EmptyTreeIterator()); diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitChangesetViewer.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitChangesetViewer.java index 30ef4111c6..4fdb4713bd 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitChangesetViewer.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitChangesetViewer.java @@ -36,6 +36,7 @@ package sonia.scm.repository; //~--- non-JDK imports -------------------------------------------------------- import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.NoHeadException; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.revwalk.RevCommit; @@ -198,6 +199,10 @@ public class GitChangesetViewer implements ChangesetViewer { logger.error("could not read changesets", ex); } + catch (GitAPIException ex) + { + logger.error("could not read changesets", ex); + } catch (IOException ex) { logger.error("could not open repository", ex); @@ -279,6 +284,10 @@ public class GitChangesetViewer implements ChangesetViewer { logger.error("could not read changesets", ex); } + catch (GitAPIException ex) + { + logger.error("could not read changesets", ex); + } catch (IOException ex) { logger.error("could not open repository", ex); diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index bbfc5728ed..07ab9709b8 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -155,6 +155,36 @@ public class GitUtil //~--- get methods ---------------------------------------------------------- + /** + * Method description + * + * + * @param repo + * @param branchName + * + * @return + * + * @throws IOException + */ + public static ObjectId getBranchId(org.eclipse.jgit.lib.Repository repo, + String branchName) + throws IOException + { + ObjectId branchId = null; + Ref ref = repo.getRef(branchName); + + if (ref != null) + { + branchId = ref.getObjectId(); + } + else if (logger.isWarnEnabled()) + { + logger.warn("could not find branch for {}", branchName); + } + + return branchId; + } + /** * Method description * @@ -209,9 +239,9 @@ public class GitUtil } } - if (logger.isInfoEnabled()) + if (logger.isDebugEnabled()) { - logger.info("use {}:{} as repository head", head, id); + logger.debug("use {}:{} as repository head", head, id); } return id; diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java new file mode 100644 index 0000000000..dc26777f65 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java @@ -0,0 +1,88 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.eclipse.jgit.lib.Repository; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + */ +public class AbstractGitCommand +{ + + /** + * Constructs ... + * + * + * + * @param context + * @param repository + * @param repositoryDirectory + */ + protected AbstractGitCommand(GitContext context, + sonia.scm.repository.Repository repository) + { + this.repository = repository; + this.context = context; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @return + * + * @throws IOException + */ + protected Repository open() throws IOException + { + return context.open(); + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + protected GitContext context; + + /** Field description */ + protected sonia.scm.repository.Repository repository; +} diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBlameCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBlameCommand.java new file mode 100644 index 0000000000..a48b4b2b1e --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBlameCommand.java @@ -0,0 +1,182 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; + +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.PersonIdent; +import org.eclipse.jgit.revwalk.RevCommit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sonia.scm.repository.BlameLine; +import sonia.scm.repository.BlameResult; +import sonia.scm.repository.GitUtil; +import sonia.scm.repository.Person; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryException; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author Sebastian Sdorra + */ +public class GitBlameCommand extends AbstractGitCommand implements BlameCommand +{ + + /** + * the logger for GitBlameCommand + */ + private static final Logger logger = + LoggerFactory.getLogger(GitBlameCommand.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * + * @param context + * @param repository + * @param repositoryDirectory + */ + public GitBlameCommand(GitContext context, Repository repository) + { + super(context, repository); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param request + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public BlameResult getBlameResult(BlameCommandRequest request) + throws IOException, RepositoryException + { + if (logger.isDebugEnabled()) + { + logger.debug("try to create blame for {}", request); + } + + Preconditions.checkArgument(!Strings.isNullOrEmpty(request.getPath()), + "path is empty or null"); + + BlameResult result = null; + + try + { + org.eclipse.jgit.lib.Repository gr = open(); + org.eclipse.jgit.api.BlameCommand blame = new Git(gr).blame(); + + blame.setFilePath(request.getPath()); + + ObjectId revId = GitUtil.getRevisionId(gr, request.getRevision()); + + blame.setStartCommit(revId); + + org.eclipse.jgit.blame.BlameResult gitBlameResult = blame.call(); + + if (gitBlameResult == null) + { + throw new RepositoryException( + "could not create blame result for path ".concat( + request.getPath())); + } + + List blameLines = new ArrayList(); + int total = gitBlameResult.getResultContents().size(); + int i = 0; + + for (; i < total; i++) + { + RevCommit commit = gitBlameResult.getSourceCommit(i); + + if (commit != null) + { + PersonIdent author = gitBlameResult.getSourceAuthor(i); + BlameLine blameLine = new BlameLine(); + + blameLine.setLineNumber(i + 1); + blameLine.setAuthor(new Person(author.getName(), + author.getEmailAddress())); + blameLine.setDescription(commit.getShortMessage()); + + long when = GitUtil.getCommitTime(commit); + + blameLine.setWhen(when); + + String rev = commit.getId().getName(); + + blameLine.setRevision(rev); + + String content = gitBlameResult.getResultContents().getString(i); + + blameLine.setCode(content); + blameLines.add(blameLine); + } + } + + result = new BlameResult(i, blameLines); + } + catch (GitAPIException ex) + { + throw new RepositoryException("could not create blame view", ex); + } + + return result; + } +} diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBrowseCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBrowseCommand.java new file mode 100644 index 0000000000..3dc4eacd80 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBrowseCommand.java @@ -0,0 +1,469 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.eclipse.jgit.errors.MissingObjectException; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectLoader; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevTree; +import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.treewalk.TreeWalk; +import org.eclipse.jgit.treewalk.filter.AndTreeFilter; +import org.eclipse.jgit.treewalk.filter.PathFilter; +import org.eclipse.jgit.treewalk.filter.TreeFilter; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sonia.scm.repository.BrowserResult; +import sonia.scm.repository.FileObject; +import sonia.scm.repository.GitSubModuleParser; +import sonia.scm.repository.GitUtil; +import sonia.scm.repository.PathNotFoundException; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryException; +import sonia.scm.repository.SubRepository; +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +/** + * + * @author Sebastian Sdorra + */ +public class GitBrowseCommand extends AbstractGitCommand + implements BrowseCommand +{ + + /** Field description */ + public static final String PATH_MODULES = ".gitmodules"; + + /** + * the logger for GitBrowseCommand + */ + private static final Logger logger = + LoggerFactory.getLogger(GitBrowseCommand.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * + * @param context + * @param repository + * @param repositoryDirectory + */ + public GitBrowseCommand(GitContext context, Repository repository) + { + super(context, repository); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param request + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public BrowserResult getBrowserResult(BrowseCommandRequest request) + throws IOException, RepositoryException + { + if (logger.isDebugEnabled()) + { + logger.debug("try to create browse result for {}", request); + } + + BrowserResult result = null; + org.eclipse.jgit.lib.Repository repo = open(); + ObjectId revId = null; + + if (Util.isEmpty(request.getRevision())) + { + revId = GitUtil.getRepositoryHead(repo); + } + else + { + revId = GitUtil.getRevisionId(repo, request.getRevision()); + } + + if (revId != null) + { + result = getResult(repo, revId, request.getPath()); + } + else + { + if (Util.isNotEmpty(request.getRevision())) + { + logger.error("could not find revision {}", request.getRevision()); + } + else if (logger.isWarnEnabled()) + { + logger.warn("coul not find head of repository, empty?"); + } + + result = new BrowserResult(Constants.HEAD, null, null, + new ArrayList()); + } + + return result; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param files + * @param repo + * @param revId + * @param path + * + * @throws IOException + * @throws RepositoryException + */ + private void appendSubModules(List files, + org.eclipse.jgit.lib.Repository repo, + ObjectId revId, String path) + throws IOException, RepositoryException + { + path = Util.nonNull(path); + + Map subRepositories = getSubRepositories(repo, + revId); + + if (subRepositories != null) + { + for (Entry e : subRepositories.entrySet()) + { + String p = e.getKey(); + + if (p.startsWith(path)) + { + p = p.substring(path.length()); + + if (p.startsWith("/")) + { + p = p.substring(1); + } + + if (p.endsWith("/")) + { + p = p.substring(0, p.length() - 1); + } + + if (!p.contains("/")) + { + FileObject fo = new FileObject(); + + fo.setDirectory(true); + fo.setPath(path); + fo.setName(p); + fo.setSubRepository(e.getValue()); + files.add(fo); + } + } + } + } + } + + /** + * Method description + * + * + * + * + * @param repo + * @param revId + * @param treeWalk + * + * @return + * + * @throws IOException + */ + private FileObject createFileObject(org.eclipse.jgit.lib.Repository repo, + ObjectId revId, TreeWalk treeWalk) + throws IOException + { + FileObject file = null; + + try + { + file = new FileObject(); + + String path = treeWalk.getPathString(); + + file.setName(treeWalk.getNameString()); + file.setPath(path); + + ObjectLoader loader = repo.open(treeWalk.getObjectId(0)); + + file.setDirectory(loader.getType() == Constants.OBJ_TREE); + file.setLength(loader.getSize()); + + // don't show message and date for directories to improve performance + if (!file.isDirectory()) + { + RevCommit commit = getLatestCommit(repo, revId, path); + + if (commit != null) + { + file.setLastModified(GitUtil.getCommitTime(commit)); + file.setDescription(commit.getShortMessage()); + } + else if (logger.isWarnEnabled()) + { + logger.warn("could not find latest commit for {} on {}", path, revId); + } + } + } + catch (MissingObjectException ex) + { + file = null; + logger.error("could not fetch object for id {}", revId); + + if (logger.isTraceEnabled()) + { + logger.trace("could not fetch object", ex); + } + } + + return file; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * + * @param repo + * @param revId + * @param path + * + * @return + */ + private RevCommit getLatestCommit(org.eclipse.jgit.lib.Repository repo, + ObjectId revId, String path) + { + RevCommit result = null; + RevWalk walk = null; + + try + { + walk = new RevWalk(repo); + walk.setTreeFilter(AndTreeFilter.create(PathFilter.create(path), + TreeFilter.ANY_DIFF)); + + RevCommit commit = walk.parseCommit(revId); + + walk.markStart(commit); + result = Util.getFirst(walk); + } + catch (Exception ex) + { + logger.error("could not parse commit for file", ex); + } + finally + { + GitUtil.release(walk); + } + + return result; + } + + /** + * Method description + * + * + * @param repo + * @param revId + * @param path + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + private BrowserResult getResult(org.eclipse.jgit.lib.Repository repo, + ObjectId revId, String path) + throws IOException, RepositoryException + { + BrowserResult result = null; + RevWalk revWalk = null; + TreeWalk treeWalk = null; + + try + { + if (logger.isDebugEnabled()) + { + logger.debug("load repository browser for revision {}", revId.name()); + } + + treeWalk = new TreeWalk(repo); + revWalk = new RevWalk(repo); + + RevTree tree = revWalk.parseTree(revId); + + if (tree != null) + { + treeWalk.addTree(tree); + } + else + { + logger.error("could not find tree for {}", revId.name()); + } + + result = new BrowserResult(); + + List files = new ArrayList(); + + appendSubModules(files, repo, revId, path); + + if (Util.isEmpty(path)) + { + while (treeWalk.next()) + { + FileObject fo = createFileObject(repo, revId, treeWalk); + + if (fo != null) + { + files.add(fo); + } + } + } + else + { + String[] parts = path.split("/"); + int current = 0; + int limit = parts.length; + + while (treeWalk.next()) + { + String name = treeWalk.getNameString(); + + if (current >= limit) + { + String p = treeWalk.getPathString(); + + if (p.split("/").length > limit) + { + FileObject fo = createFileObject(repo, revId, treeWalk); + + if (fo != null) + { + files.add(fo); + } + } + } + else if (name.equalsIgnoreCase(parts[current])) + { + current++; + treeWalk.enterSubtree(); + } + } + } + + result.setFiles(files); + result.setRevision(revId.getName()); + } + finally + { + GitUtil.release(revWalk); + GitUtil.release(treeWalk); + } + + return result; + } + + /** + * Method description + * + * + * @param repo + * @param revision + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + private Map getSubRepositories( + org.eclipse.jgit.lib.Repository repo, ObjectId revision) + throws IOException, RepositoryException + { + if (logger.isDebugEnabled()) + { + logger.debug("read submodules of {} at {}", repository.getName(), + revision); + } + + Map subRepositories = null; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + try + { + new GitCatCommand(context, repository).getContent(repo, revision, + PATH_MODULES, baos); + subRepositories = GitSubModuleParser.parse(baos.toString()); + } + catch (PathNotFoundException ex) + { + logger.trace("could not find .gitmodules", ex); + } + + return subRepositories; + } +} diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitCatCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitCatCommand.java new file mode 100644 index 0000000000..17dad775b1 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitCatCommand.java @@ -0,0 +1,195 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectLoader; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevTree; +import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.treewalk.TreeWalk; +import org.eclipse.jgit.treewalk.filter.PathFilter; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sonia.scm.repository.GitUtil; +import sonia.scm.repository.PathNotFoundException; +import sonia.scm.repository.RepositoryException; +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; +import java.io.OutputStream; + +/** + * + * @author Sebastian Sdorra + */ +public class GitCatCommand extends AbstractGitCommand implements CatCommand +{ + + /** + * the logger for GitCatCommand + */ + private static final Logger logger = + LoggerFactory.getLogger(GitCatCommand.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * + * @param context + * @param repository + * @param repositoryDirectory + */ + public GitCatCommand(GitContext context, + sonia.scm.repository.Repository repository) + { + super(context, repository); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param request + * @param output + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public void getCatResult(CatCommandRequest request, OutputStream output) + throws IOException, RepositoryException + { + if (logger.isDebugEnabled()) + { + logger.debug("try to read content for {}", request); + } + + org.eclipse.jgit.lib.Repository repo = null; + + repo = open(); + + ObjectId revId = GitUtil.getRevisionId(repo, request.getRevision()); + + getContent(repo, revId, request.getPath(), output); + } + + /** + * Method description + * + * + * + * @param repo + * @param revId + * @param path + * @param output + * + * + * @throws IOException + * @throws RepositoryException + */ + void getContent(org.eclipse.jgit.lib.Repository repo, ObjectId revId, + String path, OutputStream output) + throws IOException, RepositoryException + { + TreeWalk treeWalk = null; + RevWalk revWalk = null; + + try + { + treeWalk = new TreeWalk(repo); + treeWalk.setRecursive(Util.nonNull(path).contains("/")); + + if (logger.isDebugEnabled()) + { + logger.debug("load content for {} at {}", path, revId.name()); + } + + revWalk = new RevWalk(repo); + + RevCommit entry = revWalk.parseCommit(revId); + RevTree revTree = entry.getTree(); + + if (revTree != null) + { + treeWalk.addTree(revTree); + } + else + { + logger.error("could not find tree for {}", revId.name()); + } + + treeWalk.setFilter(PathFilter.create(path)); + + if (treeWalk.next()) + { + + // Path exists + if (treeWalk.getFileMode(0).getObjectType() == Constants.OBJ_BLOB) + { + ObjectId blobId = treeWalk.getObjectId(0); + ObjectLoader loader = repo.open(blobId); + + loader.copyTo(output); + } + else + { + + // Not a blob, its something else (tree, gitlink) + throw new PathNotFoundException(path); + } + } + else + { + throw new PathNotFoundException(path); + } + } + finally + { + GitUtil.release(revWalk); + GitUtil.release(treeWalk); + } + } +} diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitContext.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitContext.java new file mode 100644 index 0000000000..b003395e5a --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitContext.java @@ -0,0 +1,122 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sonia.scm.repository.GitUtil; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.Closeable; +import java.io.File; +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + */ +public class GitContext implements Closeable +{ + + /** + * the logger for GitContext + */ + private static final Logger logger = + LoggerFactory.getLogger(GitContext.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param directory + */ + public GitContext(File directory) + { + this.directory = directory; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + */ + @Override + public void close() + { + if (logger.isTraceEnabled()) + { + logger.trace("close git repository {}", directory); + } + + GitUtil.close(repository); + repository = null; + } + + /** + * Method description + * + * + * @return + * + * @throws IOException + */ + public org.eclipse.jgit.lib.Repository open() throws IOException + { + if (repository == null) + { + if (logger.isTraceEnabled()) + { + logger.trace("open git repository {}", directory); + } + + repository = GitUtil.open(directory); + } + + return repository; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private File directory; + + /** Field description */ + private org.eclipse.jgit.lib.Repository repository; +} diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitDiffCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitDiffCommand.java new file mode 100644 index 0000000000..a8edfa8848 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitDiffCommand.java @@ -0,0 +1,171 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.eclipse.jgit.diff.DiffEntry; +import org.eclipse.jgit.diff.DiffFormatter; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevTree; +import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.treewalk.EmptyTreeIterator; +import org.eclipse.jgit.treewalk.TreeWalk; +import org.eclipse.jgit.treewalk.filter.PathFilter; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sonia.scm.repository.GitUtil; +import sonia.scm.repository.Repository; +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.BufferedOutputStream; +import java.io.OutputStream; + +import java.util.List; + +/** + * + * @author Sebastian Sdorra + */ +public class GitDiffCommand extends AbstractGitCommand implements DiffCommand +{ + + /** + * the logger for GitDiffCommand + */ + private static final Logger logger = + LoggerFactory.getLogger(GitDiffCommand.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * + * @param context + * @param repository + * @param repositoryDirectory + */ + public GitDiffCommand(GitContext context, Repository repository) + { + super(context, repository); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param request + * @param output + */ + @Override + public void getDiffResult(DiffCommandRequest request, OutputStream output) + { + RevWalk walk = null; + TreeWalk treeWalk = null; + DiffFormatter formatter = null; + + try + { + org.eclipse.jgit.lib.Repository gr = open(); + + walk = new RevWalk(gr); + + RevCommit commit = walk.parseCommit(gr.resolve(request.getRevision())); + + walk.markStart(commit); + commit = walk.next(); + treeWalk = new TreeWalk(gr); + treeWalk.reset(); + treeWalk.setRecursive(true); + + if (Util.isNotEmpty(request.getPath())) + { + treeWalk.setFilter(PathFilter.create(request.getPath())); + } + + if (commit.getParentCount() > 0) + { + RevTree tree = commit.getParent(0).getTree(); + + if (tree != null) + { + treeWalk.addTree(tree); + } + else + { + treeWalk.addTree(new EmptyTreeIterator()); + } + } + else + { + treeWalk.addTree(new EmptyTreeIterator()); + } + + treeWalk.addTree(commit.getTree()); + formatter = new DiffFormatter(new BufferedOutputStream(output)); + formatter.setRepository(gr); + + List entries = DiffEntry.scan(treeWalk); + + for (DiffEntry e : entries) + { + if (!e.getOldId().equals(e.getNewId())) + { + formatter.format(e); + } + } + + formatter.flush(); + } + catch (Exception ex) + { + + // TODO throw exception + logger.error("could not create diff", ex); + } + finally + { + GitUtil.release(walk); + GitUtil.release(treeWalk); + GitUtil.release(formatter); + } + } +} diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java new file mode 100644 index 0000000000..dbcc023bd3 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java @@ -0,0 +1,282 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Strings; +import com.google.common.collect.Lists; + +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.api.errors.NoHeadException; +import org.eclipse.jgit.errors.IncorrectObjectTypeException; +import org.eclipse.jgit.errors.MissingObjectException; +import org.eclipse.jgit.errors.StopWalkException; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.revwalk.filter.RevFilter; +import org.eclipse.jgit.treewalk.filter.AndTreeFilter; +import org.eclipse.jgit.treewalk.filter.PathFilter; +import org.eclipse.jgit.treewalk.filter.PathFilterGroup; +import org.eclipse.jgit.treewalk.filter.TreeFilter; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sonia.scm.repository.Changeset; +import sonia.scm.repository.ChangesetPagingResult; +import sonia.scm.repository.GitChangesetConverter; +import sonia.scm.repository.GitUtil; +import sonia.scm.repository.RepositoryException; +import sonia.scm.util.IOUtil; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * + * @author Sebastian Sdorra + */ +public class GitLogCommand extends AbstractGitCommand implements LogCommand +{ + + /** + * the logger for GitLogCommand + */ + private static final Logger logger = + LoggerFactory.getLogger(GitLogCommand.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * + * @param context + * @param repository + * @param repositoryDirectory + */ + GitLogCommand(GitContext context, sonia.scm.repository.Repository repository) + { + super(context, repository); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param revision + * + * @return + */ + @Override + public Changeset getChangeset(String revision) + { + if (logger.isDebugEnabled()) + { + logger.debug("fetch changeset {}", revision); + } + + Changeset changeset = null; + Repository gr = null; + GitChangesetConverter converter = null; + + try + { + gr = open(); + + if (!gr.getAllRefs().isEmpty()) + { + RevWalk revWalk = new RevWalk(gr); + ObjectId id = GitUtil.getRevisionId(gr, revision); + RevCommit commit = revWalk.parseCommit(id); + + if (commit != null) + { + converter = new GitChangesetConverter(gr, revWalk, GitUtil.ID_LENGTH); + changeset = converter.createChangeset(commit); + } + else if (logger.isWarnEnabled()) + { + logger.warn("could not find revision {}", revision); + } + } + } + catch (IOException ex) + { + logger.error("could not open repository", ex); + } + finally + { + IOUtil.close(converter); + GitUtil.close(gr); + } + + return changeset; + } + + /** + * Method description + * + * + * @param request + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public ChangesetPagingResult getChangesets(LogCommandRequest request) + throws IOException, RepositoryException + { + if (logger.isDebugEnabled()) + { + logger.debug("fetch changesets for request: {}", request); + } + + ChangesetPagingResult changesets = null; + GitChangesetConverter converter = null; + + try + { + org.eclipse.jgit.lib.Repository gr = open(); + + if (!gr.getAllRefs().isEmpty()) + { + int counter = 0; + int start = request.getPagingStart(); + + if (start < 0) + { + if (logger.isErrorEnabled()) + { + logger.error("start parameter is negative, reset to 0"); + } + + start = 0; + } + + List changesetList = Lists.newArrayList(); + int limit = request.getPagingLimit(); + ObjectId startId = null; + + if (!Strings.isNullOrEmpty(request.getStartChangeset())) + { + startId = gr.resolve(request.getStartChangeset()); + } + + ObjectId endId = null; + + if (!Strings.isNullOrEmpty(request.getEndChangeset())) + { + endId = gr.resolve(request.getEndChangeset()); + } + + RevWalk revWalk = new RevWalk(gr); + + converter = new GitChangesetConverter(gr, revWalk, GitUtil.ID_LENGTH); + + if (!Strings.isNullOrEmpty(request.getPath())) + { + revWalk.setTreeFilter( + AndTreeFilter.create( + PathFilter.create(request.getPath()), TreeFilter.ANY_DIFF)); + } + + ObjectId head = GitUtil.getRepositoryHead(gr); + + if (head != null) + { + if (startId != null) + { + revWalk.markStart(revWalk.lookupCommit(startId)); + } + else + { + revWalk.markStart(revWalk.lookupCommit(head)); + } + + Iterator iterator = revWalk.iterator(); + + while (iterator.hasNext()) + { + RevCommit commit = iterator.next(); + + if ((counter >= start) + && ((limit < 0) || (counter < start + limit))) + { + changesetList.add(converter.createChangeset(commit)); + } + + counter++; + + if ((endId != null) && commit.getId().equals(endId)) + { + break; + } + } + } + + changesets = new ChangesetPagingResult(counter, changesetList); + } + else if (logger.isWarnEnabled()) + { + logger.warn("the repository {} seems to be empty", + repository.getName()); + } + } + catch (Exception ex) + { + throw new RepositoryException("could not create change log", ex); + } + finally + { + IOUtil.close(converter); + } + + return changesets; + } +} diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceProvider.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceProvider.java new file mode 100644 index 0000000000..097d72b6b8 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceProvider.java @@ -0,0 +1,172 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.collect.ImmutableSet; + +import sonia.scm.repository.GitRepositoryHandler; +import sonia.scm.repository.Repository; +import sonia.scm.repository.api.Command; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +import java.util.Set; + +/** + * + * @author Sebastian Sdorra + */ +public class GitRepositoryServiceProvider extends RepositoryServiceProvider +{ + + /** Field description */ + private static final Set COMMANDS = ImmutableSet.of(Command.BLAME, + Command.BROWSE, Command.CAT, + Command.DIFF, Command.LOG); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param handler + * @param repository + */ + public GitRepositoryServiceProvider(GitRepositoryHandler handler, + Repository repository) + { + this.repository = repository; + context = new GitContext(handler.getDirectory(repository)); + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @throws IOException + */ + @Override + public void close() throws IOException + { + context.close(); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + public BlameCommand getBlameCommand() + { + return new GitBlameCommand(context, repository); + } + + /** + * Method description + * + * + * @return + */ + @Override + public BrowseCommand getBrowseCommand() + { + return new GitBrowseCommand(context, repository); + } + + /** + * Method description + * + * + * @return + */ + @Override + public CatCommand getCatCommand() + { + return new GitCatCommand(context, repository); + } + + /** + * Method description + * + * + * @return + */ + @Override + public DiffCommand getDiffCommand() + { + return new GitDiffCommand(context, repository); + } + + /** + * Method description + * + * + * @return + */ + @Override + public LogCommand getLogCommand() + { + return new GitLogCommand(context, repository); + } + + /** + * Method description + * + * + * @return + */ + @Override + public Set getSupportedCommands() + { + return COMMANDS; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private GitContext context; + + /** Field description */ + private Repository repository; +} diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceResolver.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceResolver.java new file mode 100644 index 0000000000..da46605cd7 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitRepositoryServiceResolver.java @@ -0,0 +1,95 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.inject.Inject; + +import sonia.scm.plugin.ext.Extension; +import sonia.scm.repository.GitRepositoryHandler; +import sonia.scm.repository.Repository; + +/** + * + * @author Sebastian Sdorra + */ +@Extension +public class GitRepositoryServiceResolver implements RepositoryServiceResolver +{ + + /** Field description */ + public static final String TYPE = "git"; + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param handler + */ + @Inject + public GitRepositoryServiceResolver(GitRepositoryHandler handler) + { + this.handler = handler; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param repository + * + * @return + */ + @Override + public GitRepositoryServiceProvider reslove(Repository repository) + { + GitRepositoryServiceProvider provider = null; + + if (TYPE.equalsIgnoreCase(repository.getType())) + { + provider = new GitRepositoryServiceProvider(handler, repository); + } + + return provider; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private GitRepositoryHandler handler; +} diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitRepositoryViewer.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitRepositoryViewer.java index 689a175ee2..857884a888 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitRepositoryViewer.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitRepositoryViewer.java @@ -38,12 +38,16 @@ package sonia.scm.web; import org.apache.commons.lang.StringEscapeUtils; import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.NoHeadException; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import sonia.scm.io.RegexResourceProcessor; import sonia.scm.io.ResourceProcessor; import sonia.scm.repository.GitUtil; @@ -75,6 +79,12 @@ public class GitRepositoryViewer /** Field description */ public static final String RESOURCE_GITINDEX = "/sonia/scm/git.index.html"; + /** + * the logger for GitRepositoryViewer + */ + private static final Logger logger = + LoggerFactory.getLogger(GitRepositoryViewer.class); + //~--- methods -------------------------------------------------------------- /** @@ -107,16 +117,23 @@ public class GitRepositoryViewer int c = 0; ObjectId head = GitUtil.getRepositoryHead(repository); - for (RevCommit commit : git.log().add(head).call()) + try { - appendCommit(sb, commit); - c++; - - if (c > logSize) + for (RevCommit commit : git.log().add(head).call()) { - break; + appendCommit(sb, commit); + c++; + + if (c > logSize) + { + break; + } } } + catch (GitAPIException ex) + { + logger.error("could not read changesets", ex); + } } processor.addVariable("commits", sb.toString()); diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/AbstractGitCommandTestBase.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/AbstractGitCommandTestBase.java new file mode 100644 index 0000000000..496b71e656 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/AbstractGitCommandTestBase.java @@ -0,0 +1,102 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.After; + +/** + * + * @author Sebastian Sdorra + */ +public class AbstractGitCommandTestBase extends ZippedRepositoryTestBase +{ + + /** + * Method description + * + */ + @After + public void close() + { + context.close(); + } + + /** + * Method description + * + * + * @return + */ + protected GitContext createContext() + { + if (context == null) + { + context = new GitContext(repositoryDirectory); + } + + return context; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + protected String getType() + { + return "git"; + } + + /** + * Method description + * + * + * @return + */ + @Override + protected String getZippedRepositoryResource() + { + return "sonia/scm/repository/spi/scm-git-spi-test.zip"; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private GitContext context; +} diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBlameCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBlameCommandTest.java new file mode 100644 index 0000000000..953372020b --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBlameCommandTest.java @@ -0,0 +1,144 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.Test; + +import sonia.scm.repository.BlameLine; +import sonia.scm.repository.BlameResult; +import sonia.scm.repository.RepositoryException; + +import static org.junit.Assert.*; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + */ +public class GitBlameCommandTest extends AbstractGitCommandTestBase +{ + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetBlameResult() throws IOException, RepositoryException + { + BlameCommandRequest request = new BlameCommandRequest(); + + request.setPath("a.txt"); + + BlameResult result = createCommand().getBlameResult(request); + + assertNotNull(result); + assertEquals(2, result.getTotal()); + + BlameLine line = result.getLine(0); + + checkFirstLine(line); + line = result.getLine(1); + assertEquals(2, line.getLineNumber()); + assertEquals("fcd0ef1831e4002ac43ea539f4094334c79ea9ec", + line.getRevision()); + checkDate(line.getWhen()); + assertEquals("line for blame", line.getCode()); + assertEquals("added new line for blame", line.getDescription()); + assertEquals("Zaphod Beeblebrox", line.getAuthor().getName()); + assertEquals("zaphod.beeblebrox@hitchhiker.com", + line.getAuthor().getMail()); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetBlameResultWithRevision() + throws IOException, RepositoryException + { + BlameCommandRequest request = new BlameCommandRequest(); + + request.setPath("a.txt"); + request.setRevision("86a6645eceefe8b9a247db5eb16e3d89a7e6e6d1"); + + BlameResult result = createCommand().getBlameResult(request); + + assertNotNull(result); + assertEquals(1, result.getTotal()); + + BlameLine line = result.getLine(0); + + checkFirstLine(line); + } + + /** + * Method description + * + * + * @param line + */ + private void checkFirstLine(BlameLine line) + { + assertEquals(1, line.getLineNumber()); + assertEquals("435df2f061add3589cb326cc64be9b9c3897ceca", + line.getRevision()); + checkDate(line.getWhen()); + assertEquals("a", line.getCode()); + assertEquals("added a and b files", line.getDescription()); + assertEquals("Douglas Adams", line.getAuthor().getName()); + assertEquals("douglas.adams@hitchhiker.com", line.getAuthor().getMail()); + } + + /** + * Method description + * + * + * @return + */ + private GitBlameCommand createCommand() + { + return new GitBlameCommand(createContext(), repository); + } +} diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBrowseCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBrowseCommandTest.java new file mode 100644 index 0000000000..d891053f22 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBrowseCommandTest.java @@ -0,0 +1,172 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.Test; + +import sonia.scm.repository.BrowserResult; +import sonia.scm.repository.FileObject; +import sonia.scm.repository.RepositoryException; + +import static org.junit.Assert.*; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +import java.util.List; + +/** + * + * @author Sebastian Sdorra + */ +public class GitBrowseCommandTest extends AbstractGitCommandTestBase +{ + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testBrowse() throws IOException, RepositoryException + { + BrowserResult result = + createCommand().getBrowserResult(new BrowseCommandRequest()); + + assertNotNull(result); + + List foList = result.getFiles(); + + assertNotNull(foList); + assertFalse(foList.isEmpty()); + assertEquals(4, foList.size()); + + FileObject a = null; + FileObject c = null; + + for (FileObject f : foList) + { + if ("a.txt".equals(f.getName())) + { + a = f; + } + else if ("c".equals(f.getName())) + { + c = f; + } + } + + assertNotNull(a); + assertFalse(a.isDirectory()); + assertEquals("a.txt", a.getName()); + assertEquals("a.txt", a.getPath()); + assertEquals("added new line for blame", a.getDescription()); + assertTrue(a.getLength() > 0); + checkDate(a.getLastModified()); + assertNotNull(c); + assertTrue(c.isDirectory()); + assertEquals("c", c.getName()); + assertEquals("c", c.getPath()); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testBrowseSubDirectory() throws IOException, RepositoryException + { + BrowseCommandRequest request = new BrowseCommandRequest(); + + request.setPath("c"); + + BrowserResult result = createCommand().getBrowserResult(request); + + assertNotNull(result); + + List foList = result.getFiles(); + + assertNotNull(foList); + assertFalse(foList.isEmpty()); + assertEquals(2, foList.size()); + + FileObject d = null; + FileObject e = null; + + for (FileObject f : foList) + { + if ("d.txt".equals(f.getName())) + { + d = f; + } + else if ("e.txt".equals(f.getName())) + { + e = f; + } + } + + assertNotNull(d); + assertFalse(d.isDirectory()); + assertEquals("d.txt", d.getName()); + assertEquals("c/d.txt", d.getPath()); + assertEquals("added file d and e in folder c", d.getDescription()); + assertTrue(d.getLength() > 0); + checkDate(d.getLastModified()); + assertNotNull(e); + assertFalse(e.isDirectory()); + assertEquals("e.txt", e.getName()); + assertEquals("c/e.txt", e.getPath()); + assertEquals("added file d and e in folder c", e.getDescription()); + assertTrue(e.getLength() > 0); + checkDate(e.getLastModified()); + } + + /** + * Method description + * + * + * @return + */ + private GitBrowseCommand createCommand() + { + return new GitBrowseCommand(createContext(), repository); + } +} diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitCatCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitCatCommandTest.java new file mode 100644 index 0000000000..1a44a0076c --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitCatCommandTest.java @@ -0,0 +1,118 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.Test; + +import sonia.scm.repository.RepositoryException; + +import static org.junit.Assert.*; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** + * TODO add not found test + * + * @author Sebastian Sdorra + */ +public class GitCatCommandTest extends AbstractGitCommandTestBase +{ + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testCat() throws IOException, RepositoryException + { + CatCommandRequest request = new CatCommandRequest(); + + request.setPath("a.txt"); + request.setRevision("3f76a12f08a6ba0dc988c68b7f0b2cd190efc3c4"); + assertEquals("a and b", execute(request)); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testSimpleCat() throws IOException, RepositoryException + { + CatCommandRequest request = new CatCommandRequest(); + + request.setPath("b.txt"); + assertEquals("b", execute(request)); + } + + /** + * Method description + * + * + * @param request + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + private String execute(CatCommandRequest request) + throws IOException, RepositoryException + { + String content = null; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + try + { + new GitCatCommand(createContext(), repository).getCatResult(request, + baos); + } + finally + { + content = baos.toString().trim(); + } + + return content; + } +} diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitLogCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitLogCommandTest.java new file mode 100644 index 0000000000..5f7f9055fb --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitLogCommandTest.java @@ -0,0 +1,232 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.Test; + +import sonia.scm.repository.Changeset; +import sonia.scm.repository.ChangesetPagingResult; +import sonia.scm.repository.Modifications; +import sonia.scm.repository.RepositoryException; + +import static org.hamcrest.Matchers.*; + +import static org.junit.Assert.*; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + */ +public class GitLogCommandTest extends AbstractGitCommandTestBase +{ + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetAll() throws IOException, RepositoryException + { + ChangesetPagingResult result = + createCommand().getChangesets(new LogCommandRequest()); + + assertNotNull(result); + assertEquals(4, result.getTotal()); + assertEquals(4, result.getChangesets().size()); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetAllByPath() throws IOException, RepositoryException + { + LogCommandRequest request = new LogCommandRequest(); + + request.setPath("a.txt"); + + ChangesetPagingResult result = createCommand().getChangesets(request); + + assertNotNull(result); + assertEquals(2, result.getTotal()); + assertEquals(2, result.getChangesets().size()); + assertEquals("fcd0ef1831e4002ac43e", result.getChangesets().get(0).getId()); + assertEquals("435df2f061add3589cb3", result.getChangesets().get(1).getId()); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetAllWithLimit() throws IOException, RepositoryException + { + LogCommandRequest request = new LogCommandRequest(); + + request.setPagingLimit(2); + + ChangesetPagingResult result = createCommand().getChangesets(request); + + assertNotNull(result); + assertEquals(4, result.getTotal()); + assertEquals(2, result.getChangesets().size()); + + Changeset c1 = result.getChangesets().get(0); + + assertNotNull(c1); + assertEquals("fcd0ef1831e4002ac43e", c1.getId()); + + Changeset c2 = result.getChangesets().get(1); + + assertNotNull(c2); + assertEquals("86a6645eceefe8b9a247", c2.getId()); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetAllWithPaging() throws IOException, RepositoryException + { + LogCommandRequest request = new LogCommandRequest(); + + request.setPagingStart(1); + request.setPagingLimit(2); + + ChangesetPagingResult result = createCommand().getChangesets(request); + + assertNotNull(result); + assertEquals(4, result.getTotal()); + assertEquals(2, result.getChangesets().size()); + + Changeset c1 = result.getChangesets().get(0); + + assertNotNull(c1); + assertEquals("86a6645eceefe8b9a247", c1.getId()); + + Changeset c2 = result.getChangesets().get(1); + + assertNotNull(c2); + assertEquals("592d797cd36432e59141", c2.getId()); + } + + /** + * Method description + * + */ + @Test + public void testGetCommit() + { + GitLogCommand command = createCommand(); + Changeset c = command.getChangeset("435df2f061add3589cb3"); + + assertNotNull(c); + assertEquals("435df2f061add3589cb3", c.getId()); + assertEquals("added a and b files", c.getDescription()); + checkDate(c.getDate()); + assertEquals("Douglas Adams", c.getAuthor().getName()); + assertEquals("douglas.adams@hitchhiker.com", c.getAuthor().getMail()); + assertEquals("added a and b files", c.getDescription()); + + Modifications mods = c.getModifications(); + + assertNotNull(mods); + assertTrue("modified list should be empty", mods.getModified().isEmpty()); + assertTrue("removed list should be empty", mods.getRemoved().isEmpty()); + assertFalse("added list should not be empty", mods.getAdded().isEmpty()); + assertEquals(2, mods.getAdded().size()); + assertThat(mods.getAdded(), contains("a.txt", "b.txt")); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetRange() throws IOException, RepositoryException + { + LogCommandRequest request = new LogCommandRequest(); + + request.setStartChangeset("592d797cd36432e59141"); + request.setEndChangeset("435df2f061add3589cb3"); + + ChangesetPagingResult result = createCommand().getChangesets(request); + + assertNotNull(result); + assertEquals(2, result.getTotal()); + assertEquals(2, result.getChangesets().size()); + + Changeset c1 = result.getChangesets().get(0); + Changeset c2 = result.getChangesets().get(1); + + assertNotNull(c1); + assertEquals("592d797cd36432e59141", c1.getId()); + assertNotNull(c2); + assertEquals("435df2f061add3589cb3", c2.getId()); + } + + /** + * Method description + * + * + * @return + */ + private GitLogCommand createCommand() + { + return new GitLogCommand(createContext(), repository); + } +} diff --git a/scm-plugins/scm-git-plugin/src/test/resources/sonia/scm/repository/spi/scm-git-spi-test.zip b/scm-plugins/scm-git-plugin/src/test/resources/sonia/scm/repository/spi/scm-git-spi-test.zip new file mode 100644 index 0000000000..3fbab0be38 Binary files /dev/null and b/scm-plugins/scm-git-plugin/src/test/resources/sonia/scm/repository/spi/scm-git-spi-test.zip differ diff --git a/scm-plugins/scm-hg-plugin/pom.xml b/scm-plugins/scm-hg-plugin/pom.xml index c7375aae1d..b8e1bc2bef 100644 --- a/scm-plugins/scm-hg-plugin/pom.xml +++ b/scm-plugins/scm-hg-plugin/pom.xml @@ -6,12 +6,12 @@ sonia.scm.plugins scm-plugins - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm.plugins scm-hg-plugin - 1.17-SNAPSHOT + 1.18-SNAPSHOT scm-hg-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Mercurial @@ -30,7 +30,7 @@ sonia.scm scm-test - 1.17-SNAPSHOT + 1.18-SNAPSHOT test diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/AbstractHgHandler.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/AbstractHgHandler.java index c1f6f60a76..431d3c0966 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/AbstractHgHandler.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/AbstractHgHandler.java @@ -35,6 +35,8 @@ package sonia.scm.repository; //~--- non-JDK imports -------------------------------------------------------- +import com.google.common.io.Closeables; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,7 +59,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; /** @@ -68,45 +69,47 @@ public class AbstractHgHandler { /** Field description */ - public static final String ENCODING = "UTF-8"; + protected static final String ENV_NODE = "HG_NODE"; + + /** Field description */ + protected static final String ENV_PAGE_LIMIT = "SCM_PAGE_LIMIT"; + + /** Field description */ + protected static final String ENV_PAGE_START = "SCM_PAGE_START"; + + /** Field description */ + protected static final String ENV_PATH = "SCM_PATH"; + + /** Field description */ + protected static final String ENV_REPOSITORY_PATH = "SCM_REPOSITORY_PATH"; + + /** Field description */ + protected static final String ENV_REVISION = "SCM_REVISION"; + + /** Field description */ + protected static final String ENV_REVISION_END = "SCM_REVISION_END"; + + /** Field description */ + protected static final String ENV_REVISION_START = "SCM_REVISION_START"; + + /** Field description */ + private static final String ENCODING = "UTF-8"; /** mercurial encoding */ - public static final String ENV_HGENCODING = "HGENCODING"; + private static final String ENV_HGENCODING = "HGENCODING"; /** Field description */ - public static final String ENV_NODE = "HG_NODE"; - - /** Field description */ - public static final String ENV_PAGE_LIMIT = "SCM_PAGE_LIMIT"; - - /** Field description */ - public static final String ENV_PAGE_START = "SCM_PAGE_START"; - - /** Field description */ - public static final String ENV_PATH = "SCM_PATH"; - - /** Field description */ - public static final String ENV_PENDING = "HG_PENDING"; + private static final String ENV_PENDING = "HG_PENDING"; /** python encoding */ - public static final String ENV_PYTHONIOENCODING = "PYTHONIOENCODING"; + private static final String ENV_PYTHONIOENCODING = "PYTHONIOENCODING"; /** Field description */ - public static final String ENV_PYTHONPATH = "PYTHONPATH"; + private static final String ENV_PYTHONPATH = "PYTHONPATH"; - /** Field description */ - public static final String ENV_REPOSITORY_PATH = "SCM_REPOSITORY_PATH"; - - /** Field description */ - public static final String ENV_REVISION = "SCM_REVISION"; - - /** Field description */ - public static final String ENV_REVISION_END = "SCM_REVISION_END"; - - /** Field description */ - public static final String ENV_REVISION_START = "SCM_REVISION_START"; - - /** the logger for AbstractHgHandler */ + /** + * the logger for AbstractHgCommand + */ private static final Logger logger = LoggerFactory.getLogger(AbstractHgHandler.class); @@ -116,63 +119,35 @@ public class AbstractHgHandler * Constructs ... * * + * * @param handler * @param context - * @param directory + * @param repository + * @param repositoryDirectory */ - public AbstractHgHandler(HgRepositoryHandler handler, HgContext context, - File directory) + protected AbstractHgHandler(HgRepositoryHandler handler, HgContext context, + Repository repository) { - this(handler, null, context, directory); + this(handler, context, repository, handler.getDirectory(repository)); } /** * Constructs ... * * + * * @param handler * @param context * @param repository + * @param repositoryDirectory */ - public AbstractHgHandler(HgRepositoryHandler handler, HgContext context, - Repository repository) - { - this(handler, null, context, handler.getDirectory(repository)); - } - - /** - * Constructs ... - * - * - * @param handler - * @param jaxbContext - * @param context - * @param directory - */ - public AbstractHgHandler(HgRepositoryHandler handler, - JAXBContext jaxbContext, HgContext context, - File directory) + protected AbstractHgHandler(HgRepositoryHandler handler, HgContext context, + Repository repository, File repositoryDirectory) { this.handler = handler; - this.jaxbContext = jaxbContext; this.context = context; - this.directory = directory; - } - - /** - * Constructs ... - * - * - * @param handler - * @param jaxbContext - * @param context - * @param repository - */ - public AbstractHgHandler(HgRepositoryHandler handler, - JAXBContext jaxbContext, HgContext context, - Repository repository) - { - this(handler, jaxbContext, context, handler.getDirectory(repository)); + this.repository = repository; + this.repositoryDirectory = repositoryDirectory; } //~--- methods -------------------------------------------------------------- @@ -332,7 +307,8 @@ public class AbstractHgHandler { handleErrorStream(p.getErrorStream()); input = p.getInputStream(); - result = (T) jaxbContext.createUnmarshaller().unmarshal(input); + result = + (T) handler.getJaxbContext().createUnmarshaller().unmarshal(input); input.close(); } catch (JAXBException ex) @@ -343,8 +319,8 @@ public class AbstractHgHandler } finally { - IOUtil.close(input); - IOUtil.close(output); + Closeables.closeQuietly(input); + Closeables.closeQuietly(output); } return result; @@ -399,7 +375,7 @@ public class AbstractHgHandler ProcessBuilder pb = new ProcessBuilder(cmdList); - pb.directory(directory); + pb.directory(repositoryDirectory); Map env = pb.environment(); @@ -416,10 +392,11 @@ public class AbstractHgHandler { if (logger.isDebugEnabled()) { - logger.debug("enable hg pending for {}", directory.getAbsolutePath()); + logger.debug("enable hg pending for {}", + repositoryDirectory.getAbsolutePath()); } - env.put(ENV_PENDING, directory.getAbsolutePath()); + env.put(ENV_PENDING, repositoryDirectory.getAbsolutePath()); if (extraEnv.containsKey(ENV_REVISION_START)) { @@ -428,14 +405,15 @@ public class AbstractHgHandler } env.put(ENV_PYTHONPATH, HgUtil.getPythonPath(config)); - env.put(ENV_REPOSITORY_PATH, directory.getAbsolutePath()); + env.put(ENV_REPOSITORY_PATH, repositoryDirectory.getAbsolutePath()); env.putAll(extraEnv); if (logger.isTraceEnabled()) { StringBuilder msg = new StringBuilder("start process in directory '"); - msg.append(directory.getAbsolutePath()).append("' with env: \n"); + msg.append(repositoryDirectory.getAbsolutePath()).append( + "' with env: \n"); for (Map.Entry e : env.entrySet()) { @@ -452,15 +430,15 @@ public class AbstractHgHandler //~--- fields --------------------------------------------------------------- + /** Field description */ + protected Repository repository; + + /** Field description */ + protected File repositoryDirectory; + /** Field description */ private HgContext context; - /** Field description */ - private File directory; - /** Field description */ private HgRepositoryHandler handler; - - /** Field description */ - private JAXBContext jaxbContext; } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgBlameViewer.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgBlameViewer.java index ea192665bc..40dfe0a58d 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgBlameViewer.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgBlameViewer.java @@ -47,8 +47,6 @@ import java.io.IOException; import java.util.Map; -import javax.xml.bind.JAXBContext; - /** * * @author Sebastian Sdorra @@ -71,11 +69,10 @@ public class HgBlameViewer extends AbstractHgHandler implements BlameViewer * @param repository * @param blameResultContext */ - public HgBlameViewer(HgRepositoryHandler handler, - JAXBContext blameResultContext, HgContext context, + public HgBlameViewer(HgRepositoryHandler handler, HgContext context, Repository repository) { - super(handler, blameResultContext, context, repository); + super(handler, context, repository); } //~--- get methods ---------------------------------------------------------- diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgChangesetViewer.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgChangesetViewer.java index 5a93eef75f..da62011a63 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgChangesetViewer.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgChangesetViewer.java @@ -74,11 +74,10 @@ public class HgChangesetViewer extends AbstractHgHandler * @param context * @param repositoryDirectory */ - public HgChangesetViewer(HgRepositoryHandler handler, - JAXBContext jaxbContext, HgContext context, + public HgChangesetViewer(HgRepositoryHandler handler, HgContext context, File repositoryDirectory) { - super(handler, jaxbContext, context, repositoryDirectory); + super(handler, context, null, repositoryDirectory); } /** @@ -95,7 +94,7 @@ public class HgChangesetViewer extends AbstractHgHandler JAXBContext jaxbContext, HgContext context, Repository repository) { - super(handler, jaxbContext, context, repository); + super(handler, context, repository); } //~--- get methods ---------------------------------------------------------- diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgHookManager.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgHookManager.java index 818bcf5a20..795e01c22b 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgHookManager.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgHookManager.java @@ -36,6 +36,7 @@ package sonia.scm.repository; //~--- non-JDK imports -------------------------------------------------------- import com.google.inject.Inject; +import com.google.inject.Provider; import com.google.inject.Singleton; import org.slf4j.Logger; @@ -43,6 +44,9 @@ import org.slf4j.LoggerFactory; import sonia.scm.ConfigChangedListener; import sonia.scm.config.ScmConfiguration; +import sonia.scm.net.HttpClient; +import sonia.scm.net.HttpRequest; +import sonia.scm.net.HttpResponse; import sonia.scm.util.HttpUtil; import sonia.scm.util.Util; @@ -81,12 +85,15 @@ public class HgHookManager implements ConfigChangedListener * * * @param configuration + * @param httpClientProvider */ @Inject - public HgHookManager(ScmConfiguration configuration) + public HgHookManager(ScmConfiguration configuration, + Provider httpClientProvider) { this.configuration = configuration; this.configuration.addListener(this); + this.httpClientProvider = httpClientProvider; } //~--- methods -------------------------------------------------------------- @@ -292,10 +299,15 @@ public class HgHookManager implements ConfigChangedListener logger.trace("check hook url {}", url); } - HttpURLConnection connection = - (HttpURLConnection) new URL(url).openConnection(); + HttpRequest request = new HttpRequest(url); - result = connection.getResponseCode() == 204; + request.setDisableCertificateValidation(true); + request.setDisableHostnameValidation(true); + request.setIgnoreProxySettings(true); + + HttpResponse response = httpClientProvider.get().get(request); + + result = response.getStatusCode() == 204; } catch (IOException ex) { @@ -318,4 +330,7 @@ public class HgHookManager implements ConfigChangedListener /** Field description */ private volatile String hookUrl; + + /** Field description */ + private Provider httpClientProvider; } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgImportHandler.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgImportHandler.java index 2d85ea7bf2..30b5063c11 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgImportHandler.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgImportHandler.java @@ -30,14 +30,19 @@ */ + package sonia.scm.repository; //~--- non-JDK imports -------------------------------------------------------- +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import sonia.scm.io.INIConfiguration; import sonia.scm.io.INIConfigurationReader; import sonia.scm.io.INIConfigurationWriter; import sonia.scm.io.INISection; +import sonia.scm.util.ValidationUtil; //~--- JDK imports ------------------------------------------------------------ @@ -54,6 +59,12 @@ public class HgImportHandler extends AbstactImportHandler /** Field description */ public static final String HG_DIR = ".hg"; + /** + * the logger for HgImportHandler + */ + private static final Logger logger = + LoggerFactory.getLogger(HgImportHandler.class); + //~--- constructors --------------------------------------------------------- /** @@ -103,10 +114,21 @@ public class HgImportHandler extends AbstactImportHandler else { repository.setDescription(web.getParameter("description")); - repository.setContact(web.getParameter("contact")); + + String contact = web.getParameter("contact"); + + if (ValidationUtil.isMailAddressValid(contact)) + { + repository.setContact(contact); + } + else if (logger.isWarnEnabled()) + { + logger.warn("contact {} is not a valid mail address", contact); + } + handler.setWebParameter(web); } - + // issue-97 handler.registerMissingHook(c, repositoryName); diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgPythonScript.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgPythonScript.java index 927236d6ea..c0a467f5b1 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgPythonScript.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgPythonScript.java @@ -30,6 +30,7 @@ */ + package sonia.scm.repository; //~--- non-JDK imports -------------------------------------------------------- @@ -47,7 +48,8 @@ import java.io.File; public enum HgPythonScript { BLAME("blame.py"), CHANGELOG("changelog.py"), FILELOG("filelog.py"), - UTIL("util.py"), HOOK("scmhooks.py"), HGWEB("hgweb.py"), VERSION("version.py"); + LOG("log.py"), UTIL("util.py"), HOOK("scmhooks.py"), HGWEB("hgweb.py"), + VERSION("version.py"); /** Field description */ private static final String BASE_DIRECTORY = diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryBrowser.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryBrowser.java index 947e2d26b8..4a7c292087 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryBrowser.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryBrowser.java @@ -47,8 +47,6 @@ import java.io.OutputStream; import java.util.Map; -import javax.xml.bind.JAXBContext; - /** * * @author Sebastian Sdorra @@ -66,11 +64,10 @@ public class HgRepositoryBrowser extends AbstractHgHandler * @param repository * @param browserResultContext */ - public HgRepositoryBrowser(HgRepositoryHandler handler, - JAXBContext browserResultContext, - HgContext context, Repository repository) + public HgRepositoryBrowser(HgRepositoryHandler handler, HgContext context, + Repository repository) { - super(handler, browserResultContext, context, repository); + super(handler, context, repository); } //~--- get methods ---------------------------------------------------------- diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryHandler.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryHandler.java index 045f540af6..f883b571af 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryHandler.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryHandler.java @@ -127,7 +127,8 @@ public class HgRepositoryHandler try { this.jaxbContext = JAXBContext.newInstance(BrowserResult.class, - BlameResult.class, Changeset.class, ChangesetPagingResult.class); + BlameResult.class, Changeset.class, ChangesetPagingResult.class, + HgVersion.class); } catch (JAXBException ex) { @@ -222,8 +223,8 @@ public class HgRepositoryHandler if (TYPE_NAME.equals(type)) { - blameViewer = new HgBlameViewer(this, jaxbContext, - hgContextProvider.get(), repository); + blameViewer = new HgBlameViewer(this, hgContextProvider.get(), + repository); } else { @@ -311,6 +312,17 @@ public class HgRepositoryHandler return new HgImportHandler(this); } + /** + * Method description + * + * + * @return + */ + public JAXBContext getJaxbContext() + { + return jaxbContext; + } + /** * Method description * @@ -322,8 +334,7 @@ public class HgRepositoryHandler @Override public RepositoryBrowser getRepositoryBrowser(Repository repository) { - return new HgRepositoryBrowser(this, jaxbContext, hgContextProvider.get(), - repository); + return new HgRepositoryBrowser(this, hgContextProvider.get(), repository); } /** @@ -352,16 +363,23 @@ public class HgRepositoryHandler try { - JAXBContext context = JAXBContext.newInstance(HgVersion.class); - HgVersion hgVersion = new HgVersionHandler(this, context, - hgContextProvider.get(), + HgVersion hgVersion = new HgVersionHandler(this, hgContextProvider.get(), baseDirectory).getVersion(); if (hgVersion != null) { + if (logger.isDebugEnabled()) + { + logger.debug("mercurial/python informations: {}", hgVersion); + } + version = MessageFormat.format(version, hgVersion.getPython(), hgVersion.getMercurial()); } + else if (logger.isWarnEnabled()) + { + logger.warn("could not retrieve version informations"); + } } catch (Exception ex) { @@ -470,8 +488,7 @@ public class HgRepositoryHandler throw new IllegalStateException("directory not found"); } - return new HgChangesetViewer(this, jaxbContext, context, - repositoryDirectory); + return new HgChangesetViewer(this, context, repositoryDirectory); } //~--- set methods ---------------------------------------------------------- diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgVersion.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgVersion.java index 616d2dbab5..afe6a17ca1 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgVersion.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgVersion.java @@ -1,36 +1,41 @@ /** - * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * 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 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. + * 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.repository; +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Objects; + //~--- JDK imports ------------------------------------------------------------ import javax.xml.bind.annotation.XmlAccessType; @@ -46,6 +51,64 @@ import javax.xml.bind.annotation.XmlRootElement; public class HgVersion { + /** + * Method description + * + * + * @param obj + * + * @return + */ + @Override + public boolean equals(Object obj) + { + if (obj == null) + { + return false; + } + + if (getClass() != obj.getClass()) + { + return false; + } + + final HgVersion other = (HgVersion) obj; + + return Objects.equal(mercurial, other.mercurial) + && Objects.equal(python, other.python); + } + + /** + * Method description + * + * + * @return + */ + @Override + public int hashCode() + { + return Objects.hashCode(mercurial, python); + } + + /** + * Method description + * + * + * @return + */ + @Override + public String toString() + { + //J- + return Objects.toStringHelper(this) + .add("mercurial", mercurial) + .add("python", python) + .toString(); + //J+ + } + + //~--- get methods ---------------------------------------------------------- + /** * Method description * diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgVersionHandler.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgVersionHandler.java index 722b09fab4..e52eee2c8a 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgVersionHandler.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgVersionHandler.java @@ -1,34 +1,35 @@ /** - * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * 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 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. + * 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.repository; //~--- JDK imports ------------------------------------------------------------ @@ -36,8 +37,6 @@ package sonia.scm.repository; import java.io.File; import java.io.IOException; -import javax.xml.bind.JAXBContext; - /** * * @author Sebastian Sdorra @@ -54,10 +53,10 @@ public class HgVersionHandler extends AbstractHgHandler * @param context * @param directory */ - public HgVersionHandler(HgRepositoryHandler handler, JAXBContext jaxbContext, - HgContext context, File directory) + public HgVersionHandler(HgRepositoryHandler handler, HgContext context, + File directory) { - super(handler, jaxbContext, context, directory); + super(handler, context, null, directory); } //~--- get methods ---------------------------------------------------------- diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/AbstractHgCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/AbstractHgCommand.java new file mode 100644 index 0000000000..26613150c1 --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/AbstractHgCommand.java @@ -0,0 +1,88 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.repository.AbstractHgHandler; +import sonia.scm.repository.HgContext; +import sonia.scm.repository.HgRepositoryHandler; +import sonia.scm.repository.Repository; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; + +import java.util.Map; + +/** + * + * @author Sebastian Sdorra + */ +public class AbstractHgCommand extends AbstractHgHandler +{ + + /** + * Constructs ... + * + * + * @param handler + * @param context + * @param repository + * @param repositoryDirectory + */ + protected AbstractHgCommand(HgRepositoryHandler handler, HgContext context, + Repository repository, File repositoryDirectory) + { + super(handler, context, repository, repositoryDirectory); + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param revision + * @param path + * + * @param request + * + * @return + */ + protected Map createEnvironment(FileBaseCommandRequest request) + { + return createEnvironment(request.getRevision(), request.getPath()); + } +} diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBlameCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBlameCommand.java new file mode 100644 index 0000000000..4c9d3f7f06 --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBlameCommand.java @@ -0,0 +1,110 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sonia.scm.repository.BlameResult; +import sonia.scm.repository.HgContext; +import sonia.scm.repository.HgPythonScript; +import sonia.scm.repository.HgRepositoryHandler; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryException; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; +import java.io.IOException; + +import java.util.Map; + +/** + * + * @author Sebastian Sdorra + */ +public class HgBlameCommand extends AbstractHgCommand implements BlameCommand +{ + + /** + * the logger for HgBlameCommand + */ + private static final Logger logger = + LoggerFactory.getLogger(HgBlameCommand.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param handler + * @param context + * @param repository + * @param repositoryDirectory + */ + public HgBlameCommand(HgRepositoryHandler handler, HgContext context, + Repository repository, File repositoryDirectory) + { + super(handler, context, repository, repositoryDirectory); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param request + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public BlameResult getBlameResult(BlameCommandRequest request) + throws IOException, RepositoryException + { + if (logger.isDebugEnabled()) + { + logger.debug("get blame result for {}", request); + } + + Map env = createEnvironment(request); + + return getResultFromScript(BlameResult.class, HgPythonScript.BLAME, env); + } +} diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBrowseCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBrowseCommand.java new file mode 100644 index 0000000000..56ce86734c --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgBrowseCommand.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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.repository.BrowserResult; +import sonia.scm.repository.HgContext; +import sonia.scm.repository.HgPythonScript; +import sonia.scm.repository.HgRepositoryHandler; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryException; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; +import java.io.IOException; + +import java.util.Map; + +/** + * + * @author Sebastian Sdorra + */ +public class HgBrowseCommand extends AbstractHgCommand implements BrowseCommand +{ + + /** + * Constructs ... + * + * + * @param handler + * @param context + * @param repository + * @param repositoryDirectory + */ + public HgBrowseCommand(HgRepositoryHandler handler, HgContext context, + Repository repository, File repositoryDirectory) + { + super(handler, context, repository, repositoryDirectory); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param revision + * @param path + * + * @param request + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public BrowserResult getBrowserResult(BrowseCommandRequest request) + throws IOException, RepositoryException + { + Map env = createEnvironment(request); + + return getResultFromScript(BrowserResult.class, HgPythonScript.FILELOG, + env); + } +} diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgCatCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgCatCommand.java new file mode 100644 index 0000000000..69c012e52a --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgCatCommand.java @@ -0,0 +1,108 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.io.ByteStreams; +import com.google.common.io.Closeables; + +import sonia.scm.repository.HgContext; +import sonia.scm.repository.HgRepositoryHandler; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryException; +import sonia.scm.util.Util; +import sonia.scm.web.HgUtil; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * + * @author Sebastian Sdorra + */ +public class HgCatCommand extends AbstractHgCommand implements CatCommand +{ + + /** + * Constructs ... + * + * + * @param handler + * @param context + * @param repository + * @param repositoryDirectory + */ + HgCatCommand(HgRepositoryHandler handler, HgContext context, + Repository repository, File repositoryDirectory) + { + super(handler, context, repository, repositoryDirectory); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param request + * @param output + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public void getCatResult(CatCommandRequest request, OutputStream output) + throws IOException, RepositoryException + { + String revision = HgUtil.getRevision(request.getRevision()); + Process p = createHgProcess("cat", "-r", revision, + Util.nonNull(request.getPath())); + InputStream input = null; + + try + { + handleErrorStream(p.getErrorStream()); + input = p.getInputStream(); + ByteStreams.copy(input, output); + } + finally + { + Closeables.closeQuietly(input); + } + } +} diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgDiffCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgDiffCommand.java new file mode 100644 index 0000000000..8ec6d58367 --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgDiffCommand.java @@ -0,0 +1,106 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.io.ByteStreams; +import com.google.common.io.Closeables; + +import sonia.scm.repository.HgContext; +import sonia.scm.repository.HgRepositoryHandler; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryException; +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * + * @author Sebastian Sdorra + */ +public class HgDiffCommand extends AbstractHgCommand implements DiffCommand +{ + + /** + * Constructs ... + * + * + * @param handler + * @param context + * @param repository + * @param repositoryDirectory + */ + public HgDiffCommand(HgRepositoryHandler handler, HgContext context, + Repository repository, File repositoryDirectory) + { + super(handler, context, repository, repositoryDirectory); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param request + * @param output + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public void getDiffResult(DiffCommandRequest request, OutputStream output) + throws IOException, RepositoryException + { + Process p = createHgProcess("diff", "-c", request.getRevision(), + Util.nonNull(request.getPath())); + InputStream input = null; + + try + { + handleErrorStream(p.getErrorStream()); + input = p.getInputStream(); + ByteStreams.copy(input, output); + } + finally + { + Closeables.closeQuietly(input); + } + } +} diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgLogCommand.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgLogCommand.java new file mode 100644 index 0000000000..d90211d437 --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgLogCommand.java @@ -0,0 +1,136 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Strings; +import com.google.common.collect.Maps; + +import sonia.scm.repository.Changeset; +import sonia.scm.repository.ChangesetPagingResult; +import sonia.scm.repository.HgContext; +import sonia.scm.repository.HgPythonScript; +import sonia.scm.repository.HgRepositoryHandler; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryException; +import sonia.scm.util.Util; +import sonia.scm.web.HgUtil; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; +import java.io.IOException; + +import java.util.Map; + +/** + * + * @author Sebastian Sdorra + */ +public class HgLogCommand extends AbstractHgCommand implements LogCommand +{ + + /** + * Constructs ... + * + * + * @param handler + * @param context + * @param repository + * @param repositoryDirectory + */ + public HgLogCommand(HgRepositoryHandler handler, HgContext context, + Repository repository, File repositoryDirectory) + { + super(handler, context, repository, repositoryDirectory); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param id + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public Changeset getChangeset(String id) + throws IOException, RepositoryException + { + Map env = Maps.newHashMap(); + + env.put(ENV_REVISION, HgUtil.getRevision(id)); + env.put(ENV_PATH, Util.EMPTY_STRING); + env.put(ENV_PAGE_START, "0"); + env.put(ENV_PAGE_LIMIT, "1"); + env.put(ENV_REVISION_START, Util.EMPTY_STRING); + env.put(ENV_REVISION_END, Util.EMPTY_STRING); + + return getResultFromScript(Changeset.class, HgPythonScript.LOG, env); + } + + /** + * Method description + * + * + * @param request + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public ChangesetPagingResult getChangesets(LogCommandRequest request) + throws IOException, RepositoryException + { + Map env = Maps.newHashMap(); + + env.put(ENV_REVISION, Util.EMPTY_STRING); + env.put(ENV_PATH, Strings.nullToEmpty(request.getPath())); + env.put(ENV_PAGE_START, String.valueOf(request.getPagingStart())); + env.put(ENV_PAGE_LIMIT, String.valueOf(request.getPagingLimit())); + env.put(ENV_REVISION_START, + Strings.nullToEmpty(request.getStartChangeset())); + env.put(ENV_REVISION_END, Strings.nullToEmpty(request.getEndChangeset())); + + return getResultFromScript(ChangesetPagingResult.class, HgPythonScript.LOG, + env); + } +} diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceProvider.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceProvider.java new file mode 100644 index 0000000000..ffcc0fe776 --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceProvider.java @@ -0,0 +1,176 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.collect.ImmutableSet; +import com.google.inject.Provider; + +import sonia.scm.repository.HgContext; +import sonia.scm.repository.HgRepositoryHandler; +import sonia.scm.repository.Repository; +import sonia.scm.repository.api.Command; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; + +import java.util.Set; + +/** + * + * @author Sebastian Sdorra + */ +public class HgRepositoryServiceProvider extends RepositoryServiceProvider +{ + + /** Field description */ + private static final Set COMMANDS = ImmutableSet.of(Command.BLAME, + Command.BROWSE, Command.CAT, + Command.DIFF, Command.LOG); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * + * @param hgContextProvider + * @param handler + * @param repository + */ + HgRepositoryServiceProvider(HgRepositoryHandler handler, + Provider hgContextProvider, + Repository repository) + { + this.hgContextProvider = hgContextProvider; + this.handler = handler; + this.repository = repository; + this.repositoryDirectory = handler.getDirectory(repository); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + public HgBlameCommand getBlameCommand() + { + return new HgBlameCommand(handler, hgContextProvider.get(), repository, + repositoryDirectory); + } + + /** + * Method description + * + * + * @return + */ + @Override + public HgBrowseCommand getBrowseCommand() + { + return new HgBrowseCommand(handler, hgContextProvider.get(), repository, + repositoryDirectory); + } + + /** + * Method description + * + * + * @return + */ + @Override + public HgCatCommand getCatCommand() + { + return new HgCatCommand(handler, hgContextProvider.get(), repository, + repositoryDirectory); + } + + /** + * Method description + * + * + * @return + */ + @Override + public HgDiffCommand getDiffCommand() + { + return new HgDiffCommand(handler, hgContextProvider.get(), repository, + repositoryDirectory); + } + + /** + * Method description + * + * + * @return + */ + @Override + public HgLogCommand getLogCommand() + { + return new HgLogCommand(handler, hgContextProvider.get(), repository, + repositoryDirectory); + } + + /** + * Method description + * + * + * @return + */ + @Override + public Set getSupportedCommands() + { + return COMMANDS; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private HgRepositoryHandler handler; + + /** Field description */ + private Provider hgContextProvider; + + /** Field description */ + private Repository repository; + + /** Field description */ + private File repositoryDirectory; +} diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceResolver.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceResolver.java new file mode 100644 index 0000000000..abdfd441e1 --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceResolver.java @@ -0,0 +1,104 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.inject.Inject; +import com.google.inject.Provider; + +import sonia.scm.plugin.ext.Extension; +import sonia.scm.repository.HgContext; +import sonia.scm.repository.HgRepositoryHandler; +import sonia.scm.repository.Repository; + +/** + * + * @author Sebastian Sdorra + */ +@Extension +public class HgRepositoryServiceResolver implements RepositoryServiceResolver +{ + + /** Field description */ + private static final String TYPE = "hg"; + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param handler + * @param hgContextProvider + */ + @Inject + public HgRepositoryServiceResolver(HgRepositoryHandler handler, + Provider hgContextProvider) + { + this.handler = handler; + this.hgContextProvider = hgContextProvider; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param repository + * + * @return + */ + @Override + public HgRepositoryServiceProvider reslove(Repository repository) + { + HgRepositoryServiceProvider provider = null; + + if (TYPE.equalsIgnoreCase(repository.getType())) + { + provider = new HgRepositoryServiceProvider(handler, hgContextProvider, + repository); + } + + return provider; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private HgRepositoryHandler handler; + + /** Field description */ + private Provider hgContextProvider; +} diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIExceptionHandler.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIExceptionHandler.java index 5c67d147e9..c1e068b665 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIExceptionHandler.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIExceptionHandler.java @@ -1,34 +1,35 @@ /** - * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * 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 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. + * 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.web; //~--- non-JDK imports -------------------------------------------------------- diff --git a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/filelog.py b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/filelog.py index 6fe5fa1f29..af63e1ca98 100644 --- a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/filelog.py +++ b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/filelog.py @@ -44,6 +44,11 @@ def getName(path): length =- 1 return parts[length - 1] +def removeTrailingSlash(path): + if path.endswith('/'): + path = path[0:-1] + return path + def appendSubRepositoryNode(doc, parentNode, path, subRepositories): if path in subRepositories: subRepository = subRepositories[path] @@ -55,7 +60,7 @@ def appendSubRepositoryNode(doc, parentNode, path, subRepositories): def createBasicFileNode(doc, parentNode, path, directory): fileNode = createChildNode(doc, parentNode, 'file') appendTextNode(doc, fileNode, 'name', getName(path)) - appendTextNode(doc, fileNode, 'path', path) + appendTextNode(doc, fileNode, 'path', removeTrailingSlash(path)) appendTextNode(doc, fileNode, 'directory', directory) return fileNode diff --git a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/log.py b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/log.py new file mode 100644 index 0000000000..4db781321b --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/log.py @@ -0,0 +1,147 @@ +# +# 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 +# +# + + +import os +from util import * +from xml.dom.minidom import Document + +# changeset methods + +def appendIdNode(doc, parentNode, ctx): + id = getId(ctx) + appendTextNode(doc, parentNode, 'id', id) + +def appendParentNodes(doc, parentNode, ctx): + parents = ctx.parents() + if parents: + for parent in parents: + parentId = getId(parent) + appendTextNode(doc, parentNode, 'parents', parentId) + +def appendBranchesNode(doc, parentNode, ctx): + branch = ctx.branch() + if branch != 'default': + appendTextNode(doc, parentNode, 'branches', branch) + +def appendModifications(doc, parentNode, ctx): + status = repo.status(ctx.p1().node(), ctx.node()) + if status: + modificationsNode = createChildNode(doc, parentNode, 'modifications') + appendWrappedListNodes(doc, modificationsNode, 'added', 'file', status[1]) + appendWrappedListNodes(doc, modificationsNode, 'modified', 'file', status[0]) + appendWrappedListNodes(doc, modificationsNode, 'removed', 'file', status[2]) + +def appendChangesetNode(doc, parentNode, ctx): + changesetNode = createChildNode(doc, parentNode, 'changeset') + appendIdNode(doc, changesetNode, ctx) + appendParentNodes(doc, changesetNode, ctx) + appendTextNode(doc, changesetNode, 'description', ctx.description()) + appendDateNode(doc, changesetNode, 'date', ctx.date()) + appendAuthorNodes(doc, changesetNode, ctx) + appendBranchesNode(doc, changesetNode, ctx) + appendListNodes(doc, changesetNode, 'tags', ctx.tags()) + appendModifications(doc, changesetNode, ctx) + +# changeset methods end + +# change log methods + +def createBasicNodes(doc, ctxs): + rootNode = doc.createElement('changeset-paging') + doc.appendChild(rootNode) + total = str(len(ctxs)) + appendTextNode(doc, rootNode, 'total', total) + return createChildNode(doc, rootNode, 'changesets') + +def collectChangesets(repo, path, startNode, endNode): + start = 'tip' + end = '0' + if len(startNode) > 0: + start = startNode + if len(endNode) > 0: + end = endNode + + ctxs = [] + startRev = repo[start].rev() + endRev = repo[end].rev() - 1 + + onlyWithPath = len(path) > 0 + + for i in range(startRev, endRev, -1): + ctx = repo[i] + if onlyWithPath: + if path in ctx.files(): + ctxs.append(ctx) + else: + ctxs.append(ctx) + + return ctxs + +def stripChangesets(ctxs, start, limit): + if limit < 0: + ctxs = ctxs[start:] + else: + limit = limit + start + if limit > len(ctxs): + ctxs = ctxs[start:] + else: + ctxs = ctxs[start:limit] + return ctxs + +# change log methods + +# main method +repo = openRepository() +doc = Document() + +# parameter +path = os.environ['SCM_PATH'] +startNode = os.environ['SCM_REVISION_START'] +endNode = os.environ['SCM_REVISION_END'] +rev = os.environ['SCM_REVISION'] +# paging parameter +start = int(os.environ['SCM_PAGE_START']) +limit = int(os.environ['SCM_PAGE_LIMIT']) + +if len(rev) > 0: + ctx = repo[rev] + appendChangesetNode(doc, doc, ctx) +else: + ctxs = collectChangesets(repo, path, startNode, endNode) + changesetsNode = createBasicNodes(doc, ctxs) + ctxs = stripChangesets(ctxs, start, limit) + for ctx in ctxs: + appendChangesetNode(doc, changesetsNode, ctx) + + +# write document +writeXml(doc) diff --git a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/version.py b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/version.py index c6cccc7c6d..b92504d338 100644 --- a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/version.py +++ b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/python/version.py @@ -1,3 +1,34 @@ +# +# 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 +# +# + import sys from mercurial import util from xml.dom.minidom import Document diff --git a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/web/cgimessages.properties b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/web/cgimessages.properties index 6fac1956dd..a42f82271d 100644 --- a/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/web/cgimessages.properties +++ b/scm-plugins/scm-hg-plugin/src/main/resources/sonia/scm/web/cgimessages.properties @@ -1,9 +1,10 @@ +# # 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, @@ -12,7 +13,7 @@ # 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 @@ -23,9 +24,10 @@ # 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 -# +# +# error.notConfigured = The mercurial installation on the scm-manager server seems to be not configured correctly. Please check the settings. error.statusCode = Mercurial/Python process ends with return code {0} diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/HgContextProvider.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/HgContextProvider.java new file mode 100644 index 0000000000..4b0979da8d --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/HgContextProvider.java @@ -0,0 +1,57 @@ +/** + * 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.repository; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.inject.Provider; + +/** + * + * @author Sebastian Sdorra + */ +public class HgContextProvider implements Provider +{ + + /** + * Method description + * + * + * @return + */ + @Override + public HgContext get() + { + return new HgContext(); + } +} diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/HgRepositoryHandlerTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/HgRepositoryHandlerTest.java index 21d82f0827..ab052525fe 100644 --- a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/HgRepositoryHandlerTest.java +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/HgRepositoryHandlerTest.java @@ -104,28 +104,4 @@ public class HgRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase return handler; } - - //~--- inner classes -------------------------------------------------------- - - /** - * Dummy {@link Provider} for {@link HgContext} - * - * - * @author Sebastian Sdorra - */ - private static class HgContextProvider implements Provider - { - - /** - * Return context for mercurial - * - * - * @return context for mercurial - */ - @Override - public HgContext get() - { - return new HgContext(); - } - } } diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/TempSCMContextProvider.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/TempSCMContextProvider.java new file mode 100644 index 0000000000..0e14d8e8ee --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/TempSCMContextProvider.java @@ -0,0 +1,143 @@ +/** + * 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.repository; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.SCMContextProvider; +import sonia.scm.Stage; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + */ +public class TempSCMContextProvider implements SCMContextProvider +{ + + /** + * Method description + * + * + * @throws IOException + */ + @Override + public void close() throws IOException + { + + // do nothing + } + + /** + * Method description + * + */ + @Override + public void init() + { + + // do nothing + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + public File getBaseDirectory() + { + return baseDirectory; + } + + /** + * Method description + * + * + * @return + */ + @Override + public Stage getStage() + { + return Stage.DEVELOPMENT; + } + + /** + * Method description + * + * + * @return + */ + @Override + public Throwable getStartupError() + { + return null; + } + + /** + * Method description + * + * + * @return + */ + @Override + public String getVersion() + { + return "UNIT-Test"; + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param baseDirectory + */ + public void setBaseDirectory(File baseDirectory) + { + this.baseDirectory = baseDirectory; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private File baseDirectory; +} diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/AbstractHgCommandTestBase.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/AbstractHgCommandTestBase.java new file mode 100644 index 0000000000..fda5e14462 --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/AbstractHgCommandTestBase.java @@ -0,0 +1,120 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.Assume; +import org.junit.Before; + +import sonia.scm.SCMContext; +import sonia.scm.io.FileSystem; +import sonia.scm.repository.HgContextProvider; +import sonia.scm.repository.HgRepositoryHandler; +import sonia.scm.repository.TempSCMContextProvider; +import sonia.scm.store.MemoryStoreFactory; + +import static org.mockito.Mockito.*; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + */ +public class AbstractHgCommandTestBase extends ZippedRepositoryTestBase +{ + + /** + * Method description + * + * + * @throws IOException + */ + @Before + public void initHgHandler() throws IOException + { + File folder = tempFolder.newFolder(); + TempSCMContextProvider context = + (TempSCMContextProvider) SCMContext.getContext(); + + context.setBaseDirectory(folder); + + FileSystem fileSystem = mock(FileSystem.class); + + this.handler = new HgRepositoryHandler(new MemoryStoreFactory(), + fileSystem, new HgContextProvider()); + this.handler.init(context); + + // skip tests if hg not in path + if (!handler.isConfigured()) + { + System.out.println("WARNING could not find hg, skipping test"); + Assume.assumeTrue(false); + } + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + protected String getType() + { + return "hg"; + } + + /** + * Method description + * + * + * @return + */ + @Override + protected String getZippedRepositoryResource() + { + return "sonia/scm/repository/spi/scm-hg-spi-test.zip"; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + protected HgRepositoryHandler handler; +} diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgBlameCommandTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgBlameCommandTest.java new file mode 100644 index 0000000000..d55f6d6fce --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgBlameCommandTest.java @@ -0,0 +1,136 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.Test; + +import sonia.scm.repository.BlameLine; +import sonia.scm.repository.BlameResult; +import sonia.scm.repository.HgContext; +import sonia.scm.repository.RepositoryException; + +import static org.junit.Assert.*; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + */ +public class HgBlameCommandTest extends AbstractHgCommandTestBase +{ + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetBlameResult() throws IOException, RepositoryException + { + BlameCommandRequest request = new BlameCommandRequest(); + + request.setPath("a.txt"); + + BlameResult result = new HgBlameCommand(handler, new HgContext(), + repository, + repositoryDirectory).getBlameResult(request); + + assertNotNull(result); + assertEquals(2, result.getTotal()); + + BlameLine line = result.getLine(0); + + checkFirstLine(line); + line = result.getLine(1); + assertEquals(2, line.getLineNumber()); + assertEquals("4:2baab8e80280", line.getRevision()); + checkDate(line.getWhen()); + assertEquals("line for blame", line.getCode()); + assertEquals("added new line for blame", line.getDescription()); + assertEquals("Zaphod Beeblebrox", line.getAuthor().getName()); + assertEquals("zaphod.beeblebrox@hitchhiker.com", + line.getAuthor().getMail()); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetBlameResultWithRevision() + throws IOException, RepositoryException + { + BlameCommandRequest request = new BlameCommandRequest(); + + request.setPath("a.txt"); + request.setRevision("a9bacaf1b7fa"); + + BlameResult result = new HgBlameCommand(handler, new HgContext(), + repository, + repositoryDirectory).getBlameResult(request); + + assertNotNull(result); + assertEquals(1, result.getTotal()); + + BlameLine line = result.getLine(0); + + checkFirstLine(line); + } + + /** + * Method description + * + * + * @param line + */ + private void checkFirstLine(BlameLine line) + { + assertEquals(1, line.getLineNumber()); + assertEquals("0:a9bacaf1b7fa", line.getRevision()); + checkDate(line.getWhen()); + assertEquals("a", line.getCode()); + assertEquals("added a and b files", line.getDescription()); + assertEquals("Douglas Adams", line.getAuthor().getName()); + assertEquals("douglas.adams@hitchhiker.com", line.getAuthor().getMail()); + } +} diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgBrowseCommandTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgBrowseCommandTest.java new file mode 100644 index 0000000000..e637e0c12a --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgBrowseCommandTest.java @@ -0,0 +1,166 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.Test; + +import sonia.scm.repository.BrowserResult; +import sonia.scm.repository.FileObject; +import sonia.scm.repository.HgContext; +import sonia.scm.repository.RepositoryException; + +import static org.junit.Assert.*; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +import java.util.List; + +/** + * + * @author Sebastian Sdorra + */ +public class HgBrowseCommandTest extends AbstractHgCommandTestBase +{ + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testBrowse() throws IOException, RepositoryException + { + BrowserResult result = new HgBrowseCommand( + handler, new HgContext(), repository, + repositoryDirectory).getBrowserResult( + new BrowseCommandRequest()); + + assertNotNull(result); + + List foList = result.getFiles(); + + assertNotNull(foList); + assertFalse(foList.isEmpty()); + assertEquals(4, foList.size()); + + FileObject a = null; + FileObject c = null; + + for (FileObject f : foList) + { + if ("a.txt".equals(f.getName())) + { + a = f; + } + else if ("c".equals(f.getName())) + { + c = f; + } + } + + assertNotNull(a); + assertFalse(a.isDirectory()); + assertEquals("a.txt", a.getName()); + assertEquals("a.txt", a.getPath()); + assertEquals("added new line for blame", a.getDescription()); + assertTrue(a.getLength() > 0); + checkDate(a.getLastModified()); + assertNotNull(c); + assertTrue(c.isDirectory()); + assertEquals("c", c.getName()); + assertEquals("c", c.getPath()); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testBrowseSubDirectory() throws IOException, RepositoryException + { + BrowseCommandRequest request = new BrowseCommandRequest(); + + request.setPath("c"); + + BrowserResult result = new HgBrowseCommand(handler, new HgContext(), + repository, + repositoryDirectory).getBrowserResult(request); + + assertNotNull(result); + + List foList = result.getFiles(); + + assertNotNull(foList); + assertFalse(foList.isEmpty()); + assertEquals(2, foList.size()); + + FileObject d = null; + FileObject e = null; + + for (FileObject f : foList) + { + if ("d.txt".equals(f.getName())) + { + d = f; + } + else if ("e.txt".equals(f.getName())) + { + e = f; + } + } + + assertNotNull(d); + assertFalse(d.isDirectory()); + assertEquals("d.txt", d.getName()); + assertEquals("c/d.txt", d.getPath()); + assertEquals("added file d and e in folder c", d.getDescription()); + assertTrue(d.getLength() > 0); + checkDate(d.getLastModified()); + assertNotNull(e); + assertFalse(e.isDirectory()); + assertEquals("e.txt", e.getName()); + assertEquals("c/e.txt", e.getPath()); + assertEquals("added file d and e in folder c", e.getDescription()); + assertTrue(e.getLength() > 0); + checkDate(e.getLastModified()); + } +} diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgCatCommandTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgCatCommandTest.java new file mode 100644 index 0000000000..45bfee8414 --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgCatCommandTest.java @@ -0,0 +1,118 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.Test; + +import sonia.scm.repository.HgContext; +import sonia.scm.repository.RepositoryException; + +import static org.junit.Assert.*; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + */ +public class HgCatCommandTest extends AbstractHgCommandTestBase +{ + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testCat() throws IOException, RepositoryException + { + CatCommandRequest request = new CatCommandRequest(); + + request.setPath("a.txt"); + request.setRevision("a9bacaf1b7fa"); + assertEquals("a", execute(request)); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testSimpleCat() throws IOException, RepositoryException + { + CatCommandRequest request = new CatCommandRequest(); + + request.setPath("b.txt"); + assertEquals("b", execute(request)); + } + + /** + * Method description + * + * + * @param request + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + private String execute(CatCommandRequest request) + throws IOException, RepositoryException + { + String content = null; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + try + { + new HgCatCommand(handler, new HgContext(), repository, + repositoryDirectory).getCatResult(request, baos); + } + finally + { + content = baos.toString().trim(); + } + + return content; + } +} diff --git a/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgLogCommandTest.java b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgLogCommandTest.java new file mode 100644 index 0000000000..aec477a6d7 --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/test/java/sonia/scm/repository/spi/HgLogCommandTest.java @@ -0,0 +1,236 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.Test; + +import sonia.scm.repository.Changeset; +import sonia.scm.repository.ChangesetPagingResult; +import sonia.scm.repository.HgContext; +import sonia.scm.repository.Modifications; +import sonia.scm.repository.RepositoryException; + +import static org.hamcrest.Matchers.*; + +import static org.junit.Assert.*; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + */ +public class HgLogCommandTest extends AbstractHgCommandTestBase +{ + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetAll() throws IOException, RepositoryException + { + ChangesetPagingResult result = new HgLogCommand( + handler, new HgContext(), repository, + repositoryDirectory).getChangesets( + new LogCommandRequest()); + + assertNotNull(result); + assertEquals(5, result.getTotal()); + assertEquals(5, result.getChangesets().size()); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetAllByPath() throws IOException, RepositoryException + { + LogCommandRequest request = new LogCommandRequest(); + + request.setPath("a.txt"); + + ChangesetPagingResult result = + new HgLogCommand(handler, new HgContext(), repository, + repositoryDirectory).getChangesets(request); + + assertNotNull(result); + assertEquals(3, result.getTotal()); + assertEquals(3, result.getChangesets().size()); + assertEquals("4:2baab8e80280", result.getChangesets().get(0).getId()); + assertEquals("2:79b6baf49711", result.getChangesets().get(1).getId()); + assertEquals("0:a9bacaf1b7fa", result.getChangesets().get(2).getId()); + } + + + /** + * Method description + * + * + * @throws IOException + */ + @Test + public void testGetAllWithPaging() throws IOException, RepositoryException + { + LogCommandRequest request = new LogCommandRequest(); + + request.setPagingStart(1); + request.setPagingLimit(2); + + ChangesetPagingResult result = + new HgLogCommand(handler, new HgContext(), repository, + repositoryDirectory).getChangesets(request); + + assertNotNull(result); + assertEquals(5, result.getTotal()); + assertEquals(2, result.getChangesets().size()); + + Changeset c1 = result.getChangesets().get(0); + + assertNotNull(c1); + assertEquals("3:542bf4893dd2", c1.getId()); + + Changeset c2 = result.getChangesets().get(1); + + assertNotNull(c2); + assertEquals("2:79b6baf49711", c2.getId()); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetAllWithLimit() throws IOException, RepositoryException + { + LogCommandRequest request = new LogCommandRequest(); + + request.setPagingLimit(2); + + ChangesetPagingResult result = + new HgLogCommand(handler, new HgContext(), repository, + repositoryDirectory).getChangesets(request); + + assertNotNull(result); + assertEquals(5, result.getTotal()); + assertEquals(2, result.getChangesets().size()); + + Changeset c1 = result.getChangesets().get(0); + + assertNotNull(c1); + assertEquals("4:2baab8e80280", c1.getId()); + + Changeset c2 = result.getChangesets().get(1); + + assertNotNull(c2); + assertEquals("3:542bf4893dd2", c2.getId()); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetCommit() throws IOException, RepositoryException + { + HgLogCommand command = new HgLogCommand(handler, new HgContext(), + repository, repositoryDirectory); + Changeset c = command.getChangeset("a9bacaf1b7fa"); + + assertNotNull(c); + assertEquals("0:a9bacaf1b7fa", c.getId()); + assertEquals("added a and b files", c.getDescription()); + checkDate(c.getDate()); + assertEquals("Douglas Adams", c.getAuthor().getName()); + assertEquals("douglas.adams@hitchhiker.com", c.getAuthor().getMail()); + assertEquals("added a and b files", c.getDescription()); + + Modifications mods = c.getModifications(); + + assertNotNull(mods); + assertTrue("modified list should be empty", mods.getModified().isEmpty()); + assertTrue("removed list should be empty", mods.getRemoved().isEmpty()); + assertFalse("added list should not be empty", mods.getAdded().isEmpty()); + assertEquals(2, mods.getAdded().size()); + assertThat(mods.getAdded(), contains("a.txt", "b.txt")); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetRange() throws IOException, RepositoryException + { + LogCommandRequest request = new LogCommandRequest(); + + request.setStartChangeset("3049df33fdbb"); + request.setEndChangeset("a9bacaf1b7fa"); + + ChangesetPagingResult result = + new HgLogCommand(handler, new HgContext(), repository, + repositoryDirectory).getChangesets(request); + + assertNotNull(result); + assertEquals(2, result.getTotal()); + assertEquals(2, result.getChangesets().size()); + + Changeset c1 = result.getChangesets().get(0); + Changeset c2 = result.getChangesets().get(1); + + assertNotNull(c1); + assertEquals("1:3049df33fdbb", c1.getId()); + assertNotNull(c2); + assertEquals("0:a9bacaf1b7fa", c2.getId()); + } +} diff --git a/scm-plugins/scm-hg-plugin/src/test/resources/META-INF/services/sonia.scm.SCMContextProvider b/scm-plugins/scm-hg-plugin/src/test/resources/META-INF/services/sonia.scm.SCMContextProvider new file mode 100644 index 0000000000..64643da7e5 --- /dev/null +++ b/scm-plugins/scm-hg-plugin/src/test/resources/META-INF/services/sonia.scm.SCMContextProvider @@ -0,0 +1 @@ +sonia.scm.repository.TempSCMContextProvider \ No newline at end of file diff --git a/scm-plugins/scm-hg-plugin/src/test/resources/sonia/scm/repository/spi/scm-hg-spi-test.zip b/scm-plugins/scm-hg-plugin/src/test/resources/sonia/scm/repository/spi/scm-hg-spi-test.zip new file mode 100644 index 0000000000..4896adc9de Binary files /dev/null and b/scm-plugins/scm-hg-plugin/src/test/resources/sonia/scm/repository/spi/scm-hg-spi-test.zip differ diff --git a/scm-plugins/scm-svn-plugin/pom.xml b/scm-plugins/scm-svn-plugin/pom.xml index 9bb9a7e32c..1bfd63b639 100644 --- a/scm-plugins/scm-svn-plugin/pom.xml +++ b/scm-plugins/scm-svn-plugin/pom.xml @@ -6,12 +6,12 @@ scm-plugins sonia.scm.plugins - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm.plugins scm-svn-plugin - 1.17-SNAPSHOT + 1.18-SNAPSHOT scm-svn-plugin https://bitbucket.org/sdorra/scm-manager Plugin for the version control system Subversion @@ -48,7 +48,7 @@ sonia.scm scm-test - 1.17-SNAPSHOT + 1.18-SNAPSHOT test diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/Compatibility.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/Compatibility.java index 3ff8438725..69ba6e2904 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/Compatibility.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/Compatibility.java @@ -39,8 +39,11 @@ package sonia.scm.repository; */ public enum Compatibility { - NONE(false, false, false), PRE14(true, true, true), PRE15(false, true, true), - PRE16(false, false, true); + NONE(false, false, false, false, false), + PRE14(true, true, true, true, false), PRE15(false, true, true, true, false), + PRE16(false, false, true, true, false), + PRE17(false, false, false, true, false), + WITH17(false, false, false, false, true); /** * Field description @@ -48,13 +51,18 @@ public enum Compatibility * @param pre14Compatible * @param pre15Compatible * @param pre16Compatible + * @param pre17Compatible + * @param with17Compatible */ private Compatibility(boolean pre14Compatible, boolean pre15Compatible, - boolean pre16Compatible) + boolean pre16Compatible, boolean pre17Compatible, + boolean with17Compatible) { this.pre14Compatible = pre14Compatible; this.pre15Compatible = pre15Compatible; this.pre16Compatible = pre16Compatible; + this.pre17Compatible = pre17Compatible; + this.with17Compatible = with17Compatible; } //~--- get methods ---------------------------------------------------------- @@ -92,6 +100,28 @@ public enum Compatibility return pre16Compatible; } + /** + * Method description + * + * + * @return + */ + public boolean isPre17Compatible() + { + return pre17Compatible; + } + + /** + * Method description + * + * + * @return + */ + public boolean isWith17Compatible() + { + return with17Compatible; + } + //~--- fields --------------------------------------------------------------- /** Field description */ @@ -102,4 +132,10 @@ public enum Compatibility /** Field description */ private boolean pre16Compatible; + + /** Field description */ + private boolean pre17Compatible; + + /** Field description */ + private boolean with17Compatible; } diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHandler.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHandler.java index 2254e94941..a33c8613e9 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHandler.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHandler.java @@ -293,7 +293,9 @@ public class SvnRepositoryHandler log.append(directory.getName()).append("\": pre14Compatible="); log.append(comp.isPre14Compatible()).append(", pre15Compatible="); log.append(comp.isPre15Compatible()).append(", pre16Compatible="); - log.append(comp.isPre16Compatible()); + log.append(comp.isPre16Compatible()).append(", pre17Compatible="); + log.append(comp.isPre17Compatible()).append(", with17Compatible="); + log.append(comp.isWith17Compatible()); logger.debug(log.toString()); } @@ -303,7 +305,8 @@ public class SvnRepositoryHandler { SVNURL url = SVNRepositoryFactory.createLocalRepository(directory, null, true, false, comp.isPre14Compatible(), - comp.isPre15Compatible(), comp.isPre16Compatible()); + comp.isPre15Compatible(), comp.isPre16Compatible(), + comp.isPre17Compatible(), comp.isWith17Compatible()); svnRepository = SVNRepositoryFactory.create(url); diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnUtil.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnUtil.java index 20491121ef..7d1c533d2e 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnUtil.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnUtil.java @@ -101,6 +101,11 @@ public class SvnUtil public static void appendModification(Modifications modifications, char type, String path) { + if (path.startsWith("/")) + { + path = path.substring(1); + } + switch (type) { case SVNLogEntryPath.TYPE_ADDED : @@ -198,4 +203,36 @@ public class SvnUtil } } } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param revision + * + * @return + * + * @throws RepositoryException + */ + public static long getRevisionNumber(String revision) + throws RepositoryException + { + long revisionNumber = -1; + + if (Util.isNotEmpty(revision)) + { + try + { + revisionNumber = Long.parseLong(revision); + } + catch (NumberFormatException ex) + { + throw new RepositoryException("given revision is not a svnrevision"); + } + } + + return revisionNumber; + } } diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/AbstractSvnCommand.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/AbstractSvnCommand.java new file mode 100644 index 0000000000..0cc80a8e92 --- /dev/null +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/AbstractSvnCommand.java @@ -0,0 +1,88 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.io.SVNRepository; +import org.tmatesoft.svn.core.io.SVNRepositoryFactory; + +import sonia.scm.repository.Repository; + +/** + * + * @author Sebastian Sdorra + */ +public class AbstractSvnCommand +{ + + /** + * Constructs ... + * + * + * + * @param context + * @param repository + * @param repositoryDirectory + */ + protected AbstractSvnCommand(SvnContext context, Repository repository) + { + this.context = context; + this.repository = repository; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @return + * + * @throws SVNException + */ + public SVNRepository open() throws SVNException + { + return context.open(); + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + protected SvnContext context; + + /** Field description */ + protected Repository repository; +} diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnBlameCommand.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnBlameCommand.java new file mode 100644 index 0000000000..9c059d0ea5 --- /dev/null +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnBlameCommand.java @@ -0,0 +1,134 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.collect.Lists; + +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager; +import org.tmatesoft.svn.core.io.SVNRepository; +import org.tmatesoft.svn.core.io.SVNRepositoryFactory; +import org.tmatesoft.svn.core.wc.SVNLogClient; +import org.tmatesoft.svn.core.wc.SVNRevision; + +import sonia.scm.repository.BlameLine; +import sonia.scm.repository.BlameResult; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryException; +import sonia.scm.repository.SvnBlameHandler; +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; +import java.io.IOException; + +import java.util.List; + +/** + * + * @author Sebastian Sdorra + */ +public class SvnBlameCommand extends AbstractSvnCommand implements BlameCommand +{ + + /** + * Constructs ... + * + * + * + * @param context + * @param repository + * @param repositoryDirectory + */ + public SvnBlameCommand(SvnContext context, Repository repository) + { + super(context, repository); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param request + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public BlameResult getBlameResult(BlameCommandRequest request) + throws IOException, RepositoryException + { + String path = request.getPath(); + String revision = request.getRevision(); + List blameLines = Lists.newArrayList(); + SVNRevision endRevision = null; + + if (Util.isNotEmpty(revision)) + { + endRevision = SVNRevision.create(Long.parseLong(revision)); + } + else + { + endRevision = SVNRevision.HEAD; + } + + try + { + SVNURL svnurl = SVNURL.fromFile(new File(context.getDirectory(), path)); + SVNRepository svnRepository = + SVNRepositoryFactory.create(context.createUrl()); + ISVNAuthenticationManager svnManager = + svnRepository.getAuthenticationManager(); + SVNLogClient svnLogClient = new SVNLogClient(svnManager, null); + + svnLogClient.doAnnotate(svnurl, SVNRevision.UNDEFINED, + SVNRevision.create(1l), endRevision, + new SvnBlameHandler(svnRepository, path, + blameLines)); + } + catch (SVNException ex) + { + throw new RepositoryException("could not create blame result", ex); + } + + return new BlameResult(blameLines.size(), blameLines); + } +} diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnBrowseCommand.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnBrowseCommand.java new file mode 100644 index 0000000000..d1cea1a511 --- /dev/null +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnBrowseCommand.java @@ -0,0 +1,230 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.tmatesoft.svn.core.SVNDirEntry; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNNodeKind; +import org.tmatesoft.svn.core.SVNProperties; +import org.tmatesoft.svn.core.SVNProperty; +import org.tmatesoft.svn.core.io.SVNRepository; + +import sonia.scm.repository.BrowserResult; +import sonia.scm.repository.FileObject; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryException; +import sonia.scm.repository.SubRepository; +import sonia.scm.repository.SvnUtil; +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * + * @author Sebastian Sdorra + */ +public class SvnBrowseCommand extends AbstractSvnCommand + implements BrowseCommand +{ + + /** + * the logger for SvnBrowseCommand + */ + private static final Logger logger = + LoggerFactory.getLogger(SvnBrowseCommand.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * + * @param context + * @param repository + * @param repositoryDirectory + */ + SvnBrowseCommand(SvnContext context, Repository repository) + { + super(context, repository); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param request + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public BrowserResult getBrowserResult(BrowseCommandRequest request) + throws IOException, RepositoryException + { + String path = request.getPath(); + long revisionNumber = SvnUtil.getRevisionNumber(request.getRevision()); + + if (logger.isDebugEnabled()) + { + logger.debug("browser repository {} in path {} at revision {}", + new Object[] { repository.getName(), + path, revisionNumber }); + } + + BrowserResult result = null; + + try + { + SVNRepository svnRepository = open(); + Collection entries = + svnRepository.getDir(Util.nonNull(path), revisionNumber, null, + (Collection) null); + List children = new ArrayList(); + String basePath = Util.EMPTY_STRING; + + if (Util.isNotEmpty(path)) + { + basePath = path; + + if (!basePath.endsWith("/")) + { + basePath = basePath.concat("/"); + } + } + + for (SVNDirEntry entry : entries) + { + children.add(createFileObject(svnRepository, revisionNumber, entry, + basePath)); + } + + result = new BrowserResult(); + result.setRevision(String.valueOf(revisionNumber)); + result.setFiles(children); + } + catch (SVNException ex) + { + logger.error("could not open repository", ex); + } + + return result; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * + * @param repository + * @param revision + * @param entry + * @param path + * + * @return + */ + private FileObject createFileObject(SVNRepository repository, long revision, + SVNDirEntry entry, String path) + { + FileObject fileObject = new FileObject(); + + fileObject.setName(entry.getName()); + fileObject.setPath(path.concat(entry.getRelativePath())); + fileObject.setDirectory(entry.getKind() == SVNNodeKind.DIR); + + if (entry.getDate() != null) + { + fileObject.setLastModified(entry.getDate().getTime()); + } + + fileObject.setLength(entry.getSize()); + fileObject.setDescription(entry.getCommitMessage()); + + if (fileObject.isDirectory() && entry.hasProperties()) + { + fetchExternalsProperty(repository, revision, entry, fileObject); + } + + return fileObject; + } + + /** + * Method description + * + * + * @param repository + * @param revision + * @param entry + * @param fileObject + */ + private void fetchExternalsProperty(SVNRepository repository, long revision, + SVNDirEntry entry, FileObject fileObject) + { + try + { + SVNProperties properties = new SVNProperties(); + + repository.getFile(entry.getRelativePath(), revision, properties, null); + + String externals = properties.getStringValue(SVNProperty.EXTERNALS); + + if (Util.isNotEmpty(externals)) + { + SubRepository subRepository = new SubRepository(externals); + + fileObject.setSubRepository(subRepository); + } + } + catch (SVNException ex) + { + logger.error("could not fetch file properties"); + } + } +} diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnCatCommand.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnCatCommand.java new file mode 100644 index 0000000000..5acbe5966f --- /dev/null +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnCatCommand.java @@ -0,0 +1,117 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNProperties; +import org.tmatesoft.svn.core.io.SVNRepository; + +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryException; +import sonia.scm.repository.SvnUtil; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; +import java.io.OutputStream; + +/** + * + * @author Sebastian Sdorra + */ +public class SvnCatCommand extends AbstractSvnCommand implements CatCommand +{ + + /** + * the logger for SvnCatCommand + */ + private static final Logger logger = + LoggerFactory.getLogger(SvnCatCommand.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * + * @param context + * @param repository + * @param repositoryDirectory + */ + SvnCatCommand(SvnContext context, Repository repository) + { + super(context, repository); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param request + * @param output + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public void getCatResult(CatCommandRequest request, OutputStream output) + throws IOException, RepositoryException + { + if (logger.isDebugEnabled()) + { + logger.debug("try to get content for {}", request); + } + + long revisionNumber = SvnUtil.getRevisionNumber(request.getRevision()); + + try + { + SVNRepository svnRepository = open(); + + svnRepository.getFile(request.getPath(), revisionNumber, + new SVNProperties(), output); + } + catch (SVNException ex) + { + logger.error("could not open repository", ex); + } + } +} diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnContext.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnContext.java new file mode 100644 index 0000000000..3a04ec1a2d --- /dev/null +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnContext.java @@ -0,0 +1,154 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.io.SVNRepository; +import org.tmatesoft.svn.core.io.SVNRepositoryFactory; + +import sonia.scm.repository.SvnUtil; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.Closeable; +import java.io.File; +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + */ +public class SvnContext implements Closeable +{ + + /** + * the logger for SvnContext + */ + private static final Logger logger = + LoggerFactory.getLogger(SvnContext.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param directory + */ + public SvnContext(File directory) + { + this.directory = directory; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @throws IOException + */ + @Override + public void close() throws IOException + { + if (logger.isTraceEnabled()) + { + logger.trace("close svn repository {}", directory); + } + + SvnUtil.closeSession(repository); + } + + /** + * Method description + * + * + * @return + * + * @throws SVNException + */ + public SVNURL createUrl() throws SVNException + { + return SVNURL.fromFile(directory); + } + + /** + * Method description + * + * + * @return + * + * @throws SVNException + */ + public SVNRepository open() throws SVNException + { + if (repository == null) + { + if (logger.isTraceEnabled()) + { + logger.trace("open svn repository {}", directory); + } + + repository = SVNRepositoryFactory.create(createUrl()); + } + + return repository; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + public File getDirectory() + { + return directory; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private File directory; + + /** Field description */ + private SVNRepository repository; +} diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnDiffCommand.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnDiffCommand.java new file mode 100644 index 0000000000..8990240223 --- /dev/null +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnDiffCommand.java @@ -0,0 +1,157 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Preconditions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.tmatesoft.svn.core.SVNDepth; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.wc.DefaultSVNDiffGenerator; +import org.tmatesoft.svn.core.wc.ISVNDiffGenerator; +import org.tmatesoft.svn.core.wc.SVNClientManager; +import org.tmatesoft.svn.core.wc.SVNDiffClient; +import org.tmatesoft.svn.core.wc.SVNRevision; + +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryException; +import sonia.scm.repository.SvnUtil; +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; + +/** + * + * @author Sebastian Sdorra + */ +public class SvnDiffCommand extends AbstractSvnCommand implements DiffCommand +{ + + /** + * the logger for SvnDiffCommand + */ + private static final Logger logger = + LoggerFactory.getLogger(SvnDiffCommand.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * + * @param context + * @param repository + * @param repositoryDirectory + */ + public SvnDiffCommand(SvnContext context, Repository repository) + { + super(context, repository); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param request + * @param output + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public void getDiffResult(DiffCommandRequest request, OutputStream output) + throws IOException, RepositoryException + { + if (logger.isDebugEnabled()) + { + logger.debug("create diff for {}", request); + } + + Preconditions.checkNotNull(request, "request is required"); + Preconditions.checkNotNull(output, "outputstream is required"); + + String path = request.getPath(); + SVNClientManager clientManager = null; + + try + { + SVNURL svnurl = context.createUrl(); + + if (Util.isNotEmpty(path)) + { + svnurl = svnurl.appendPath(path, true); + } + + clientManager = SVNClientManager.newInstance(); + + SVNDiffClient diffClient = clientManager.getDiffClient(); + ISVNDiffGenerator diffGenerator = diffClient.getDiffGenerator(); + + if (diffGenerator == null) + { + diffGenerator = new DefaultSVNDiffGenerator(); + } + + diffGenerator.setDiffAdded(true); + diffGenerator.setDiffDeleted(true); + diffClient.setDiffGenerator(diffGenerator); + + long currentRev = SvnUtil.getRevisionNumber(request.getRevision()); + + diffClient.doDiff(svnurl, SVNRevision.HEAD, + SVNRevision.create(currentRev - 1), + SVNRevision.create(currentRev), SVNDepth.INFINITY, + false, output); + } + catch (SVNException ex) + { + throw new RepositoryException("could not create diff", ex); + } + finally + { + SvnUtil.dispose(clientManager); + } + } +} diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnLogCommand.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnLogCommand.java new file mode 100644 index 0000000000..74b1eb5566 --- /dev/null +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnLogCommand.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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Strings; +import com.google.common.collect.Lists; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNLogEntry; +import org.tmatesoft.svn.core.io.SVNRepository; + +import sonia.scm.repository.Changeset; +import sonia.scm.repository.ChangesetPagingResult; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryException; +import sonia.scm.repository.SvnUtil; +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +import java.util.Collection; +import java.util.List; + +/** + * + * @author Sebastian Sdorra + */ +public class SvnLogCommand extends AbstractSvnCommand implements LogCommand +{ + + /** + * the logger for SvnLogCommand + */ + private static final Logger logger = + LoggerFactory.getLogger(SvnLogCommand.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * + * @param context + * @param repository + * @param repositoryDirectory + */ + SvnLogCommand(SvnContext context, Repository repository) + { + super(context, repository); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param revision + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public Changeset getChangeset(String revision) + throws IOException, RepositoryException + { + Changeset changeset = null; + + if (logger.isDebugEnabled()) + { + logger.debug("fetch changeset {}", revision); + } + + try + { + long revisioNumber = Long.parseLong(revision); + SVNRepository repository = open(); + Collection entries = repository.log(null, null, + revisioNumber, revisioNumber, true, + true); + + if (Util.isNotEmpty(entries)) + { + changeset = SvnUtil.createChangeset(entries.iterator().next()); + } + } + catch (NumberFormatException ex) + { + throw new RepositoryException("could not convert revision", ex); + } + catch (SVNException ex) + { + throw new RepositoryException("could not open repository", ex); + } + + return changeset; + } + + /** + * Method description + * + * + * @param request + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public ChangesetPagingResult getChangesets(LogCommandRequest request) + throws IOException, RepositoryException + { + if (logger.isDebugEnabled()) + { + logger.debug("fetch changesets for {}", request); + } + + ChangesetPagingResult changesets = null; + String startRevision = request.getStartChangeset(); + String endRevision = request.getEndChangeset(); + + try + { + SVNRepository repository = open(); + long startRev = repository.getLatestRevision(); + long endRev = 0; + long maxRev = startRev; + + if (!Strings.isNullOrEmpty(startRevision)) + { + startRev = Long.parseLong(startRevision); + } + + if (!Strings.isNullOrEmpty(endRevision)) + { + endRev = Long.parseLong(endRevision); + } + + String[] pathArray = null; + + if (!Strings.isNullOrEmpty(request.getPath())) + { + pathArray = new String[] { request.getPath() }; + } + + List changesetList = Lists.newArrayList(); + Collection entries = repository.log(pathArray, null, + startRev, endRev, true, true); + + for (SVNLogEntry entry : entries) + { + if (entry.getRevision() <= maxRev) + { + changesetList.add(SvnUtil.createChangeset(entry)); + } + } + + int total = changesetList.size(); + int start = request.getPagingStart(); + int max = request.getPagingLimit() + start; + int end = total; + + if (end > max) + { + end = max; + } + + if (start < 0) + { + start = 0; + } + + changesetList = Lists.newArrayList(changesetList.subList(start, end)); + changesets = new ChangesetPagingResult(total, changesetList); + } + catch (NumberFormatException ex) + { + throw new RepositoryException( + "could not parse revision ".concat(startRevision), ex); + } + catch (SVNException ex) + { + throw new RepositoryException("could not open repository", ex); + } + + return changesets; + } +} diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceProvider.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceProvider.java new file mode 100644 index 0000000000..eb260209dc --- /dev/null +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceProvider.java @@ -0,0 +1,156 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.collect.ImmutableSet; + +import sonia.scm.repository.Repository; +import sonia.scm.repository.SvnRepositoryHandler; +import sonia.scm.repository.api.Command; + +//~--- JDK imports ------------------------------------------------------------ + +import java.util.Set; + +/** + * + * @author Sebastian Sdorra + */ +public class SvnRepositoryServiceProvider extends RepositoryServiceProvider +{ + + /** Field description */ + private static final Set COMMANDS = ImmutableSet.of(Command.BLAME, + Command.BROWSE, Command.CAT, + Command.DIFF, Command.LOG); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param handler + * @param repository + */ + SvnRepositoryServiceProvider(SvnRepositoryHandler handler, + Repository repository) + { + this.repository = repository; + this.context = new SvnContext(handler.getDirectory(repository)); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + public SvnBlameCommand getBlameCommand() + { + return new SvnBlameCommand(context, repository); + } + + /** + * Method description + * + * + * @return + */ + @Override + public SvnBrowseCommand getBrowseCommand() + { + return new SvnBrowseCommand(context, repository); + } + + /** + * Method description + * + * + * @return + */ + @Override + public SvnCatCommand getCatCommand() + { + return new SvnCatCommand(context, repository); + } + + /** + * Method description + * + * + * @return + */ + @Override + public SvnDiffCommand getDiffCommand() + { + return new SvnDiffCommand(context, repository); + } + + /** + * Method description + * + * + * @return + */ + @Override + public SvnLogCommand getLogCommand() + { + return new SvnLogCommand(context, repository); + } + + /** + * Method description + * + * + * @return + */ + @Override + public Set getSupportedCommands() + { + return COMMANDS; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private SvnContext context; + + /** Field description */ + private Repository repository; +} diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceResolver.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceResolver.java new file mode 100644 index 0000000000..cf01df8f84 --- /dev/null +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceResolver.java @@ -0,0 +1,95 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.inject.Inject; + +import sonia.scm.plugin.ext.Extension; +import sonia.scm.repository.Repository; +import sonia.scm.repository.SvnRepositoryHandler; + +/** + * + * @author Sebastian Sdorra + */ +@Extension +public class SvnRepositoryServiceResolver implements RepositoryServiceResolver +{ + + /** Field description */ + public static final String TYPE = "svn"; + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param handler + */ + @Inject + public SvnRepositoryServiceResolver(SvnRepositoryHandler handler) + { + this.handler = handler; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param repository + * + * @return + */ + @Override + public SvnRepositoryServiceProvider reslove(Repository repository) + { + SvnRepositoryServiceProvider provider = null; + + if (TYPE.equalsIgnoreCase(repository.getType())) + { + provider = new SvnRepositoryServiceProvider(handler, repository); + } + + return provider; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private SvnRepositoryHandler handler; +} diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnGZipFilter.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnGZipFilter.java index 0daa5d6af8..2267673e3f 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnGZipFilter.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnGZipFilter.java @@ -1,34 +1,35 @@ /** - * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * 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 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. + * 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.web; //~--- non-JDK imports -------------------------------------------------------- diff --git a/scm-plugins/scm-svn-plugin/src/main/resources/sonia/scm/svn.config.js b/scm-plugins/scm-svn-plugin/src/main/resources/sonia/scm/svn.config.js index 5cc3339c78..1359b71696 100644 --- a/scm-plugins/scm-svn-plugin/src/main/resources/sonia/scm/svn.config.js +++ b/scm-plugins/scm-svn-plugin/src/main/resources/sonia/scm/svn.config.js @@ -40,6 +40,8 @@ Sonia.svn.ConfigPanel = Ext.extend(Sonia.config.SimpleConfigForm, { pre14CompatibleText: 'Pre 1.4 Compatible', pre15CompatibleText: 'Pre 1.5 Compatible', pre16CompatibleText: 'Pre 1.6 Compatible', + pre17CompatibleText: 'Pre 1.7 Compatible', + with17CompatibleText: 'With 1.7 Compatible', enableGZipText: 'Enable GZip Encoding', disabledText: 'Disabled', @@ -80,6 +82,14 @@ Sonia.svn.ConfigPanel = Ext.extend(Sonia.config.SimpleConfigForm, { boxLabel: this.pre16CompatibleText, inputValue: 'PRE16', name: 'compatibility' + },{ + boxLabel: this.pre17CompatibleText, + inputValue: 'PRE17', + name: 'compatibility' + },{ + boxLabel: this.with17CompatibleText, + inputValue: 'WITH17', + name: 'compatibility' }] },{ xtype: 'checkbox', @@ -117,6 +127,8 @@ if ( i18n != null && i18n.country == 'de' ){ pre14CompatibleText: 'Mit Versionen vor 1.4 kompatibel', pre15CompatibleText: 'Mit Versionen vor 1.5 kompatibel', pre16CompatibleText: 'Mit Versionen vor 1.6 kompatibel', + pre17CompatibleText: 'Mit Versionen vor 1.7 kompatibel', + with17CompatibleText: 'Mit Version 1.7 kompatibel', disabledText: 'Deaktivieren', // helpTexts diff --git a/scm-plugins/scm-svn-plugin/src/main/resources/sonia/scm/version/scm-svn-plugin b/scm-plugins/scm-svn-plugin/src/main/resources/sonia/scm/version/scm-svn-plugin index 76ed46fd46..76fa1f0105 100644 --- a/scm-plugins/scm-svn-plugin/src/main/resources/sonia/scm/version/scm-svn-plugin +++ b/scm-plugins/scm-svn-plugin/src/main/resources/sonia/scm/version/scm-svn-plugin @@ -1 +1 @@ -scm-svn-plugin/${project.version} svnkit/${svnkit-dav.version} \ No newline at end of file +scm-svn-plugin/${project.version} svnkit/${svnkit.version} \ No newline at end of file diff --git a/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/AbstractSvnCommandTestBase.java b/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/AbstractSvnCommandTestBase.java new file mode 100644 index 0000000000..81b55e5db3 --- /dev/null +++ b/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/AbstractSvnCommandTestBase.java @@ -0,0 +1,111 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.After; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + */ +public class AbstractSvnCommandTestBase extends ZippedRepositoryTestBase +{ + + /** + * Method description + * + * + * @throws IOException + */ + @After + public void close() throws IOException + { + if (context != null) + { + context.close(); + } + } + + /** + * Method description + * + * + * @return + */ + public SvnContext createContext() + { + if (context == null) + { + context = new SvnContext(repositoryDirectory); + } + + return context; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + protected String getType() + { + return "svn"; + } + + /** + * Method description + * + * + * @return + */ + @Override + protected String getZippedRepositoryResource() + { + return "sonia/scm/repository/spi/scm-svn-spi-test.zip"; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private SvnContext context; +} diff --git a/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/SvnBlameCommandTest.java b/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/SvnBlameCommandTest.java new file mode 100644 index 0000000000..e320dd3251 --- /dev/null +++ b/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/SvnBlameCommandTest.java @@ -0,0 +1,141 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.Test; + +import sonia.scm.repository.BlameLine; +import sonia.scm.repository.BlameResult; +import sonia.scm.repository.RepositoryException; + +import static org.junit.Assert.*; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + */ +public class SvnBlameCommandTest extends AbstractSvnCommandTestBase +{ + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetBlameResult() throws IOException, RepositoryException + { + BlameCommandRequest request = new BlameCommandRequest(); + + request.setPath("a.txt"); + + BlameResult result = createCommand().getBlameResult(request); + + assertNotNull(result); + assertEquals(2, result.getTotal()); + + BlameLine line = result.getLine(0); + + checkFirstLine(line); + line = result.getLine(1); + assertEquals(2, line.getLineNumber()); + assertEquals("5", line.getRevision()); + checkDate(line.getWhen()); + assertEquals("line for blame test", line.getCode()); + assertEquals("added line for blame test", line.getDescription()); + assertEquals("zaphod", line.getAuthor().getName()); + assertNull(line.getAuthor().getMail()); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetBlameResultWithRevision() + throws IOException, RepositoryException + { + BlameCommandRequest request = new BlameCommandRequest(); + + request.setPath("a.txt"); + request.setRevision("3"); + + BlameResult result = createCommand().getBlameResult(request); + + assertNotNull(result); + assertEquals(1, result.getTotal()); + + BlameLine line = result.getLine(0); + + checkFirstLine(line); + } + + /** + * Method description + * + * + * @param line + */ + private void checkFirstLine(BlameLine line) + { + assertEquals(1, line.getLineNumber()); + assertEquals("3", line.getRevision()); + checkDate(line.getWhen()); + assertEquals("a and b", line.getCode()); + assertEquals("remove b and modified a", line.getDescription()); + assertEquals("perfect", line.getAuthor().getName()); + assertNull(line.getAuthor().getMail()); + } + + /** + * Method description + * + * + * @return + */ + private SvnBlameCommand createCommand() + { + return new SvnBlameCommand(createContext(), repository); + } +} diff --git a/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/SvnBrowseCommandTest.java b/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/SvnBrowseCommandTest.java new file mode 100644 index 0000000000..e59b878d5c --- /dev/null +++ b/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/SvnBrowseCommandTest.java @@ -0,0 +1,172 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.Test; + +import sonia.scm.repository.BrowserResult; +import sonia.scm.repository.FileObject; +import sonia.scm.repository.RepositoryException; + +import static org.junit.Assert.*; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +import java.util.List; + +/** + * + * @author Sebastian Sdorra + */ +public class SvnBrowseCommandTest extends AbstractSvnCommandTestBase +{ + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testBrowse() throws IOException, RepositoryException + { + BrowserResult result = + createCommand().getBrowserResult(new BrowseCommandRequest()); + + assertNotNull(result); + + List foList = result.getFiles(); + + assertNotNull(foList); + assertFalse(foList.isEmpty()); + assertEquals(2, foList.size()); + + FileObject a = null; + FileObject c = null; + + for (FileObject f : foList) + { + if ("a.txt".equals(f.getName())) + { + a = f; + } + else if ("c".equals(f.getName())) + { + c = f; + } + } + + assertNotNull(a); + assertFalse(a.isDirectory()); + assertEquals("a.txt", a.getName()); + assertEquals("a.txt", a.getPath()); + assertEquals("added line for blame test", a.getDescription()); + assertTrue(a.getLength() > 0); + checkDate(a.getLastModified()); + assertNotNull(c); + assertTrue(c.isDirectory()); + assertEquals("c", c.getName()); + assertEquals("c", c.getPath()); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testBrowseSubDirectory() throws IOException, RepositoryException + { + BrowseCommandRequest request = new BrowseCommandRequest(); + + request.setPath("c"); + + BrowserResult result = createCommand().getBrowserResult(request); + + assertNotNull(result); + + List foList = result.getFiles(); + + assertNotNull(foList); + assertFalse(foList.isEmpty()); + assertEquals(2, foList.size()); + + FileObject d = null; + FileObject e = null; + + for (FileObject f : foList) + { + if ("d.txt".equals(f.getName())) + { + d = f; + } + else if ("e.txt".equals(f.getName())) + { + e = f; + } + } + + assertNotNull(d); + assertFalse(d.isDirectory()); + assertEquals("d.txt", d.getName()); + assertEquals("c/d.txt", d.getPath()); + assertEquals("added d and e in folder c", d.getDescription()); + assertTrue(d.getLength() > 0); + checkDate(d.getLastModified()); + assertNotNull(e); + assertFalse(e.isDirectory()); + assertEquals("e.txt", e.getName()); + assertEquals("c/e.txt", e.getPath()); + assertEquals("added d and e in folder c", e.getDescription()); + assertTrue(e.getLength() > 0); + checkDate(e.getLastModified()); + } + + /** + * Method description + * + * + * @return + */ + private SvnBrowseCommand createCommand() + { + return new SvnBrowseCommand(createContext(), repository); + } +} diff --git a/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/SvnCatCommandTest.java b/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/SvnCatCommandTest.java new file mode 100644 index 0000000000..198a55edf3 --- /dev/null +++ b/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/SvnCatCommandTest.java @@ -0,0 +1,117 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.Test; + +import sonia.scm.repository.RepositoryException; + +import static org.junit.Assert.*; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + */ +public class SvnCatCommandTest extends AbstractSvnCommandTestBase +{ + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testCat() throws IOException, RepositoryException + { + CatCommandRequest request = new CatCommandRequest(); + + request.setPath("a.txt"); + request.setRevision("1"); + assertEquals("a", execute(request)); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testSimpleCat() throws IOException, RepositoryException + { + CatCommandRequest request = new CatCommandRequest(); + + request.setPath("c/d.txt"); + assertEquals("d", execute(request)); + } + + /** + * Method description + * + * + * @param request + * + * @return + * + * @throws IOException + * @throws RepositoryException + */ + private String execute(CatCommandRequest request) + throws IOException, RepositoryException + { + String content = null; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + try + { + new SvnCatCommand(createContext(), repository).getCatResult(request, + baos); + } + finally + { + content = baos.toString().trim(); + } + + return content; + } +} diff --git a/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/SvnLogCommandTest.java b/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/SvnLogCommandTest.java new file mode 100644 index 0000000000..a3942bd0f4 --- /dev/null +++ b/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/spi/SvnLogCommandTest.java @@ -0,0 +1,231 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.Test; + +import sonia.scm.repository.Changeset; +import sonia.scm.repository.ChangesetPagingResult; +import sonia.scm.repository.Modifications; +import sonia.scm.repository.RepositoryException; + +import static org.junit.Assert.*; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +/** + * + * @author Sebastian Sdorra + */ +public class SvnLogCommandTest extends AbstractSvnCommandTestBase +{ + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetAll() throws IOException, RepositoryException + { + ChangesetPagingResult result = + createCommand().getChangesets(new LogCommandRequest()); + + assertNotNull(result); + assertEquals(6, result.getTotal()); + assertEquals(6, result.getChangesets().size()); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetAllByPath() throws IOException, RepositoryException + { + LogCommandRequest request = new LogCommandRequest(); + + request.setPath("a.txt"); + + ChangesetPagingResult result = createCommand().getChangesets(request); + + assertNotNull(result); + assertEquals(3, result.getTotal()); + assertEquals(3, result.getChangesets().size()); + assertEquals("5", result.getChangesets().get(0).getId()); + assertEquals("3", result.getChangesets().get(1).getId()); + assertEquals("1", result.getChangesets().get(2).getId()); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetAllWithLimit() throws IOException, RepositoryException + { + LogCommandRequest request = new LogCommandRequest(); + + request.setPagingLimit(2); + + ChangesetPagingResult result = createCommand().getChangesets(request); + + assertNotNull(result); + assertEquals(6, result.getTotal()); + assertEquals(2, result.getChangesets().size()); + + Changeset c1 = result.getChangesets().get(0); + + assertNotNull(c1); + assertEquals("5", c1.getId()); + + Changeset c2 = result.getChangesets().get(1); + + assertNotNull(c2); + assertEquals("4", c2.getId()); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetAllWithPaging() throws IOException, RepositoryException + { + LogCommandRequest request = new LogCommandRequest(); + + request.setPagingStart(1); + request.setPagingLimit(2); + + ChangesetPagingResult result = createCommand().getChangesets(request); + + assertNotNull(result); + assertEquals(6, result.getTotal()); + assertEquals(2, result.getChangesets().size()); + + Changeset c1 = result.getChangesets().get(0); + + assertNotNull(c1); + assertEquals("4", c1.getId()); + + Changeset c2 = result.getChangesets().get(1); + + assertNotNull(c2); + assertEquals("3", c2.getId()); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetCommit() throws IOException, RepositoryException + { + Changeset c = createCommand().getChangeset("3"); + + assertNotNull(c); + assertEquals("3", c.getId()); + assertEquals("remove b and modified a", c.getDescription()); + checkDate(c.getDate()); + assertEquals("perfect", c.getAuthor().getName()); + assertNull("douglas.adams@hitchhiker.com", c.getAuthor().getMail()); + + Modifications mods = c.getModifications(); + + assertNotNull(mods); + assertEquals(1, mods.getModified().size()); + assertEquals(1, mods.getRemoved().size()); + assertTrue("added list should be empty", mods.getAdded().isEmpty()); + assertEquals("a.txt", mods.getModified().get(0)); + assertEquals("b.txt", mods.getRemoved().get(0)); + } + + /** + * Method description + * + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetRange() throws IOException, RepositoryException + { + LogCommandRequest request = new LogCommandRequest(); + + request.setStartChangeset("2"); + request.setEndChangeset("1"); + + ChangesetPagingResult result = createCommand().getChangesets(request); + + assertNotNull(result); + assertEquals(2, result.getTotal()); + assertEquals(2, result.getChangesets().size()); + + Changeset c1 = result.getChangesets().get(0); + Changeset c2 = result.getChangesets().get(1); + + assertNotNull(c1); + assertEquals("2", c1.getId()); + assertNotNull(c2); + assertEquals("1", c2.getId()); + } + + /** + * Method description + * + * + * @return + */ + private SvnLogCommand createCommand() + { + return new SvnLogCommand(createContext(), repository); + } +} diff --git a/scm-plugins/scm-svn-plugin/src/test/resources/sonia/scm/repository/spi/scm-svn-spi-test.zip b/scm-plugins/scm-svn-plugin/src/test/resources/sonia/scm/repository/spi/scm-svn-spi-test.zip new file mode 100644 index 0000000000..6e27feef41 Binary files /dev/null and b/scm-plugins/scm-svn-plugin/src/test/resources/sonia/scm/repository/spi/scm-svn-spi-test.zip differ diff --git a/scm-samples/pom.xml b/scm-samples/pom.xml index def37d44c7..459bd98d7e 100644 --- a/scm-samples/pom.xml +++ b/scm-samples/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm.samples scm-samples pom - 1.17-SNAPSHOT + 1.18-SNAPSHOT scm-samples diff --git a/scm-samples/scm-sample-auth/pom.xml b/scm-samples/scm-sample-auth/pom.xml index 209ae3d930..4869d3f692 100644 --- a/scm-samples/scm-sample-auth/pom.xml +++ b/scm-samples/scm-sample-auth/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm.sample scm-sample-auth - 1.17-SNAPSHOT + 1.18-SNAPSHOT scm-sample-auth Sample Authentication Plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.17-SNAPSHOT + 1.18-SNAPSHOT diff --git a/scm-samples/scm-sample-hello/pom.xml b/scm-samples/scm-sample-hello/pom.xml index 8fc95b1024..26d772606f 100644 --- a/scm-samples/scm-sample-hello/pom.xml +++ b/scm-samples/scm-sample-hello/pom.xml @@ -6,12 +6,12 @@ scm-samples sonia.scm.samples - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm.sample scm-sample-hello - 1.17-SNAPSHOT + 1.18-SNAPSHOT scm-sample-hello A simple hello world plugin https://bitbucket.org/sdorra/scm-manager @@ -28,7 +28,7 @@ sonia.scm scm-core - 1.17-SNAPSHOT + 1.18-SNAPSHOT diff --git a/scm-server/pom.xml b/scm-server/pom.xml index 1d8862ff1c..b779966ddb 100644 --- a/scm-server/pom.xml +++ b/scm-server/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm scm-server - 1.17-SNAPSHOT + 1.18-SNAPSHOT scm-server jar diff --git a/scm-test/pom.xml b/scm-test/pom.xml index 3b8c0b9728..1c87e3e9d9 100644 --- a/scm-test/pom.xml +++ b/scm-test/pom.xml @@ -6,12 +6,12 @@ scm sonia.scm - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm scm-test - 1.17-SNAPSHOT + 1.18-SNAPSHOT scm-test @@ -25,7 +25,7 @@ sonia.scm scm-core - 1.17-SNAPSHOT + 1.18-SNAPSHOT diff --git a/scm-test/src/main/java/sonia/scm/cache/MapCache.java b/scm-test/src/main/java/sonia/scm/cache/MapCache.java new file mode 100644 index 0000000000..24a0d7622c --- /dev/null +++ b/scm-test/src/main/java/sonia/scm/cache/MapCache.java @@ -0,0 +1,154 @@ +/** + * 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.cache; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.collect.Maps; + +import sonia.scm.Filter; + +//~--- JDK imports ------------------------------------------------------------ + +import java.util.Map; + +/** + * + * @author Sebastian Sdorra + * @since 1.17 + * + * @param + * @param + */ +public class MapCache implements Cache +{ + + /** + * Method description + * + */ + @Override + public void clear() + { + map.clear(); + } + + /** + * Method description + * + * + * @param key + * + * @return + */ + @Override + public boolean contains(K key) + { + return map.containsKey(key); + } + + /** + * Method description + * + * + * @param key + * @param value + */ + @Override + public void put(K key, V value) + { + map.put(key, value); + } + + /** + * Method description + * + * + * @param key + * + * @return + */ + @Override + public boolean remove(K key) + { + return map.remove(key) != null; + } + + /** + * Method description + * + * + * @param filter + * + * @return + */ + @Override + public boolean removeAll(Filter filter) + { + boolean result = false; + + for (K key : map.keySet()) + { + if (filter.accept(key)) + { + if (remove(key)) + { + result = true; + } + } + } + + return result; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param key + * + * @return + */ + @Override + public V get(K key) + { + return map.get(key); + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private Map map = Maps.newHashMap(); +} diff --git a/scm-test/src/main/java/sonia/scm/cache/MapCacheManager.java b/scm-test/src/main/java/sonia/scm/cache/MapCacheManager.java new file mode 100644 index 0000000000..afc4580f99 --- /dev/null +++ b/scm-test/src/main/java/sonia/scm/cache/MapCacheManager.java @@ -0,0 +1,181 @@ +/** + * 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.cache; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Objects; +import com.google.common.collect.Maps; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +import java.util.Map; + +/** + * + * @author Sebastian Sdorra + * @since 1.17 + */ +public class MapCacheManager implements CacheManager +{ + + /** + * Method description + * + * + * @throws IOException + */ + @Override + public void close() throws IOException + { + + // do nothing + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param key + * @param value + * @param name + * @param + * @param + * + * @return + */ + @Override + public Cache getCache(Class key, Class value, String name) + { + CacheKey cacheKey = new CacheKey(key, value, name); + Cache cache = cacheMap.get(cacheKey); + + if (cache == null) + { + cache = new MapCache(); + cacheMap.put(cacheKey, cache); + } + + return cache; + } + + //~--- inner classes -------------------------------------------------------- + + /** + * Class description + * + * + * @version Enter version here..., 12/06/24 + * @author Enter your name here... + */ + private static class CacheKey + { + + /** + * Constructs ... + * + * + * @param key + * @param value + * @param name + */ + public CacheKey(Class key, Class value, String name) + { + this.key = key; + this.value = value; + this.name = name; + } + + //~--- methods ------------------------------------------------------------ + + /** + * Method description + * + * + * @param obj + * + * @return + */ + @Override + public boolean equals(Object obj) + { + if (obj == null) + { + return false; + } + + if (getClass() != obj.getClass()) + { + return false; + } + + final CacheKey other = (CacheKey) obj; + + return Objects.equal(key, other.key) && Objects.equal(value, other.value) + && Objects.equal(name, other.name); + } + + /** + * Method description + * + * + * @return + */ + @Override + public int hashCode() + { + return Objects.hashCode(key, value, name); + } + + //~--- fields ------------------------------------------------------------- + + /** Field description */ + private Class key; + + /** Field description */ + private String name; + + /** Field description */ + private Class value; + } + + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private Map cacheMap = Maps.newHashMap(); +} diff --git a/scm-test/src/main/java/sonia/scm/repository/spi/ZippedRepositoryTestBase.java b/scm-test/src/main/java/sonia/scm/repository/spi/ZippedRepositoryTestBase.java new file mode 100644 index 0000000000..f42fb0993b --- /dev/null +++ b/scm-test/src/main/java/sonia/scm/repository/spi/ZippedRepositoryTestBase.java @@ -0,0 +1,216 @@ +/** + * 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.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.io.Closeables; +import com.google.common.io.Resources; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.rules.TemporaryFolder; + +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryTestData; +import sonia.scm.util.IOUtil; + +import static org.junit.Assert.*; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import java.net.URL; + +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +/** + * + * @author Sebastian Sdorra + */ +public abstract class ZippedRepositoryTestBase +{ + + /** + * Method description + * + * + * @return + */ + protected abstract String getType(); + + /** + * Method description + * + * + * @return + */ + protected abstract String getZippedRepositoryResource(); + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + */ + @Before + public void before() + { + repositoryDirectory = createRepositoryDirectory(); + } + + /** + * Method description + * + * + * @param date + */ + protected void checkDate(Long date) + { + assertNotNull(date); + assertTrue("Date should not be older than current date", + date < System.currentTimeMillis()); + } + + /** + * Method description + * + * + * @return + */ + protected Repository createRepository() + { + return RepositoryTestData.createHeartOfGold(getType()); + } + + /** + * Method description + * + * + * @return + * + * @throws IOException + */ + protected File createRepositoryDirectory() + { + File folder = null; + + try + { + folder = tempFolder.newFolder(); + folder.mkdirs(); + extract(folder); + } + catch (IOException ex) + { + fail(ex.getMessage()); + } + + return folder; + } + + /** + * Method description + * + * + * @param folder + * + * @throws IOException + */ + private void extract(File folder) throws IOException + { + URL url = Resources.getResource(getZippedRepositoryResource()); + ZipInputStream zip = null; + + try + { + zip = new ZipInputStream(url.openStream()); + + ZipEntry entry = zip.getNextEntry(); + + while (entry != null) + { + File file = new File(folder, entry.getName()); + File parent = file.getParentFile(); + + if (!parent.exists()) + { + parent.mkdirs(); + } + + if (entry.isDirectory()) + { + file.mkdirs(); + } + else + { + OutputStream output = null; + + try + { + output = new FileOutputStream(file); + IOUtil.copy(zip, output); + } + finally + { + Closeables.closeQuietly(output); + } + } + + zip.closeEntry(); + entry = zip.getNextEntry(); + } + } + finally + { + Closeables.closeQuietly(zip); + } + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + @Rule + public TemporaryFolder tempFolder = new TemporaryFolder(); + + /** Field description */ + protected Repository repository = createRepository(); + + /** Field description */ + protected File repositoryDirectory; +} diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index 52c456c6a8..93504d5211 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -6,13 +6,13 @@ sonia.scm scm - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm scm-webapp war - 1.17-SNAPSHOT + 1.18-SNAPSHOT scm-webapp @@ -38,31 +38,31 @@ sonia.scm scm-core - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm scm-dao-xml - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm.plugins scm-hg-plugin - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm.plugins scm-svn-plugin - 1.17-SNAPSHOT + 1.18-SNAPSHOT sonia.scm.plugins scm-git-plugin - 1.17-SNAPSHOT + 1.18-SNAPSHOT @@ -221,7 +221,7 @@ sonia.scm scm-test - 1.17-SNAPSHOT + 1.18-SNAPSHOT test @@ -231,6 +231,20 @@ + + org.seleniumhq.selenium + selenium-java + 2.24.1 + test + + + + org.seleniumhq.selenium + selenium-firefox-driver + 2.24.1 + test + + com.jcraft jsch @@ -373,7 +387,7 @@ sonia.scm scm-dao-orientdb - 1.17-SNAPSHOT + 1.18-SNAPSHOT @@ -435,6 +449,11 @@ org.apache.maven.plugins maven-failsafe-plugin 2.12 + + + sonia/scm/it/*ITCase.java + + integration-test @@ -499,6 +518,110 @@ + + selenium + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.12 + + + sonia/scm/selenium/*ITCase.java + + + + + integration-test + + integration-test + + + + verify + + verify + + + + + + + org.mortbay.jetty + maven-jetty-plugin + 6.1.26 + + 8086 + STOP + + + scm.home + target/scm-it + + + + + 8082 + 60000 + + + ${project.build.javaLevel} + ${project.build.javaLevel} + ${project.build.sourceEncoding} + 0 + true + + + + start-jetty + pre-integration-test + + deploy-war + + + + stop-jetty + post-integration-test + + stop + + + + + + + org.codehaus.mojo + selenium-maven-plugin + 2.3 + + + start-selenium-server + pre-integration-test + + start-server + + + true + + + + stop-selenium-server + post-integration-test + + stop-server + + + + + + + + + + doc diff --git a/scm-webapp/src/main/java/sonia/scm/BindingExtensionProcessor.java b/scm-webapp/src/main/java/sonia/scm/BindingExtensionProcessor.java index c3195ff97c..666e925ddf 100644 --- a/scm-webapp/src/main/java/sonia/scm/BindingExtensionProcessor.java +++ b/scm-webapp/src/main/java/sonia/scm/BindingExtensionProcessor.java @@ -46,6 +46,8 @@ import sonia.scm.group.GroupListener; import sonia.scm.io.FileSystem; import sonia.scm.plugin.ext.Extension; import sonia.scm.plugin.ext.ExtensionProcessor; +import sonia.scm.repository.BlameLinePreProcessor; +import sonia.scm.repository.BlameLinePreProcessorFactory; import sonia.scm.repository.ChangesetPreProcessor; import sonia.scm.repository.ChangesetPreProcessorFactory; import sonia.scm.repository.FileObjectPreProcessor; @@ -54,6 +56,7 @@ import sonia.scm.repository.RepositoryHandler; import sonia.scm.repository.RepositoryHook; import sonia.scm.repository.RepositoryListener; import sonia.scm.repository.RepositoryRequestListener; +import sonia.scm.repository.spi.RepositoryServiceResolver; import sonia.scm.resources.ResourceHandler; import sonia.scm.security.EncryptionHandler; import sonia.scm.user.UserListener; @@ -124,6 +127,16 @@ public class BindingExtensionProcessor implements ExtensionProcessor Multibinder fileObjectPreProcessorFactoryBinder = Multibinder.newSetBinder(binder, FileObjectPreProcessorFactory.class); + // blameline pre processor + Multibinder blameLinePreProcessorBinder = + Multibinder.newSetBinder(binder, BlameLinePreProcessor.class); + Multibinder blameLinePreProcessorFactoryBinder = + Multibinder.newSetBinder(binder, BlameLinePreProcessorFactory.class); + + // repository service resolver + Multibinder repositoryServiceResolverBinder = + Multibinder.newSetBinder(binder, RepositoryServiceResolver.class); + // listeners Multibinder repositoryListenerBinder = Multibinder.newSetBinder(binder, RepositoryListener.class); @@ -268,6 +281,27 @@ public class BindingExtensionProcessor implements ExtensionProcessor fileObjectPreProcessorFactoryBinder.addBinding().to(extensionClass); } + else if (BlameLinePreProcessor.class.isAssignableFrom(extensionClass)) + { + if (logger.isInfoEnabled()) + { + logger.info("bind BlameLinePreProcessor {}", + extensionClass.getName()); + } + + blameLinePreProcessorBinder.addBinding().to(extensionClass); + } + else if (BlameLinePreProcessorFactory.class.isAssignableFrom( + extensionClass)) + { + if (logger.isInfoEnabled()) + { + logger.info("bind BlameLinePreProcessorFactory {}", + extensionClass.getName()); + } + + blameLinePreProcessorFactoryBinder.addBinding().to(extensionClass); + } else if (RepositoryHook.class.isAssignableFrom(extensionClass)) { if (logger.isInfoEnabled()) @@ -297,6 +331,16 @@ public class BindingExtensionProcessor implements ExtensionProcessor servletContextListenerBinder.addBinding().to(extensionClass); } + else if (RepositoryServiceResolver.class.isAssignableFrom(extensionClass)) + { + if (logger.isInfoEnabled()) + { + logger.info("bind RepositoryServiceResolver {}", + extensionClass.getName()); + } + + repositoryServiceResolverBinder.addBinding().to(extensionClass); + } else { if (logger.isInfoEnabled()) diff --git a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java index 8c9847746e..7d56eef7b4 100644 --- a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java +++ b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java @@ -71,6 +71,7 @@ import sonia.scm.repository.RepositoryBrowserUtil; import sonia.scm.repository.RepositoryDAO; import sonia.scm.repository.RepositoryManager; import sonia.scm.repository.RepositoryProvider; +import sonia.scm.repository.api.RepositoryServiceFactory; import sonia.scm.repository.xml.XmlRepositoryDAO; import sonia.scm.resources.DefaultResourceManager; import sonia.scm.resources.DevelopmentResourceManager; @@ -101,6 +102,7 @@ import sonia.scm.util.DebugServlet; import sonia.scm.util.ScmConfigurationUtil; import sonia.scm.web.cgi.CGIExecutorFactory; import sonia.scm.web.cgi.DefaultCGIExecutorFactory; +import sonia.scm.web.filter.LoggingFilter; import sonia.scm.web.security.AdministrationContext; import sonia.scm.web.security.ApiBasicAuthenticationFilter; import sonia.scm.web.security.AuthenticationManager; @@ -172,6 +174,9 @@ public class ScmServletModule extends ServletModule /** Field description */ public static final String REST_PACKAGE = "sonia.scm.api.rest"; + /** Field description */ + public static final String SYSTEM_PROPERTY_DEBUG_HTTP = "scm.debug.http"; + /** Field description */ public static final String[] PATTERN_STATIC_RESOURCES = new String[] { PATTERN_SCRIPT, @@ -299,6 +304,15 @@ public class ScmServletModule extends ServletModule Names.named(UrlProviderFactory.TYPE_WUI)).toProvider( WebUIUrlProvider.class); + // bind repository service factory + bind(RepositoryServiceFactory.class); + + // bind debug logging filter + if ("true".equalsIgnoreCase(System.getProperty(SYSTEM_PROPERTY_DEBUG_HTTP))) + { + filter(PATTERN_ALL).through(LoggingFilter.class); + } + /* * filter(PATTERN_PAGE, * PATTERN_STATIC_RESOURCES).through(StaticResourceFilter.class); diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/BrowserStreamingOutput.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/BrowserStreamingOutput.java index c9f9f5f680..5b2dcfa50b 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/BrowserStreamingOutput.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/BrowserStreamingOutput.java @@ -39,9 +39,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sonia.scm.repository.PathNotFoundException; -import sonia.scm.repository.RepositoryBrowser; import sonia.scm.repository.RepositoryException; import sonia.scm.repository.RevisionNotFoundException; +import sonia.scm.repository.api.CatCommandBuilder; //~--- JDK imports ------------------------------------------------------------ @@ -71,13 +71,13 @@ public class BrowserStreamingOutput implements StreamingOutput * * @param browser * @param revision + * + * @param builder * @param path */ - public BrowserStreamingOutput(RepositoryBrowser browser, String revision, - String path) + public BrowserStreamingOutput(CatCommandBuilder builder, String path) { - this.browser = browser; - this.revision = revision; + this.builder = builder; this.path = path; } @@ -98,7 +98,7 @@ public class BrowserStreamingOutput implements StreamingOutput { try { - browser.getContent(revision, path, output); + builder.retriveContent(output, path); } catch (PathNotFoundException ex) { @@ -130,11 +130,8 @@ public class BrowserStreamingOutput implements StreamingOutput //~--- fields --------------------------------------------------------------- /** Field description */ - private RepositoryBrowser browser; + private CatCommandBuilder builder; /** Field description */ private String path; - - /** Field description */ - private String revision; } diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/DiffStreamingOutput.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/DiffStreamingOutput.java index a8f7c93ef4..ad55889c0d 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/DiffStreamingOutput.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/DiffStreamingOutput.java @@ -38,10 +38,10 @@ package sonia.scm.api.rest.resources; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import sonia.scm.repository.DiffViewer; import sonia.scm.repository.PathNotFoundException; import sonia.scm.repository.RepositoryException; import sonia.scm.repository.RevisionNotFoundException; +import sonia.scm.repository.api.DiffCommandBuilder; //~--- JDK imports ------------------------------------------------------------ @@ -66,19 +66,14 @@ public class DiffStreamingOutput implements StreamingOutput //~--- constructors --------------------------------------------------------- /** - * Constructs ... + * Constructs ... * * - * @param diffViewer - * @param revision - * @param path + * @param builder */ - public DiffStreamingOutput(DiffViewer diffViewer, String revision, - String path) + public DiffStreamingOutput(DiffCommandBuilder builder) { - this.diffViewer = diffViewer; - this.revision = revision; - this.path = path; + this.builder = builder; } //~--- methods -------------------------------------------------------------- @@ -98,7 +93,7 @@ public class DiffStreamingOutput implements StreamingOutput { try { - diffViewer.getDiff(revision, path, output); + builder.retriveContent(output); } catch (PathNotFoundException ex) { @@ -130,11 +125,5 @@ public class DiffStreamingOutput implements StreamingOutput //~--- fields --------------------------------------------------------------- /** Field description */ - private DiffViewer diffViewer; - - /** Field description */ - private String path; - - /** Field description */ - private String revision; + private DiffCommandBuilder builder; } diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java index 8880bc6a70..9fa12d452c 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java @@ -35,6 +35,8 @@ package sonia.scm.api.rest.resources; //~--- non-JDK imports -------------------------------------------------------- +import com.google.common.base.Strings; +import com.google.common.io.Closeables; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; @@ -45,30 +47,30 @@ import org.codehaus.enunciate.modules.jersey.ExternallyManagedLifecycle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import sonia.scm.NotSupportedFeatuerException; import sonia.scm.config.ScmConfiguration; import sonia.scm.repository.BlameResult; -import sonia.scm.repository.BlameViewerUtil; import sonia.scm.repository.BrowserResult; import sonia.scm.repository.Changeset; import sonia.scm.repository.ChangesetPagingResult; -import sonia.scm.repository.ChangesetViewerUtil; -import sonia.scm.repository.DiffViewer; import sonia.scm.repository.Permission; import sonia.scm.repository.PermissionType; import sonia.scm.repository.PermissionUtil; import sonia.scm.repository.Repository; -import sonia.scm.repository.RepositoryBrowser; -import sonia.scm.repository.RepositoryBrowserUtil; import sonia.scm.repository.RepositoryException; -import sonia.scm.repository.RepositoryHandler; import sonia.scm.repository.RepositoryIsNotArchivedException; import sonia.scm.repository.RepositoryManager; import sonia.scm.repository.RepositoryNotFoundException; import sonia.scm.repository.RepositoryUtil; +import sonia.scm.repository.api.BlameCommandBuilder; +import sonia.scm.repository.api.BrowseCommandBuilder; +import sonia.scm.repository.api.CatCommandBuilder; +import sonia.scm.repository.api.CommandNotSupportedException; +import sonia.scm.repository.api.DiffCommandBuilder; +import sonia.scm.repository.api.LogCommandBuilder; +import sonia.scm.repository.api.RepositoryService; +import sonia.scm.repository.api.RepositoryServiceFactory; import sonia.scm.security.ScmSecurityException; import sonia.scm.util.AssertUtil; -import sonia.scm.util.HttpUtil; import sonia.scm.util.Util; import sonia.scm.web.security.WebSecurityContext; @@ -125,6 +127,7 @@ public class RepositoryResource * @param configuration * @param repositoryManager * @param securityContextProvider + * @param servicefactory * @param changesetViewerUtil * @param repositoryBrowserUtil * @param blameViewerUtil @@ -133,17 +136,13 @@ public class RepositoryResource public RepositoryResource( ScmConfiguration configuration, RepositoryManager repositoryManager, Provider securityContextProvider, - ChangesetViewerUtil changesetViewerUtil, - RepositoryBrowserUtil repositoryBrowserUtil, - BlameViewerUtil blameViewerUtil) + RepositoryServiceFactory servicefactory) { super(repositoryManager); this.configuration = configuration; this.repositoryManager = repositoryManager; + this.servicefactory = servicefactory; this.securityContextProvider = securityContextProvider; - this.changesetViewerUtil = changesetViewerUtil; - this.repositoryBrowserUtil = repositoryBrowserUtil; - this.blameViewerUtil = blameViewerUtil; setDisableCache(false); } @@ -349,13 +348,21 @@ public class RepositoryResource throws RepositoryException, IOException { Response response = null; + RepositoryService service = null; try { AssertUtil.assertIsNotNull(path); + service = servicefactory.create(id); - BlameResult blamePagingResult = blameViewerUtil.getBlame(id, revision, - path); + BlameCommandBuilder builder = service.getBlameCommand(); + + if (!Strings.isNullOrEmpty(revision)) + { + builder.setRevision(revision); + } + + BlameResult blamePagingResult = builder.getBlameResult(path); if (blamePagingResult != null) { @@ -374,10 +381,14 @@ public class RepositoryResource { response = Response.status(Response.Status.NOT_FOUND).build(); } - catch (NotSupportedFeatuerException ex) + catch (CommandNotSupportedException ex) { response = Response.status(Response.Status.BAD_REQUEST).build(); } + finally + { + Closeables.closeQuietly(service); + } return response; } @@ -413,11 +424,25 @@ public class RepositoryResource throws RepositoryException, IOException { Response response = null; + RepositoryService service = null; try { - BrowserResult result = repositoryBrowserUtil.getResult(id, revision, - path); + service = servicefactory.create(id); + + BrowseCommandBuilder builder = service.getBrowseCommand(); + + if (!Strings.isNullOrEmpty(revision)) + { + builder.setRevision(revision); + } + + if (!Strings.isNullOrEmpty(path)) + { + builder.setPath(path); + } + + BrowserResult result = builder.getBrowserResult(); if (result != null) { @@ -432,10 +457,14 @@ public class RepositoryResource { response = Response.status(Response.Status.NOT_FOUND).build(); } - catch (NotSupportedFeatuerException ex) + catch (CommandNotSupportedException ex) { response = Response.status(Response.Status.BAD_REQUEST).build(); } + finally + { + Closeables.closeQuietly(service); + } return response; } @@ -511,9 +540,13 @@ public class RepositoryResource if (Util.isNotEmpty(id) && Util.isNotEmpty(revision)) { + RepositoryService service = null; + try { - Changeset changeset = changesetViewerUtil.getChangeset(id, revision); + service = servicefactory.create(id); + + Changeset changeset = service.getLogCommand().getChangeset(revision); if (changeset != null) { @@ -528,10 +561,14 @@ public class RepositoryResource { response = Response.status(Response.Status.NOT_FOUND).build(); } - catch (NotSupportedFeatuerException ex) + catch (CommandNotSupportedException ex) { response = Response.status(Response.Status.BAD_REQUEST).build(); } + finally + { + Closeables.closeQuietly(service); + } } else { @@ -581,21 +618,29 @@ public class RepositoryResource @QueryParam("limit") int limit) throws RepositoryException, IOException { Response response = null; + RepositoryService service = null; try { ChangesetPagingResult changesets = null; - if (Util.isEmpty(path)) + service = servicefactory.create(id); + + LogCommandBuilder builder = service.getLogCommand(); + + if (!Strings.isNullOrEmpty(path)) { - changesets = changesetViewerUtil.getChangesets(id, start, limit); + builder.setPath(path); } - else + + if (!Strings.isNullOrEmpty(revision)) { - changesets = changesetViewerUtil.getChangesets(id, path, revision, - start, limit); + builder.setStartChangeset(revision); } + changesets = + builder.setPagingStart(start).setPagingLimit(limit).getChangesets(); + if (changesets != null) { response = Response.ok(changesets).build(); @@ -609,10 +654,14 @@ public class RepositoryResource { response = Response.status(Response.Status.NOT_FOUND).build(); } - catch (NotSupportedFeatuerException ex) + catch (CommandNotSupportedException ex) { response = Response.status(Response.Status.BAD_REQUEST).build(); } + finally + { + Closeables.closeQuietly(service); + } return response; } @@ -645,37 +694,43 @@ public class RepositoryResource { Response response = null; StreamingOutput output = null; - Repository repository = repositoryManager.get(id); + RepositoryService service = null; - if (repository != null) + try { - try + service = servicefactory.create(id); + + CatCommandBuilder builder = service.getCatCommand(); + + if (!Strings.isNullOrEmpty(revision)) { - RepositoryBrowser browser = - repositoryManager.getRepositoryBrowser(repository); - - if (browser != null) - { - output = new BrowserStreamingOutput(browser, revision, path); - - String contentDispositionName = - getContentDispositionNameFromPath(path); - - response = Response.ok(output).header("Content-Disposition", - contentDispositionName).build(); - } - else if (logger.isWarnEnabled()) - { - logger.warn("could not find repository browser for respository {}", - repository.getId()); - response = Response.status(Response.Status.NOT_FOUND).build(); - } - } - catch (Exception ex) - { - logger.error("could not retrive content", ex); - response = createErrorResonse(ex); + builder.setRevision(revision); } + + output = new BrowserStreamingOutput(builder, path); + + String contentDispositionName = getContentDispositionNameFromPath(path); + + response = Response.ok(output).header("Content-Disposition", + contentDispositionName).build(); + } + catch (RepositoryNotFoundException ex) + { + logger.warn("could not find repository browser for respository {}", id); + response = Response.status(Response.Status.NOT_FOUND).build(); + } + catch (CommandNotSupportedException ex) + { + response = Response.status(Response.Status.BAD_REQUEST).build(); + } + catch (Exception ex) + { + logger.error("could not retrive content", ex); + response = createErrorResonse(ex); + } + finally + { + Closeables.closeQuietly(service); } return response; @@ -714,36 +769,49 @@ public class RepositoryResource AssertUtil.assertIsNotEmpty(id); AssertUtil.assertIsNotEmpty(revision); + RepositoryService service = null; Response response = null; try { - Repository repository = repositoryManager.get(id); + service = servicefactory.create(id); - if (repository != null) + DiffCommandBuilder builder = service.getDiffCommand(); + + if (!Strings.isNullOrEmpty(revision)) { - DiffViewer diffViewer = repositoryManager.getDiffViewer(repository); - - if (diffViewer != null) - { - String name = - repository.getName().concat("-").concat(revision).concat(".diff"); - String contentDispositionName = getContentDispositionName(name); - - response = Response.ok(new DiffStreamingOutput(diffViewer, revision, - path)).header("Content-Disposition", - contentDispositionName).build(); - } - else - { - response = Response.status(Response.Status.NOT_FOUND).build(); - } + builder.setRevision(revision); } + + if (!Strings.isNullOrEmpty(path)) + { + builder.setPath(path); + } + + String name = service.getRepository().getName().concat("-").concat( + revision).concat(".diff"); + String contentDispositionName = getContentDispositionName(name); + + response = Response.ok(new DiffStreamingOutput(builder)).header( + "Content-Disposition", contentDispositionName).build(); } catch (RepositoryNotFoundException ex) { response = Response.status(Response.Status.NOT_FOUND).build(); } + catch (CommandNotSupportedException ex) + { + response = Response.status(Response.Status.BAD_REQUEST).build(); + } + catch (Exception ex) + { + logger.error("could not create diff", ex); + response = createErrorResonse(ex); + } + finally + { + Closeables.closeQuietly(service); + } return response; } @@ -909,21 +977,15 @@ public class RepositoryResource //~--- fields --------------------------------------------------------------- - /** Field description */ - private BlameViewerUtil blameViewerUtil; - - /** Field description */ - private ChangesetViewerUtil changesetViewerUtil; - /** Field description */ private ScmConfiguration configuration; - /** Field description */ - private RepositoryBrowserUtil repositoryBrowserUtil; - /** Field description */ private RepositoryManager repositoryManager; /** Field description */ private Provider securityContextProvider; + + /** Field description */ + private RepositoryServiceFactory servicefactory; } diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryRootResource.java index 9a11e74a6f..cc2b903ff3 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryRootResource.java @@ -1,34 +1,35 @@ /** - * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * 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 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. + * 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.api.rest.resources; //~--- non-JDK imports -------------------------------------------------------- @@ -42,7 +43,6 @@ import com.google.inject.Inject; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryManager; import sonia.scm.repository.RepositoryTypePredicate; -import sonia.scm.repository.RepositoryUtil; import sonia.scm.template.TemplateHandler; import sonia.scm.url.UrlProvider; import sonia.scm.url.UrlProviderFactory; @@ -116,15 +116,15 @@ public class RepositoryRootResource @PathParam("type") final String type) throws IOException { - UrlProvider uiUrlProvider = - UrlProviderFactory.createUrlProvider(HttpUtil.getCompleteUrl(request), - UrlProviderFactory.TYPE_WUI); + String baseUrl = HttpUtil.getCompleteUrl(request); + UrlProvider uiUrlProvider = UrlProviderFactory.createUrlProvider(baseUrl, + UrlProviderFactory.TYPE_WUI); //J- Collection unsortedRepositories = Collections2.transform( Collections2.filter( repositoryManager.getAll(), new RepositoryTypePredicate(type)) - , new RepositoryTransformFunction(request, repositoryManager, uiUrlProvider) + , new RepositoryTransformFunction(uiUrlProvider, baseUrl) ); List repositories = Ordering.from( @@ -160,12 +160,14 @@ public class RepositoryRootResource * * @param repository * @param uiUrlProvider + * @param baseUrl */ public RepositoryTemplateElement(Repository repository, - UrlProvider uiUrlProvider) + UrlProvider uiUrlProvider, String baseUrl) { this.repository = repository; this.urlProvider = uiUrlProvider; + this.baseUrl = baseUrl; } //~--- get methods -------------------------------------------------------- @@ -236,11 +238,14 @@ public class RepositoryRootResource */ public String getUrl() { - return repository.getUrl(); + return repository.createUrl(baseUrl); } //~--- fields ------------------------------------------------------------- + /** Field description */ + private String baseUrl; + /** Field description */ private Repository repository; @@ -298,14 +303,12 @@ public class RepositoryRootResource * @param request * @param repositoryManager * @param urlProvider + * @param baseUrl */ - public RepositoryTransformFunction(HttpServletRequest request, - RepositoryManager repositoryManager, - UrlProvider urlProvider) + public RepositoryTransformFunction(UrlProvider urlProvider, String baseUrl) { - this.request = request; - this.repositoryManager = repositoryManager; this.urlProvider = urlProvider; + this.baseUrl = baseUrl; } //~--- methods ------------------------------------------------------------ @@ -321,18 +324,13 @@ public class RepositoryRootResource @Override public RepositoryTemplateElement apply(Repository repository) { - RepositoryUtil.appendUrl(request, repositoryManager, repository); - - return new RepositoryTemplateElement(repository, urlProvider); + return new RepositoryTemplateElement(repository, urlProvider, baseUrl); } //~--- fields ------------------------------------------------------------- /** Field description */ - private RepositoryManager repositoryManager; - - /** Field description */ - private HttpServletRequest request; + private String baseUrl; /** Field description */ private UrlProvider urlProvider; diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/SupportResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/SupportResource.java index b7a85d8c13..0fac1a6591 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/SupportResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/SupportResource.java @@ -1,27 +1,29 @@ /** - * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * 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 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. + * 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 * @@ -38,8 +40,11 @@ import com.google.common.collect.Maps; import com.google.inject.Inject; import sonia.scm.SCMContextProvider; +import sonia.scm.Type; import sonia.scm.config.ScmConfiguration; import sonia.scm.plugin.PluginManager; +import sonia.scm.repository.RepositoryHandler; +import sonia.scm.repository.RepositoryManager; import sonia.scm.store.StoreFactory; import sonia.scm.template.TemplateHandler; import sonia.scm.util.SecurityUtil; @@ -50,18 +55,17 @@ import sonia.scm.web.security.WebSecurityContext; import java.io.IOException; import java.io.StringWriter; + import java.util.Collection; import java.util.List; - +import java.util.Locale; import java.util.Map; +import java.util.TimeZone; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; -import sonia.scm.Type; -import sonia.scm.repository.RepositoryHandler; -import sonia.scm.repository.RepositoryManager; /** * @@ -87,13 +91,16 @@ public class SupportResource * @param configuration * @param pluginManager * @param storeFactory + * @param repositoryManager */ @Inject public SupportResource(WebSecurityContext securityContext, SCMContextProvider context, TemplateHandler templateHandler, ScmConfiguration configuration, - PluginManager pluginManager, StoreFactory storeFactory, RepositoryManager repositoryManager ) + PluginManager pluginManager, + StoreFactory storeFactory, + RepositoryManager repositoryManager) { this.securityContext = securityContext; this.context = context; @@ -104,8 +111,6 @@ public class SupportResource this.repositoryManager = repositoryManager; } - private RepositoryManager repositoryManager; - //~--- get methods ---------------------------------------------------------- /** @@ -138,15 +143,21 @@ public class SupportResource return writer.toString(); } + /** + * Method description + * + * + * @return + */ private List getRepositoryHandlers() { List handlers = Lists.newArrayList(); - - for ( Type type : repositoryManager.getConfiguredTypes() ) + + for (Type type : repositoryManager.getConfiguredTypes()) { - handlers.add( repositoryManager.getHandler(type.getName()) ); + handlers.add(repositoryManager.getHandler(type.getName())); } - + return handlers; } @@ -259,6 +270,8 @@ public class SupportResource container = SystemUtil.getServletContainer().name(); java = System.getProperty("java.vendor").concat("/").concat( System.getProperty("java.version")); + locale = Locale.getDefault().toString(); + timeZone = TimeZone.getDefault().getID(); } //~--- get methods -------------------------------------------------------- @@ -296,6 +309,17 @@ public class SupportResource return java; } + /** + * Method description + * + * + * @return + */ + public String getLocale() + { + return locale; + } + /** * Method description * @@ -307,6 +331,17 @@ public class SupportResource return os; } + /** + * Method description + * + * + * @return + */ + public String getTimeZone() + { + return timeZone; + } + //~--- fields ------------------------------------------------------------- /** Field description */ @@ -318,8 +353,14 @@ public class SupportResource /** Field description */ private String java; + /** Field description */ + private String locale; + /** Field description */ private String os; + + /** Field description */ + private String timeZone; } @@ -407,6 +448,9 @@ public class SupportResource /** Field description */ private PluginManager pluginManager; + /** Field description */ + private RepositoryManager repositoryManager; + /** Field description */ private WebSecurityContext securityContext; diff --git a/scm-webapp/src/main/java/sonia/scm/boot/BootstrapListener.java b/scm-webapp/src/main/java/sonia/scm/boot/BootstrapListener.java index c6f45f2bc3..6794e2aa98 100644 --- a/scm-webapp/src/main/java/sonia/scm/boot/BootstrapListener.java +++ b/scm-webapp/src/main/java/sonia/scm/boot/BootstrapListener.java @@ -39,6 +39,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sonia.scm.SCMContext; +import sonia.scm.SCMContextProvider; //~--- JDK imports ------------------------------------------------------------ @@ -102,14 +103,16 @@ public class BootstrapListener implements ServletContextListener @Override public void contextInitialized(ServletContextEvent sce) { + SCMContextProvider context = SCMContext.getContext(); + if (logger.isInfoEnabled()) { - logger.info("start scm-manager in stage: {}", - SCMContext.getContext().getStage()); + logger.info("start scm-manager {} in stage: {}", context.getVersion(), + context.getStage()); } ClassLoader classLoader = null; - File pluginDirectory = new File(SCMContext.getContext().getBaseDirectory(), + File pluginDirectory = new File(context.getBaseDirectory(), PLUGIN_DIRECTORY); if (pluginDirectory.exists()) diff --git a/scm-webapp/src/main/java/sonia/scm/net/TrustAllHostnameVerifier.java b/scm-webapp/src/main/java/sonia/scm/net/TrustAllHostnameVerifier.java new file mode 100644 index 0000000000..2ffd2f4676 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/net/TrustAllHostnameVerifier.java @@ -0,0 +1,61 @@ +/** + * 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.net; + +//~--- JDK imports ------------------------------------------------------------ + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSession; + +/** + * + * @author Sebastian Sdorra + */ +public class TrustAllHostnameVerifier implements HostnameVerifier +{ + + /** + * Method description + * + * + * @param hostname + * @param session + * + * @return + */ + @Override + public boolean verify(String hostname, SSLSession session) + { + return true; + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/net/TrustAllTrustManager.java b/scm-webapp/src/main/java/sonia/scm/net/TrustAllTrustManager.java new file mode 100644 index 0000000000..e4d73aed31 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/net/TrustAllTrustManager.java @@ -0,0 +1,88 @@ +/** + * 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.net; + +//~--- JDK imports ------------------------------------------------------------ + +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import javax.net.ssl.X509TrustManager; + +/** + * + * @author Sebastian Sdorra + */ +public class TrustAllTrustManager implements X509TrustManager +{ + + /** + * Method description + * + * + * @param chain + * @param authType + * + * @throws CertificateException + */ + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) + throws CertificateException {} + + /** + * Method description + * + * + * @param chain + * @param authType + * + * @throws CertificateException + */ + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) + throws CertificateException {} + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + public X509Certificate[] getAcceptedIssuers() + { + return null; + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/net/URLHttpClient.java b/scm-webapp/src/main/java/sonia/scm/net/URLHttpClient.java index 3fecc05d91..c2a38223d5 100644 --- a/scm-webapp/src/main/java/sonia/scm/net/URLHttpClient.java +++ b/scm-webapp/src/main/java/sonia/scm/net/URLHttpClient.java @@ -64,6 +64,10 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; + /** * * @author Sebastian Sdorra @@ -383,6 +387,49 @@ public class URLHttpClient implements HttpClient } } + /** + * Method description + * + * + * @param request + * @param connection + */ + private void applySSLSettings(HttpRequest request, + HttpsURLConnection connection) + { + if (request.isDisableCertificateValidation()) + { + if (logger.isTraceEnabled()) + { + logger.trace("disable certificate validation"); + } + + try + { + TrustManager[] trustAllCerts = new TrustManager[] { + new TrustAllTrustManager() }; + SSLContext sc = SSLContext.getInstance("SSL"); + + sc.init(null, trustAllCerts, new java.security.SecureRandom()); + connection.setSSLSocketFactory(sc.getSocketFactory()); + } + catch (Exception ex) + { + logger.error("could not disable certificate validation", ex); + } + } + + if (request.isDisableHostnameValidation()) + { + if (logger.isTraceEnabled()) + { + logger.trace("disable hostname validation"); + } + + connection.setHostnameVerifier(new TrustAllHostnameVerifier()); + } + } + /** * Method description * @@ -484,9 +531,15 @@ public class URLHttpClient implements HttpClient private HttpURLConnection openConnection(HttpRequest request, URL url) throws IOException { + if (request == null) + { + // TODO improve + request = new HttpRequest(url.toExternalForm()); + } + HttpURLConnection connection = null; - if (configuration.isEnableProxy()) + if (!request.isIgnoreProxySettings() && configuration.isEnableProxy()) { if (logger.isDebugEnabled()) { @@ -506,6 +559,11 @@ public class URLHttpClient implements HttpClient } else { + if (request.isIgnoreProxySettings() && logger.isTraceEnabled()) + { + logger.trace("ignore proxy settings"); + } + if (logger.isDebugEnabled()) { logger.debug("fetch '{}'", url.toExternalForm()); @@ -514,6 +572,11 @@ public class URLHttpClient implements HttpClient connection = (HttpURLConnection) url.openConnection(); } + if (connection instanceof HttpsURLConnection) + { + applySSLSettings(request, (HttpsURLConnection) connection); + } + connection.setReadTimeout(TIMEOUT_RAED); connection.setConnectTimeout(TIMEOUT_CONNECTION); diff --git a/scm-webapp/src/main/java/sonia/scm/plugin/DefaultProxySelector.java b/scm-webapp/src/main/java/sonia/scm/plugin/DefaultProxySelector.java index 616b5b9308..fd3ad16507 100644 --- a/scm-webapp/src/main/java/sonia/scm/plugin/DefaultProxySelector.java +++ b/scm-webapp/src/main/java/sonia/scm/plugin/DefaultProxySelector.java @@ -1,34 +1,35 @@ /** - * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * 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 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. + * 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.plugin; //~--- non-JDK imports -------------------------------------------------------- diff --git a/scm-webapp/src/main/java/sonia/scm/web/cgi/DefaultCGIStatusCodeHandler.java b/scm-webapp/src/main/java/sonia/scm/web/cgi/DefaultCGIStatusCodeHandler.java index 3d5eee88cd..91531d9838 100644 --- a/scm-webapp/src/main/java/sonia/scm/web/cgi/DefaultCGIStatusCodeHandler.java +++ b/scm-webapp/src/main/java/sonia/scm/web/cgi/DefaultCGIStatusCodeHandler.java @@ -1,34 +1,35 @@ /** - * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * 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 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. + * 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.web.cgi; //~--- non-JDK imports -------------------------------------------------------- diff --git a/scm-webapp/src/main/java/sonia/scm/web/security/BasicSecurityContext.java b/scm-webapp/src/main/java/sonia/scm/web/security/BasicSecurityContext.java index f17bb67494..cf1c78f97c 100644 --- a/scm-webapp/src/main/java/sonia/scm/web/security/BasicSecurityContext.java +++ b/scm-webapp/src/main/java/sonia/scm/web/security/BasicSecurityContext.java @@ -124,9 +124,16 @@ public class BasicSecurityContext implements WebSecurityContext HttpServletResponse response, String username, String password) { + if ( logger.isTraceEnabled() ){ + logger.trace("start authentication for user {}", username); + } AuthenticationResult ar = authenticator.authenticate(request, response, username, password); + if ( logger.isTraceEnabled() ){ + logger.trace("authentication ends with {}", ar); + } + if ((ar != null) && (ar.getState() == AuthenticationState.SUCCESS)) { authenticate(request, password, ar); diff --git a/scm-webapp/src/main/java/sonia/scm/web/security/ChainAuthenticatonManager.java b/scm-webapp/src/main/java/sonia/scm/web/security/ChainAuthenticatonManager.java index fcdb2a4d06..2f51ef6cfe 100644 --- a/scm-webapp/src/main/java/sonia/scm/web/security/ChainAuthenticatonManager.java +++ b/scm-webapp/src/main/java/sonia/scm/web/security/ChainAuthenticatonManager.java @@ -130,6 +130,12 @@ public class ChainAuthenticatonManager extends AbstractAuthenticationManager if (ar == null) { + if (logger.isTraceEnabled()) + { + logger.trace("no authentication result for user {} found in cache", + username); + } + ar = doAuthentication(request, response, username, password); if ((ar != null) && ar.isCacheable()) @@ -157,6 +163,11 @@ public class ChainAuthenticatonManager extends AbstractAuthenticationManager { for (AuthenticationHandler authenticator : authenticationHandlerSet) { + if (logger.isTraceEnabled()) + { + logger.trace("close authenticator {}", authenticator.getClass()); + } + IOUtil.close(authenticator); } } @@ -172,6 +183,11 @@ public class ChainAuthenticatonManager extends AbstractAuthenticationManager { for (AuthenticationHandler authenticator : authenticationHandlerSet) { + if (logger.isTraceEnabled()) + { + logger.trace("initialize authenticator {}", authenticator.getClass()); + } + authenticator.init(context); } @@ -200,8 +216,19 @@ public class ChainAuthenticatonManager extends AbstractAuthenticationManager { AuthenticationResult ar = null; + if (logger.isTraceEnabled()) + { + logger.trace("start authentication chain for user {}", username); + } + for (AuthenticationHandler authenticator : authenticationHandlerSet) { + if (logger.isTraceEnabled()) + { + logger.trace("check authenticator {} for user {}", + authenticator.getClass(), username); + } + try { AuthenticationResult result = authenticator.authenticate(request, diff --git a/scm-webapp/src/main/resources/config/ehcache.xml b/scm-webapp/src/main/resources/config/ehcache.xml index 5e144a653c..beb3b7f862 100644 --- a/scm-webapp/src/main/resources/config/ehcache.xml +++ b/scm-webapp/src/main/resources/config/ehcache.xml @@ -161,4 +161,36 @@ diskPersistent="false" /> + + + + + + + + diff --git a/scm-webapp/src/main/resources/templates/support.html b/scm-webapp/src/main/resources/templates/support.html index bd34ad2c1c..f22f902d9a 100644 --- a/scm-webapp/src/main/resources/templates/support.html +++ b/scm-webapp/src/main/resources/templates/support.html @@ -134,6 +134,8 @@
  • Architecture: ${system.arch}
  • ServletContainer: ${system.container}
  • Java: ${system.java}
  • +
  • Local: ${system.locale}
  • +
  • TimeZone: ${system.timeZone}
  • Repository Handlers

    diff --git a/scm-webapp/src/main/webapp/index.html b/scm-webapp/src/main/webapp/index.html index ae9ff6a176..05483ea295 100644 --- a/scm-webapp/src/main/webapp/index.html +++ b/scm-webapp/src/main/webapp/index.html @@ -211,6 +211,15 @@ - + + \ No newline at end of file diff --git a/scm-webapp/src/main/webapp/resources/css/style.css b/scm-webapp/src/main/webapp/resources/css/style.css index 05ee6d9971..0adbcadd9f 100644 --- a/scm-webapp/src/main/webapp/resources/css/style.css +++ b/scm-webapp/src/main/webapp/resources/css/style.css @@ -183,3 +183,22 @@ li.scm-removed { background-image: url(../images/delete.png); } + +div.noscript-container { + background-color: #ffffff; + margin: 10px; + color: #202020; + font-family: Verdana,Helvetica,Arial,sans-serif; + font-size: 12px; + margin: 1em; +} + +div.noscript-container h1 { + font-size: 18px; + font-family: Arial, "Arial CE", "Lucida Grande CE", lucida, "Helvetica CE", sans-serif; + font-weight: bold; + margin: 0.5em 0em; + padding: 0px; + color: #D20005; + border-bottom: 1px solid #AFAFAF; +} diff --git a/scm-webapp/src/main/webapp/resources/js/i18n/de.js b/scm-webapp/src/main/webapp/resources/js/i18n/de.js index e93addef4e..a98f58afad 100644 --- a/scm-webapp/src/main/webapp/resources/js/i18n/de.js +++ b/scm-webapp/src/main/webapp/resources/js/i18n/de.js @@ -86,7 +86,9 @@ if (Sonia.login.Form){ cancelText: 'Abbrechen', waitTitleText: 'Verbinden', WaitMsgText: 'Übertrage Daten...', - failedMsgText: 'Anmeldung fehlgeschlagen!' + failedMsgText: 'Anmeldung fehlgeschlagen!', + failedDescriptionText: 'Falscher Benutzername, Passwort oder sie haben nicht\n\ + genug Berechtigungen. Bitte versuchen sie es erneut.' }); } diff --git a/scm-webapp/src/main/webapp/resources/js/login/sonia.login.form.js b/scm-webapp/src/main/webapp/resources/js/login/sonia.login.form.js index cb8f7e5240..22d037d6a2 100644 --- a/scm-webapp/src/main/webapp/resources/js/login/sonia.login.form.js +++ b/scm-webapp/src/main/webapp/resources/js/login/sonia.login.form.js @@ -38,6 +38,7 @@ Sonia.login.Form = Ext.extend(Ext.FormPanel,{ waitTitleText: 'Connecting', WaitMsgText: 'Sending data...', failedMsgText: 'Login failed!', + failedDescriptionText: 'Incorrect username, password or not enough permission. Please Try again.', initComponent: function(){ @@ -81,6 +82,7 @@ Sonia.login.Form = Ext.extend(Ext.FormPanel,{ scope: this, handler: this.cancel },{ + id: 'loginButton', text: this.loginText, formBind: true, scope: this, @@ -88,7 +90,7 @@ Sonia.login.Form = Ext.extend(Ext.FormPanel,{ }] }; - this.addEvents('cancel'); + this.addEvents('cancel', 'failure'); Ext.apply(this, Ext.apply(this.initialConfig, config)); Sonia.login.Form.superclass.initComponent.apply(this, arguments); @@ -118,7 +120,13 @@ Sonia.login.Form = Ext.extend(Ext.FormPanel,{ if ( debug ){ console.debug( 'login failed' ); } - Ext.Msg.alert(this.failedMsgText); + this.fireEvent('failure'); + Ext.Msg.show({ + title: this.failedMsgText, + msg: this.failedDescriptionText, + buttons: Ext.Msg.OK, + icon: Ext.MessageBox.WARNING + }); form.reset(); } }); diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetpanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetpanel.js index 1d0aeebf8a..7e5dd0fb8e 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetpanel.js @@ -117,7 +117,7 @@ Sonia.repository.ChangesetPanel = Ext.extend(Ext.Panel, { }, showCommit: function(){ - if ( console ){ + if ( debug ){ console.debug('open commit for ' + this.revision); } this.openPanel(this.createCommitPanel()); @@ -126,7 +126,7 @@ Sonia.repository.ChangesetPanel = Ext.extend(Ext.Panel, { }, showDiff: function(){ - if ( console ){ + if ( debug ){ console.debug('open diff for ' + this.revision); } this.openPanel(this.createDiffPanel()); @@ -135,7 +135,7 @@ Sonia.repository.ChangesetPanel = Ext.extend(Ext.Panel, { }, downloadRawDiff: function(){ - if ( console ){ + if ( debug ){ console.debug('open raw diff for ' + this.revision); } window.open(this.createDiffUrl()); diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.grid.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.grid.js index 4d157f0dcb..a9428d2413 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.grid.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.grid.js @@ -86,8 +86,6 @@ Sonia.repository.Grid = Ext.extend(Sonia.rest.Grid, { name: 'description' },{ name: 'creationDate' - },{ - name:'url' },{ name: 'public' },{ @@ -150,8 +148,9 @@ Sonia.repository.Grid = Ext.extend(Sonia.rest.Grid, { },{ id: 'Url', header: this.colUrlText, - dataIndex: 'url', - renderer: this.renderUrl, + dataIndex: 'name', + renderer: this.renderRepositoryUrl, + scope: this, width: 250 },{ id: 'Archive', @@ -219,6 +218,13 @@ Sonia.repository.Grid = Ext.extend(Sonia.rest.Grid, { } }, + renderRepositoryUrl: function(name, meta, record){ + var type = record.get('type'); + return this.renderUrl( + Sonia.repository.createUrl(type, name) + ); + }, + renderArchive: function(v){ return v ? ' + v + ' : ''; }, diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js index 20c40c62a7..01f4bdffa9 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js @@ -74,7 +74,7 @@ Sonia.repository.InfoPanel = Ext.extend(Ext.Panel, { text: this.urlText },{ xtype: 'box', - html: String.format(this.linkTemplate, this.item.url) + html: String.format(this.linkTemplate, Sonia.repository.createUrlFromObject(this.item)) }]; var config = { @@ -105,7 +105,7 @@ Sonia.repository.InfoPanel = Ext.extend(Ext.Panel, { }, getRepositoryUrlWithUsername: function(){ - var uri = this.item.url; + var uri = Sonia.repository.createUrlFromObject(this.item); if ( state.user.name != 'anonymous' ){ var index = uri.indexOf("://"); if ( index > 0 ){ diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js index 13d1d1af56..1ed840a02b 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js @@ -78,6 +78,14 @@ Sonia.repository.setEditPanel = function(panels){ editPanel.doLayout(); } +Sonia.repository.createUrl = function(type, name){ + return Sonia.util.getBaseUrl() + '/' + type + '/' + name +} + +Sonia.repository.createUrlFromObject = function(repository){ + return Sonia.repository.createUrl(repository.type, repository.name); +} + /** * default panel */ diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js index 60228ce38e..1350693f82 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js @@ -73,6 +73,7 @@ Sonia.repository.Panel = Ext.extend(Sonia.rest.Panel, { var toolbar = []; if ( admin ){ toolbar.push({ + id: 'repositoryAddButton', xtype: 'tbbutton', text: this.addText, icon: this.addIcon, diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.settingsformpanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.settingsformpanel.js index 3987f2076c..956934cee5 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.settingsformpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.settingsformpanel.js @@ -45,6 +45,7 @@ Sonia.repository.SettingsFormPanel = Ext.extend(Sonia.repository.FormPanel, { helpText: this.nameHelpText, vtype: 'repositoryName' },{ + id: 'repositoryType', fieldLabel: this.typeText, name: 'type', xtype: 'combo', diff --git a/scm-webapp/src/main/webapp/resources/js/sonia.core.js b/scm-webapp/src/main/webapp/resources/js/sonia.core.js index 474eb4c992..83732d10ae 100644 --- a/scm-webapp/src/main/webapp/resources/js/sonia.core.js +++ b/scm-webapp/src/main/webapp/resources/js/sonia.core.js @@ -1,10 +1,10 @@ -/* * +/* * 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, @@ -13,7 +13,7 @@ * 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 @@ -24,12 +24,11 @@ * 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 - * + * */ - String.prototype.endsWith = function(suffix) { return this.indexOf(suffix, this.length - suffix.length) !== -1; }; diff --git a/scm-webapp/src/main/webapp/resources/js/sonia.global.js b/scm-webapp/src/main/webapp/resources/js/sonia.global.js index 6d23c35b92..25b8cb1db0 100644 --- a/scm-webapp/src/main/webapp/resources/js/sonia.global.js +++ b/scm-webapp/src/main/webapp/resources/js/sonia.global.js @@ -29,7 +29,7 @@ * */ // enable debug mode, if console is available -var debug = typeof console != 'undefined'; +var debug = typeof console != 'undefined' && typeof console.debug != 'undefined'; var state = null; var admin = false; diff --git a/scm-webapp/src/main/webapp/resources/js/sonia.scm.js b/scm-webapp/src/main/webapp/resources/js/sonia.scm.js index db6e6dd56c..a04f2dea25 100644 --- a/scm-webapp/src/main/webapp/resources/js/sonia.scm.js +++ b/scm-webapp/src/main/webapp/resources/js/sonia.scm.js @@ -523,7 +523,7 @@ Sonia.scm.Main = Ext.extend(Ext.util.Observable, { css.rel = 'stylesheet'; css.type = 'text/css'; css.href = url; - document.head.appendChild(css); + document.getElementsByTagName('head')[0].appendChild(css); this.stylesheets.push(url); } }, diff --git a/scm-webapp/src/main/webapp/resources/js/util/sonia.util.js b/scm-webapp/src/main/webapp/resources/js/util/sonia.util.js index 450ba16a57..4f80ed7b09 100644 --- a/scm-webapp/src/main/webapp/resources/js/util/sonia.util.js +++ b/scm-webapp/src/main/webapp/resources/js/util/sonia.util.js @@ -59,6 +59,21 @@ Sonia.util.getContextPath = function(){ return path; } +Sonia.util.getBaseUrl = function(){ + var url = location.href; + var i = url.indexOf('#'); + if ( i > 0 ){ + url = url.substring(0, i); + } + + if ( url.endsWith('/index.html') ){ + url = url.substring(0, url.length - '/index.html'.length); + } else if ( url.endsWith('/') ){ + url = url.substring(0, url.length -1); + } + return url; +} + Sonia.util.getName = function(path){ var name = path; var index = path.lastIndexOf('/'); diff --git a/scm-webapp/src/test/java/sonia/scm/it/DeactivatedUserITCase.java b/scm-webapp/src/test/java/sonia/scm/it/DeactivatedUserITCase.java index b29c17b5a4..68fe13b201 100644 --- a/scm-webapp/src/test/java/sonia/scm/it/DeactivatedUserITCase.java +++ b/scm-webapp/src/test/java/sonia/scm/it/DeactivatedUserITCase.java @@ -1,34 +1,35 @@ /** - * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * 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 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. + * 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.it; //~--- non-JDK imports -------------------------------------------------------- diff --git a/scm-webapp/src/test/java/sonia/scm/selenium/AuthenticationITCase.java b/scm-webapp/src/test/java/sonia/scm/selenium/AuthenticationITCase.java new file mode 100644 index 0000000000..a2b0d0fe6d --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/selenium/AuthenticationITCase.java @@ -0,0 +1,58 @@ +/** + * 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.selenium; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.Test; + +/** + * + * @author Sebastian Sdorra + */ +public class AuthenticationITCase extends SeleniumTestBase +{ + + /** + * Method description + * + * + * @throws Exception + */ + @Test + public void testAuthentication() throws Exception + { + login("scmadmin", "scmadmin"); + logout(); + } +} diff --git a/scm-webapp/src/test/java/sonia/scm/selenium/RepositoryCRUDITCase.java b/scm-webapp/src/test/java/sonia/scm/selenium/RepositoryCRUDITCase.java new file mode 100644 index 0000000000..64760ae774 --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/selenium/RepositoryCRUDITCase.java @@ -0,0 +1,94 @@ +/** + * 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.selenium; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * + * @author Sebastian Sdorra + */ +public class RepositoryCRUDITCase extends SeleniumTestBase +{ + + /** + * Method description + * + */ + @After + public void after() + { + logout(); + } + + /** + * Method description + * + */ + @Test + public void createRepository() throws InterruptedException + { + waitAndClick("#repositoryAddButton"); + waitForPresence("input[name=name]").sendKeys("scm"); + select("#x-form-el-repositoryType img").click(); + waitAndClick("div.x-combo-list-item:nth-of-type(2)"); + type("input[name=contact]", "scmadmin@scm-manager.org"); + type("textarea[name=description]", "SCM-Manager"); + waitAndClick("div.x-panel-btns button:nth-of-type(1)"); + + String name = + waitForPresence( + "div.x-grid3-row-selected div.x-grid3-col-name").getText(); + + assertEquals("scm", name); + + waitAndClick("#repoRmButton button"); + waitAndClick("div.x-window button:nth-of-type(1)"); + } + + /** + * Method description + * + */ + @Before + public void login() + { + login("scmadmin", "scmadmin"); + } +} diff --git a/scm-webapp/src/test/java/sonia/scm/selenium/SeleniumTestBase.java b/scm-webapp/src/test/java/sonia/scm/selenium/SeleniumTestBase.java new file mode 100644 index 0000000000..1ae5e86b3d --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/selenium/SeleniumTestBase.java @@ -0,0 +1,271 @@ +/** + * 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.selenium; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.io.Files; + +import org.junit.After; +import org.junit.Before; + +import org.openqa.selenium.By; +import org.openqa.selenium.OutputType; +import org.openqa.selenium.TakesScreenshot; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.firefox.FirefoxDriver; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.junit.Assert.*; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; +import java.io.IOException; + +import java.util.concurrent.TimeUnit; + +/** + * + * @author Sebastian Sdorra + */ +public class SeleniumTestBase +{ + + /** + * the logger for SeleniumTestBase + */ + private static final Logger logger = + LoggerFactory.getLogger(SeleniumTestBase.class); + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @throws Exception + */ + @After + public void tearDown() throws Exception + { + driver.quit(); + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @throws Exception + */ + @Before + public void setUp() throws Exception + { + driver = new FirefoxDriver(); + baseUrl = "http://localhost:8082/scm/"; + open("index.html"); + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param username + * @param password + */ + protected void login(String username, String password) + { + type("input[name=username]", username); + type("input[name=password]", password); + waitAndClick("#loginButton button"); + + String ue = waitForPresence("#scm-userinfo-tip").getText(); + + assertEquals(username, ue); + } + + /** + * Method description + * + */ + protected void logout() + { + waitAndClick("#navLogout a"); + } + + /** + * Method description + * + * + * @param url + */ + protected void open(String url) + { + driver.get(baseUrl + url); + pause(500, TimeUnit.MILLISECONDS); + } + + /** + * Method description + * + * + * @param value + * @param unit + */ + protected void pause(int value, TimeUnit unit) + { + driver.manage().timeouts().implicitlyWait(value, unit); + } + + /** + * Method description + * + * + * @param target + */ + protected void screenshot(String target) + { + screenshot(new File(target)); + } + + /** + * Method description + * + * + * @param target + */ + protected void screenshot(File target) + { + try + { + File scrFile = + ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); + + Files.copy(scrFile, target); + } + catch (IOException ex) + { + logger.error("could not create screenshot", ex); + } + } + + /** + * Method description + * + * + * @param cssSelector + * + * @return + */ + protected WebElement select(String cssSelector) + { + WebElement element = driver.findElement(By.cssSelector(cssSelector)); + + assertNotNull(element); + + return element; + } + + /** + * Method description + * + * + * @param cssLocator + * @param value + */ + protected void type(String cssLocator, String value) + { + select(cssLocator).clear(); + select(cssLocator).sendKeys(value); + } + + /** + * Method description + * + * + * @param query + */ + protected void waitAndClick(String query) + { + waitToBeClickable(query).click(); + } + + /** + * Method description + * + * + * @param query + * + * @return + */ + protected WebElement waitForPresence(String query) + { + WebDriverWait wait = new WebDriverWait(driver, 5); + + return wait.until( + ExpectedConditions.presenceOfElementLocated(By.cssSelector(query))); + } + + /** + * Method description + * + * + * @param query + * + * @return + */ + protected WebElement waitToBeClickable(String query) + { + WebDriverWait wait = new WebDriverWait(driver, 5); + + return wait.until( + ExpectedConditions.elementToBeClickable(By.cssSelector(query))); + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + protected WebDriver driver; + + /** Field description */ + private String baseUrl; +}