mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-06 05:25:44 +01:00
Merged in feature/repository_namespaces (pull request #52)
Feature/repository namespaces
This commit is contained in:
19
pom.xml
19
pom.xml
@@ -225,6 +225,23 @@
|
|||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.github.legman</groupId>
|
||||||
|
<artifactId>legman-maven-plugin</artifactId>
|
||||||
|
<version>${legman.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<fail>true</fail>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>process-classes</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>guava-migration-check</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
@@ -513,7 +530,7 @@
|
|||||||
<guice.version>4.0</guice.version>
|
<guice.version>4.0</guice.version>
|
||||||
|
|
||||||
<!-- event bus -->
|
<!-- event bus -->
|
||||||
<legman.version>1.2.0</legman.version>
|
<legman.version>1.3.0</legman.version>
|
||||||
|
|
||||||
<!-- webserver -->
|
<!-- webserver -->
|
||||||
<jetty.version>9.2.10.v20150310</jetty.version>
|
<jetty.version>9.2.10.v20150310</jetty.version>
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2010, Sebastian Sdorra
|
* Copyright (c) 2010, Sebastian Sdorra
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
* <p>
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
*
|
* <p>
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
* 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
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
* contributors may be used to endorse or promote products derived from this
|
* contributors may be used to endorse or promote products derived from this
|
||||||
* software without specific prior written permission.
|
* software without specific prior written permission.
|
||||||
*
|
* <p>
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
@@ -24,39 +24,32 @@
|
|||||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
* <p>
|
||||||
* http://bitbucket.org/sdorra/scm-manager
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package sonia.scm.config;
|
package sonia.scm.config;
|
||||||
|
|
||||||
//~--- non-JDK imports --------------------------------------------------------
|
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import sonia.scm.event.ScmEventBus;
|
import sonia.scm.event.ScmEventBus;
|
||||||
import sonia.scm.util.HttpUtil;
|
import sonia.scm.util.HttpUtil;
|
||||||
import sonia.scm.xml.XmlSetStringAdapter;
|
import sonia.scm.xml.XmlSetStringAdapter;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlAccessType;
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main configuration object for SCM-Manager.
|
* The main configuration object for SCM-Manager.
|
||||||
@@ -67,38 +60,137 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
|||||||
@Singleton
|
@Singleton
|
||||||
@XmlRootElement(name = "scm-config")
|
@XmlRootElement(name = "scm-config")
|
||||||
@XmlAccessorType(XmlAccessType.FIELD)
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
public class ScmConfiguration
|
public class ScmConfiguration {
|
||||||
{
|
|
||||||
|
|
||||||
/** Default JavaScript date format */
|
/**
|
||||||
|
* Default JavaScript date format
|
||||||
|
*/
|
||||||
public static final String DEFAULT_DATEFORMAT = "YYYY-MM-DD HH:mm:ss";
|
public static final String DEFAULT_DATEFORMAT = "YYYY-MM-DD HH:mm:ss";
|
||||||
|
|
||||||
/** Default plugin url */
|
/**
|
||||||
|
* Default plugin url
|
||||||
|
*/
|
||||||
public static final String DEFAULT_PLUGINURL =
|
public static final String DEFAULT_PLUGINURL =
|
||||||
"http://plugins.scm-manager.org/scm-plugin-backend/api/{version}/plugins?os={os}&arch={arch}&snapshot=false";
|
"http://plugins.scm-manager.org/scm-plugin-backend/api/{version}/plugins?os={os}&arch={arch}&snapshot=false";
|
||||||
|
|
||||||
/** Default plugin url from version 1.0 */
|
/**
|
||||||
|
* Default plugin url from version 1.0
|
||||||
|
*/
|
||||||
public static final String OLD_PLUGINURL =
|
public static final String OLD_PLUGINURL =
|
||||||
"http://plugins.scm-manager.org/plugins.xml.gz";
|
"http://plugins.scm-manager.org/plugins.xml.gz";
|
||||||
|
|
||||||
/** Path to the configuration file */
|
/**
|
||||||
|
* Path to the configuration file
|
||||||
|
*/
|
||||||
public static final String PATH =
|
public static final String PATH =
|
||||||
"config".concat(File.separator).concat("config.xml");
|
"config".concat(File.separator).concat("config.xml");
|
||||||
|
|
||||||
/** the logger for ScmConfiguration */
|
/**
|
||||||
|
* the logger for ScmConfiguration
|
||||||
|
*/
|
||||||
private static final Logger logger =
|
private static final Logger logger =
|
||||||
LoggerFactory.getLogger(ScmConfiguration.class);
|
LoggerFactory.getLogger(ScmConfiguration.class);
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
|
||||||
|
@XmlElement(name = "admin-groups")
|
||||||
|
@XmlJavaTypeAdapter(XmlSetStringAdapter.class)
|
||||||
|
private Set<String> adminGroups;
|
||||||
|
|
||||||
|
|
||||||
|
@XmlElement(name = "admin-users")
|
||||||
|
@XmlJavaTypeAdapter(XmlSetStringAdapter.class)
|
||||||
|
private Set<String> adminUsers;
|
||||||
|
|
||||||
|
|
||||||
|
@XmlElement(name = "base-url")
|
||||||
|
private String baseUrl;
|
||||||
|
|
||||||
|
|
||||||
|
@XmlElement(name = "force-base-url")
|
||||||
|
private boolean forceBaseUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum allowed login attempts.
|
||||||
|
*
|
||||||
|
* @since 1.34
|
||||||
|
*/
|
||||||
|
@XmlElement(name = "login-attempt-limit")
|
||||||
|
private int loginAttemptLimit = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* glob patterns for urls which are excluded from proxy
|
||||||
|
*/
|
||||||
|
@XmlElement(name = "proxy-excludes")
|
||||||
|
@XmlJavaTypeAdapter(XmlSetStringAdapter.class)
|
||||||
|
private Set<String> proxyExcludes;
|
||||||
|
|
||||||
|
|
||||||
|
private String proxyPassword;
|
||||||
|
|
||||||
|
|
||||||
|
private int proxyPort = 8080;
|
||||||
|
|
||||||
|
|
||||||
|
private String proxyServer = "proxy.mydomain.com";
|
||||||
|
|
||||||
|
|
||||||
|
private String proxyUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skip failed authenticators.
|
||||||
|
*
|
||||||
|
* @since 1.36
|
||||||
|
*/
|
||||||
|
@XmlElement(name = "skip-failed-authenticators")
|
||||||
|
private boolean skipFailedAuthenticators = false;
|
||||||
|
|
||||||
|
|
||||||
|
@XmlElement(name = "plugin-url")
|
||||||
|
private String pluginUrl = DEFAULT_PLUGINURL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Login attempt timeout.
|
||||||
|
*
|
||||||
|
* @since 1.34
|
||||||
|
*/
|
||||||
|
@XmlElement(name = "login-attempt-limit-timeout")
|
||||||
|
private long loginAttemptLimitTimeout = TimeUnit.MINUTES.toSeconds(5l);
|
||||||
|
|
||||||
|
|
||||||
|
private boolean enableProxy = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authentication realm for basic authentication.
|
||||||
|
*/
|
||||||
|
private String realmDescription = HttpUtil.AUTHENTICATION_REALM;
|
||||||
|
private boolean enableRepositoryArchive = false;
|
||||||
|
private boolean disableGroupingGrid = false;
|
||||||
|
/**
|
||||||
|
* JavaScript date format from moment.js
|
||||||
|
*
|
||||||
|
* @see <a href="http://momentjs.com/docs/#/parsing/" target="_blank">http://momentjs.com/docs/#/parsing/</a>
|
||||||
|
*/
|
||||||
|
private String dateFormat = DEFAULT_DATEFORMAT;
|
||||||
|
private boolean anonymousAccessEnabled = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables xsrf cookie protection.
|
||||||
|
*
|
||||||
|
* @since 1.47
|
||||||
|
*/
|
||||||
|
@XmlElement(name = "xsrf-protection")
|
||||||
|
private boolean enabledXsrfProtection = true;
|
||||||
|
|
||||||
|
@XmlElement(name = "default-namespace-strategy")
|
||||||
|
private String defaultNamespaceStrategy = "sonia.scm.repository.DefaultNamespaceStrategy";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls the {@link sonia.scm.ConfigChangedListener#configChanged(Object)}
|
* Calls the {@link sonia.scm.ConfigChangedListener#configChanged(Object)}
|
||||||
* method of all registered listeners.
|
* method of all registered listeners.
|
||||||
*/
|
*/
|
||||||
public void fireChangeEvent()
|
public void fireChangeEvent() {
|
||||||
{
|
if (logger.isDebugEnabled()) {
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
{
|
|
||||||
logger.debug("fire config changed event");
|
logger.debug("fire config changed event");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,12 +201,9 @@ public class ScmConfiguration
|
|||||||
/**
|
/**
|
||||||
* Load all properties from another {@link ScmConfiguration} object.
|
* Load all properties from another {@link ScmConfiguration} object.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param other
|
* @param other
|
||||||
*/
|
*/
|
||||||
public void load(ScmConfiguration other)
|
public void load(ScmConfiguration other) {
|
||||||
{
|
|
||||||
this.realmDescription = other.realmDescription;
|
this.realmDescription = other.realmDescription;
|
||||||
this.dateFormat = other.dateFormat;
|
this.dateFormat = other.dateFormat;
|
||||||
this.pluginUrl = other.pluginUrl;
|
this.pluginUrl = other.pluginUrl;
|
||||||
@@ -135,29 +224,14 @@ public class ScmConfiguration
|
|||||||
this.loginAttemptLimit = other.loginAttemptLimit;
|
this.loginAttemptLimit = other.loginAttemptLimit;
|
||||||
this.loginAttemptLimitTimeout = other.loginAttemptLimitTimeout;
|
this.loginAttemptLimitTimeout = other.loginAttemptLimitTimeout;
|
||||||
this.enabledXsrfProtection = other.enabledXsrfProtection;
|
this.enabledXsrfProtection = other.enabledXsrfProtection;
|
||||||
|
this.defaultNamespaceStrategy = other.defaultNamespaceStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
public Set<String> getAdminGroups() {
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a set of admin group names.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return set of admin group names
|
|
||||||
*/
|
|
||||||
public Set<String> getAdminGroups()
|
|
||||||
{
|
|
||||||
return adminGroups;
|
return adminGroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public Set<String> getAdminUsers() {
|
||||||
* Returns a set of admin user names.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return set of admin user names
|
|
||||||
*/
|
|
||||||
public Set<String> getAdminUsers()
|
|
||||||
{
|
|
||||||
return adminUsers;
|
return adminUsers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,11 +239,10 @@ public class ScmConfiguration
|
|||||||
* Returns the complete base url of the scm-manager including the context path.
|
* Returns the complete base url of the scm-manager including the context path.
|
||||||
* For example http://localhost:8080/scm
|
* For example http://localhost:8080/scm
|
||||||
*
|
*
|
||||||
* @since 1.5
|
|
||||||
* @return complete base url of the scm-manager
|
* @return complete base url of the scm-manager
|
||||||
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public String getBaseUrl()
|
public String getBaseUrl() {
|
||||||
{
|
|
||||||
return baseUrl;
|
return baseUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,23 +250,14 @@ public class ScmConfiguration
|
|||||||
* Returns the date format for the user interface. This format is a
|
* Returns the date format for the user interface. This format is a
|
||||||
* JavaScript date format, from the library moment.js.
|
* JavaScript date format, from the library moment.js.
|
||||||
*
|
*
|
||||||
* @see <a href="http://momentjs.com/docs/#/parsing/" target="_blank">http://momentjs.com/docs/#/parsing/</a>
|
|
||||||
* @return moment.js date format
|
* @return moment.js date format
|
||||||
|
* @see <a href="http://momentjs.com/docs/#/parsing/" target="_blank">http://momentjs.com/docs/#/parsing/</a>
|
||||||
*/
|
*/
|
||||||
public String getDateFormat()
|
public String getDateFormat() {
|
||||||
{
|
|
||||||
return dateFormat;
|
return dateFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public int getLoginAttemptLimit() {
|
||||||
* Returns maximum allowed login attempts.
|
|
||||||
*
|
|
||||||
* @return maximum allowed login attempts
|
|
||||||
*
|
|
||||||
* @since 1.34
|
|
||||||
*/
|
|
||||||
public int getLoginAttemptLimit()
|
|
||||||
{
|
|
||||||
return loginAttemptLimit;
|
return loginAttemptLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,11 +266,9 @@ public class ScmConfiguration
|
|||||||
* because of too many failed login attempts.
|
* because of too many failed login attempts.
|
||||||
*
|
*
|
||||||
* @return login attempt timeout in seconds
|
* @return login attempt timeout in seconds
|
||||||
*
|
|
||||||
* @since 1.34
|
* @since 1.34
|
||||||
*/
|
*/
|
||||||
public long getLoginAttemptLimitTimeout()
|
public long getLoginAttemptLimitTimeout() {
|
||||||
{
|
|
||||||
return loginAttemptLimitTimeout;
|
return loginAttemptLimitTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,8 +284,7 @@ public class ScmConfiguration
|
|||||||
*
|
*
|
||||||
* @return the complete plugin url.
|
* @return the complete plugin url.
|
||||||
*/
|
*/
|
||||||
public String getPluginUrl()
|
public String getPluginUrl() {
|
||||||
{
|
|
||||||
return pluginUrl;
|
return pluginUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,289 +292,141 @@ public class ScmConfiguration
|
|||||||
* Returns a set of glob patterns for urls which should excluded from
|
* Returns a set of glob patterns for urls which should excluded from
|
||||||
* proxy settings.
|
* proxy settings.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @return set of glob patterns
|
* @return set of glob patterns
|
||||||
* @since 1.23
|
* @since 1.23
|
||||||
*/
|
*/
|
||||||
public Set<String> getProxyExcludes()
|
public Set<String> getProxyExcludes() {
|
||||||
{
|
if (proxyExcludes == null) {
|
||||||
if (proxyExcludes == null)
|
|
||||||
{
|
|
||||||
proxyExcludes = Sets.newHashSet();
|
proxyExcludes = Sets.newHashSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
return proxyExcludes;
|
return proxyExcludes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public String getProxyPassword() {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* @since 1.7
|
|
||||||
*/
|
|
||||||
public String getProxyPassword()
|
|
||||||
{
|
|
||||||
return proxyPassword;
|
return proxyPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public int getProxyPort() {
|
||||||
* Returns the proxy port.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return proxy port
|
|
||||||
*/
|
|
||||||
public int getProxyPort()
|
|
||||||
{
|
|
||||||
return proxyPort;
|
return proxyPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the servername or ip of the proxyserver.
|
* Returns the servername or ip of the proxyserver.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @return servername or ip of the proxyserver
|
* @return servername or ip of the proxyserver
|
||||||
*/
|
*/
|
||||||
public String getProxyServer()
|
public String getProxyServer() {
|
||||||
{
|
|
||||||
return proxyServer;
|
return proxyServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public String getProxyUser() {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* @since 1.7
|
|
||||||
*/
|
|
||||||
public String getProxyUser()
|
|
||||||
{
|
|
||||||
return proxyUser;
|
return proxyUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public String getRealmDescription() {
|
||||||
* Returns the realm description.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return realm description
|
|
||||||
* @since 1.36
|
|
||||||
*/
|
|
||||||
public String getRealmDescription()
|
|
||||||
{
|
|
||||||
return realmDescription;
|
return realmDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAnonymousAccessEnabled() {
|
||||||
/**
|
|
||||||
* Returns true if the anonymous access to the SCM-Manager is enabled.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return true if the anonymous access to the SCM-Manager is enabled
|
|
||||||
*/
|
|
||||||
public boolean isAnonymousAccessEnabled()
|
|
||||||
{
|
|
||||||
return anonymousAccessEnabled;
|
return anonymousAccessEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public boolean isDisableGroupingGrid() {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
* @since 1.9
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public boolean isDisableGroupingGrid()
|
|
||||||
{
|
|
||||||
return disableGroupingGrid;
|
return disableGroupingGrid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns {@code true} if the cookie xsrf protection is enabled.
|
* Returns {@code true} if the cookie xsrf protection is enabled.
|
||||||
*
|
*
|
||||||
* @see <a href="https://goo.gl/s67xO3">Issue 793</a>
|
|
||||||
* @return {@code true} if the cookie xsrf protection is enabled
|
* @return {@code true} if the cookie xsrf protection is enabled
|
||||||
*
|
* @see <a href="https://goo.gl/s67xO3">Issue 793</a>
|
||||||
* @since 1.47
|
* @since 1.47
|
||||||
*/
|
*/
|
||||||
public boolean isEnabledXsrfProtection()
|
public boolean isEnabledXsrfProtection() {
|
||||||
{
|
|
||||||
return enabledXsrfProtection;
|
return enabledXsrfProtection;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public boolean isEnableProxy() {
|
||||||
* Returns true if proxy is enabled.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return true if proxy is enabled
|
|
||||||
*/
|
|
||||||
public boolean isEnableProxy()
|
|
||||||
{
|
|
||||||
return enableProxy;
|
return enableProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public boolean isEnableRepositoryArchive() {
|
||||||
* Returns true if the repository archive is enabled.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return true if the repository archive is enabled
|
|
||||||
* @since 1.14
|
|
||||||
*/
|
|
||||||
public boolean isEnableRepositoryArchive()
|
|
||||||
{
|
|
||||||
return enableRepositoryArchive;
|
return enableRepositoryArchive;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public boolean isForceBaseUrl() {
|
||||||
* Returns true if force base url is enabled.
|
|
||||||
*
|
|
||||||
* @since 1.5
|
|
||||||
* @return true if force base url is enabled
|
|
||||||
*/
|
|
||||||
public boolean isForceBaseUrl()
|
|
||||||
{
|
|
||||||
return forceBaseUrl;
|
return forceBaseUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public boolean isLoginAttemptLimitEnabled() {
|
||||||
* Returns true if the login attempt limit is enabled.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return true if login attempt limit is enabled
|
|
||||||
*
|
|
||||||
* @since 1.37
|
|
||||||
*/
|
|
||||||
public boolean isLoginAttemptLimitEnabled()
|
|
||||||
{
|
|
||||||
return loginAttemptLimit > 0;
|
return loginAttemptLimit > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDefaultNamespaceStrategy() {
|
||||||
|
return defaultNamespaceStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if failed authenticators are skipped.
|
* Returns true if failed authenticators are skipped.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @return true if failed authenticators are skipped
|
* @return true if failed authenticators are skipped
|
||||||
*
|
|
||||||
* @since 1.36
|
* @since 1.36
|
||||||
*/
|
*/
|
||||||
public boolean isSkipFailedAuthenticators()
|
public boolean isSkipFailedAuthenticators() {
|
||||||
{
|
|
||||||
return skipFailedAuthenticators;
|
return skipFailedAuthenticators;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- set methods ----------------------------------------------------------
|
public void setAdminGroups(Set<String> adminGroups) {
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param adminGroups
|
|
||||||
*/
|
|
||||||
public void setAdminGroups(Set<String> adminGroups)
|
|
||||||
{
|
|
||||||
this.adminGroups = adminGroups;
|
this.adminGroups = adminGroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setAdminUsers(Set<String> adminUsers) {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param adminUsers
|
|
||||||
*/
|
|
||||||
public void setAdminUsers(Set<String> adminUsers)
|
|
||||||
{
|
|
||||||
this.adminUsers = adminUsers;
|
this.adminUsers = adminUsers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setAnonymousAccessEnabled(boolean anonymousAccessEnabled) {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param anonymousAccessEnabled
|
|
||||||
*/
|
|
||||||
public void setAnonymousAccessEnabled(boolean anonymousAccessEnabled)
|
|
||||||
{
|
|
||||||
this.anonymousAccessEnabled = anonymousAccessEnabled;
|
this.anonymousAccessEnabled = anonymousAccessEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setBaseUrl(String baseUrl) {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param baseUrl
|
|
||||||
* @since 1.5
|
|
||||||
*/
|
|
||||||
public void setBaseUrl(String baseUrl)
|
|
||||||
{
|
|
||||||
this.baseUrl = baseUrl;
|
this.baseUrl = baseUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setDateFormat(String dateFormat) {
|
||||||
* Sets the date format for the ui.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param dateFormat date format for ui
|
|
||||||
*/
|
|
||||||
public void setDateFormat(String dateFormat)
|
|
||||||
{
|
|
||||||
this.dateFormat = dateFormat;
|
this.dateFormat = dateFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setDisableGroupingGrid(boolean disableGroupingGrid) {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
* @since 1.9
|
|
||||||
*
|
|
||||||
* @param disableGroupingGrid
|
|
||||||
*/
|
|
||||||
public void setDisableGroupingGrid(boolean disableGroupingGrid)
|
|
||||||
{
|
|
||||||
this.disableGroupingGrid = disableGroupingGrid;
|
this.disableGroupingGrid = disableGroupingGrid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setEnableProxy(boolean enableProxy) {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param enableProxy
|
|
||||||
*/
|
|
||||||
public void setEnableProxy(boolean enableProxy)
|
|
||||||
{
|
|
||||||
this.enableProxy = enableProxy;
|
this.enableProxy = enableProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable or disable the repository archive. Default is disabled.
|
* Enable or disable the repository archive. Default is disabled.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @param enableRepositoryArchive true to disable the repository archive
|
* @param enableRepositoryArchive true to disable the repository archive
|
||||||
* @since 1.14
|
* @since 1.14
|
||||||
*/
|
*/
|
||||||
public void setEnableRepositoryArchive(boolean enableRepositoryArchive)
|
public void setEnableRepositoryArchive(boolean enableRepositoryArchive) {
|
||||||
{
|
|
||||||
this.enableRepositoryArchive = enableRepositoryArchive;
|
this.enableRepositoryArchive = enableRepositoryArchive;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setForceBaseUrl(boolean forceBaseUrl) {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param forceBaseUrl
|
|
||||||
* @since 1.5
|
|
||||||
*/
|
|
||||||
public void setForceBaseUrl(boolean forceBaseUrl)
|
|
||||||
{
|
|
||||||
this.forceBaseUrl = forceBaseUrl;
|
this.forceBaseUrl = forceBaseUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set maximum allowed login attempts.
|
* Set maximum allowed login attempts.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @param loginAttemptLimit login attempt limit
|
* @param loginAttemptLimit login attempt limit
|
||||||
*
|
|
||||||
* @since 1.34
|
* @since 1.34
|
||||||
*/
|
*/
|
||||||
public void setLoginAttemptLimit(int loginAttemptLimit)
|
public void setLoginAttemptLimit(int loginAttemptLimit) {
|
||||||
{
|
|
||||||
this.loginAttemptLimit = loginAttemptLimit;
|
this.loginAttemptLimit = loginAttemptLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -522,22 +435,13 @@ public class ScmConfiguration
|
|||||||
* because of too many failed login attempts.
|
* because of too many failed login attempts.
|
||||||
*
|
*
|
||||||
* @param loginAttemptLimitTimeout login attempt timeout in seconds
|
* @param loginAttemptLimitTimeout login attempt timeout in seconds
|
||||||
*
|
|
||||||
* @since 1.34
|
* @since 1.34
|
||||||
*/
|
*/
|
||||||
public void setLoginAttemptLimitTimeout(long loginAttemptLimitTimeout)
|
public void setLoginAttemptLimitTimeout(long loginAttemptLimitTimeout) {
|
||||||
{
|
|
||||||
this.loginAttemptLimitTimeout = loginAttemptLimitTimeout;
|
this.loginAttemptLimitTimeout = loginAttemptLimitTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setPluginUrl(String pluginUrl) {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param pluginUrl
|
|
||||||
*/
|
|
||||||
public void setPluginUrl(String pluginUrl)
|
|
||||||
{
|
|
||||||
this.pluginUrl = pluginUrl;
|
this.pluginUrl = pluginUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -545,70 +449,30 @@ public class ScmConfiguration
|
|||||||
* Set glob patterns for urls which are should be excluded from proxy
|
* Set glob patterns for urls which are should be excluded from proxy
|
||||||
* settings.
|
* settings.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @param proxyExcludes glob patterns
|
* @param proxyExcludes glob patterns
|
||||||
* @since 1.23
|
* @since 1.23
|
||||||
*/
|
*/
|
||||||
public void setProxyExcludes(Set<String> proxyExcludes)
|
public void setProxyExcludes(Set<String> proxyExcludes) {
|
||||||
{
|
|
||||||
this.proxyExcludes = proxyExcludes;
|
this.proxyExcludes = proxyExcludes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setProxyPassword(String proxyPassword) {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param proxyPassword
|
|
||||||
* @since 1.7
|
|
||||||
*/
|
|
||||||
public void setProxyPassword(String proxyPassword)
|
|
||||||
{
|
|
||||||
this.proxyPassword = proxyPassword;
|
this.proxyPassword = proxyPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setProxyPort(int proxyPort) {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param proxyPort
|
|
||||||
*/
|
|
||||||
public void setProxyPort(int proxyPort)
|
|
||||||
{
|
|
||||||
this.proxyPort = proxyPort;
|
this.proxyPort = proxyPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setProxyServer(String proxyServer) {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param proxyServer
|
|
||||||
*/
|
|
||||||
public void setProxyServer(String proxyServer)
|
|
||||||
{
|
|
||||||
this.proxyServer = proxyServer;
|
this.proxyServer = proxyServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setProxyUser(String proxyUser) {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param proxyUser
|
|
||||||
* @since 1.7
|
|
||||||
*/
|
|
||||||
public void setProxyUser(String proxyUser)
|
|
||||||
{
|
|
||||||
this.proxyUser = proxyUser;
|
this.proxyUser = proxyUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setRealmDescription(String realmDescription) {
|
||||||
* Sets the realm description.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param realmDescription
|
|
||||||
* @since 1.36
|
|
||||||
*/
|
|
||||||
public void setRealmDescription(String realmDescription)
|
|
||||||
{
|
|
||||||
this.realmDescription = realmDescription;
|
this.realmDescription = realmDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -617,11 +481,9 @@ public class ScmConfiguration
|
|||||||
* authenticator finds the user but fails to authenticate the user.
|
* authenticator finds the user but fails to authenticate the user.
|
||||||
*
|
*
|
||||||
* @param skipFailedAuthenticators true to skip failed authenticators
|
* @param skipFailedAuthenticators true to skip failed authenticators
|
||||||
*
|
|
||||||
* @since 1.36
|
* @since 1.36
|
||||||
*/
|
*/
|
||||||
public void setSkipFailedAuthenticators(boolean skipFailedAuthenticators)
|
public void setSkipFailedAuthenticators(boolean skipFailedAuthenticators) {
|
||||||
{
|
|
||||||
this.skipFailedAuthenticators = skipFailedAuthenticators;
|
this.skipFailedAuthenticators = skipFailedAuthenticators;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -630,109 +492,13 @@ public class ScmConfiguration
|
|||||||
*
|
*
|
||||||
* @param enabledXsrfProtection {@code true} to enable xsrf protection
|
* @param enabledXsrfProtection {@code true} to enable xsrf protection
|
||||||
* @see <a href="https://goo.gl/s67xO3">Issue 793</a>
|
* @see <a href="https://goo.gl/s67xO3">Issue 793</a>
|
||||||
*
|
|
||||||
* @since 1.47
|
* @since 1.47
|
||||||
*/
|
*/
|
||||||
public void setEnabledXsrfProtection(boolean enabledXsrfProtection)
|
public void setEnabledXsrfProtection(boolean enabledXsrfProtection) {
|
||||||
{
|
|
||||||
this.enabledXsrfProtection = enabledXsrfProtection;
|
this.enabledXsrfProtection = enabledXsrfProtection;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- fields ---------------------------------------------------------------
|
public void setDefaultNamespaceStrategy(String defaultNamespaceStrategy) {
|
||||||
|
this.defaultNamespaceStrategy = defaultNamespaceStrategy;
|
||||||
/** Field description */
|
}
|
||||||
@XmlElement(name = "admin-groups")
|
|
||||||
@XmlJavaTypeAdapter(XmlSetStringAdapter.class)
|
|
||||||
private Set<String> adminGroups;
|
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
@XmlElement(name = "admin-users")
|
|
||||||
@XmlJavaTypeAdapter(XmlSetStringAdapter.class)
|
|
||||||
private Set<String> adminUsers;
|
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
@XmlElement(name = "base-url")
|
|
||||||
private String baseUrl;
|
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
@XmlElement(name = "force-base-url")
|
|
||||||
private boolean forceBaseUrl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maximum allowed login attempts.
|
|
||||||
*
|
|
||||||
* @since 1.34
|
|
||||||
*/
|
|
||||||
@XmlElement(name = "login-attempt-limit")
|
|
||||||
private int loginAttemptLimit = -1;
|
|
||||||
|
|
||||||
/** glob patterns for urls which are excluded from proxy */
|
|
||||||
@XmlElement(name = "proxy-excludes")
|
|
||||||
@XmlJavaTypeAdapter(XmlSetStringAdapter.class)
|
|
||||||
private Set<String> proxyExcludes;
|
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
private String proxyPassword;
|
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
private int proxyPort = 8080;
|
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
private String proxyServer = "proxy.mydomain.com";
|
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
private String proxyUser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Skip failed authenticators.
|
|
||||||
*
|
|
||||||
* @since 1.36
|
|
||||||
*/
|
|
||||||
@XmlElement(name = "skip-failed-authenticators")
|
|
||||||
private boolean skipFailedAuthenticators = false;
|
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
@XmlElement(name = "plugin-url")
|
|
||||||
private String pluginUrl = DEFAULT_PLUGINURL;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Login attempt timeout.
|
|
||||||
*
|
|
||||||
* @since 1.34
|
|
||||||
*/
|
|
||||||
@XmlElement(name = "login-attempt-limit-timeout")
|
|
||||||
private long loginAttemptLimitTimeout = TimeUnit.MINUTES.toSeconds(5l);
|
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
private boolean enableProxy = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Authentication realm for basic authentication.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private String realmDescription = HttpUtil.AUTHENTICATION_REALM;
|
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
private boolean enableRepositoryArchive = false;
|
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
private boolean disableGroupingGrid = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JavaScript date format from moment.js
|
|
||||||
* @see <a href="http://momentjs.com/docs/#/parsing/" target="_blank">http://momentjs.com/docs/#/parsing/</a>
|
|
||||||
*/
|
|
||||||
private String dateFormat = DEFAULT_DATEFORMAT;
|
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
private boolean anonymousAccessEnabled = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enables xsrf cookie protection.
|
|
||||||
*
|
|
||||||
* @since 1.47
|
|
||||||
*/
|
|
||||||
@XmlElement(name = "xsrf-protection")
|
|
||||||
private boolean enabledXsrfProtection = true;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,19 +36,16 @@ package sonia.scm.repository;
|
|||||||
//~--- non-JDK imports --------------------------------------------------------
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import sonia.scm.repository.ImportResult.Builder;
|
import sonia.scm.repository.ImportResult.Builder;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class for directory based {@link ImportHandler} and
|
* Abstract base class for directory based {@link ImportHandler} and
|
||||||
* {@link AdvancedImportHandler}.
|
* {@link AdvancedImportHandler}.
|
||||||
@@ -164,23 +161,24 @@ public abstract class AbstactImportHandler implements AdvancedImportHandler
|
|||||||
|
|
||||||
logger.trace("search for repositories to import");
|
logger.trace("search for repositories to import");
|
||||||
|
|
||||||
try
|
// TODO #8783
|
||||||
{
|
// try
|
||||||
|
// {
|
||||||
List<String> repositoryNames =
|
//
|
||||||
RepositoryUtil.getRepositoryNames(getRepositoryHandler(),
|
// List<String> repositoryNames =
|
||||||
getDirectoryNames());
|
// RepositoryUtil.getRepositoryNames(getRepositoryHandler(),
|
||||||
|
// getDirectoryNames());
|
||||||
for (String repositoryName : repositoryNames)
|
//
|
||||||
{
|
// for (String repositoryName : repositoryNames)
|
||||||
importRepository(manager, builder, throwExceptions, repositoryName);
|
// {
|
||||||
}
|
// importRepository(manager, builder, throwExceptions, repositoryName);
|
||||||
|
// }
|
||||||
}
|
//
|
||||||
catch (IOException ex)
|
// }
|
||||||
{
|
// catch (IOException ex)
|
||||||
handleException(ex, throwExceptions);
|
// {
|
||||||
}
|
// handleException(ex, throwExceptions);
|
||||||
|
// }
|
||||||
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
@@ -214,46 +212,48 @@ public abstract class AbstactImportHandler implements AdvancedImportHandler
|
|||||||
* @param manager
|
* @param manager
|
||||||
* @param builder
|
* @param builder
|
||||||
* @param throwExceptions
|
* @param throwExceptions
|
||||||
* @param repositoryName
|
* @param directoryName
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* @throws RepositoryException
|
* @throws RepositoryException
|
||||||
*/
|
*/
|
||||||
private void importRepository(RepositoryManager manager, Builder builder,
|
private void importRepository(RepositoryManager manager, Builder builder,
|
||||||
boolean throwExceptions, String repositoryName)
|
boolean throwExceptions, String directoryName)
|
||||||
throws IOException, RepositoryException
|
throws IOException, RepositoryException
|
||||||
{
|
{
|
||||||
logger.trace("check repository {} for import", repositoryName);
|
logger.trace("check repository {} for import", directoryName);
|
||||||
|
|
||||||
Repository repository = manager.get(getTypeName(), repositoryName);
|
// TODO #8783
|
||||||
|
//
|
||||||
if (repository == null)
|
// Repository repository = manager.get(namespaceAndName);
|
||||||
{
|
//
|
||||||
try
|
// if (repository == null)
|
||||||
{
|
// {
|
||||||
importRepository(manager, repositoryName);
|
// try
|
||||||
builder.addImportedDirectory(repositoryName);
|
// {
|
||||||
}
|
// importRepository(manager, repositoryName);
|
||||||
catch (IOException ex)
|
// builder.addImportedDirectory(repositoryName);
|
||||||
{
|
// }
|
||||||
builder.addFailedDirectory(repositoryName);
|
// catch (IOException ex)
|
||||||
handleException(ex, throwExceptions);
|
// {
|
||||||
}
|
// builder.addFailedDirectory(repositoryName);
|
||||||
catch (IllegalStateException ex)
|
// handleException(ex, throwExceptions);
|
||||||
{
|
// }
|
||||||
builder.addFailedDirectory(repositoryName);
|
// catch (IllegalStateException ex)
|
||||||
handleException(ex, throwExceptions);
|
// {
|
||||||
}
|
// builder.addFailedDirectory(repositoryName);
|
||||||
catch (RepositoryException ex)
|
// handleException(ex, throwExceptions);
|
||||||
{
|
// }
|
||||||
builder.addFailedDirectory(repositoryName);
|
// catch (RepositoryException ex)
|
||||||
handleException(ex, throwExceptions);
|
// {
|
||||||
}
|
// builder.addFailedDirectory(repositoryName);
|
||||||
}
|
// handleException(ex, throwExceptions);
|
||||||
else if (logger.isDebugEnabled())
|
// }
|
||||||
{
|
// }
|
||||||
logger.debug("repository {} is allready managed", repositoryName);
|
// else if (logger.isDebugEnabled())
|
||||||
}
|
// {
|
||||||
|
// logger.debug("repository {} is already managed", repositoryName);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2010, Sebastian Sdorra
|
* Copyright (c) 2010, Sebastian Sdorra
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
* <p>
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
*
|
* <p>
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
* 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
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
* contributors may be used to endorse or promote products derived from this
|
* contributors may be used to endorse or promote products derived from this
|
||||||
* software without specific prior written permission.
|
* software without specific prior written permission.
|
||||||
*
|
* <p>
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
@@ -24,13 +24,11 @@
|
|||||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
* <p>
|
||||||
* http://bitbucket.org/sdorra/scm-manager
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package sonia.scm.repository;
|
package sonia.scm.repository;
|
||||||
|
|
||||||
//~--- non-JDK imports --------------------------------------------------------
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
@@ -54,91 +52,56 @@ import java.net.URL;
|
|||||||
//~--- JDK imports ------------------------------------------------------------
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Sebastian Sdorra
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param <C>
|
* @param <C>
|
||||||
|
* @author Sebastian Sdorra
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractSimpleRepositoryHandler<C extends SimpleRepositoryConfig>
|
public abstract class AbstractSimpleRepositoryHandler<C extends SimpleRepositoryConfig>
|
||||||
extends AbstractRepositoryHandler<C> implements RepositoryDirectoryHandler
|
extends AbstractRepositoryHandler<C> implements RepositoryDirectoryHandler {
|
||||||
{
|
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
public static final String DEFAULT_VERSION_INFORMATION = "unknown";
|
public static final String DEFAULT_VERSION_INFORMATION = "unknown";
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
public static final String DIRECTORY_REPOSITORY = "repositories";
|
public static final String DIRECTORY_REPOSITORY = "repositories";
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
public static final String DOT = ".";
|
public static final String DOT = ".";
|
||||||
|
|
||||||
/** the logger for AbstractSimpleRepositoryHandler */
|
/**
|
||||||
|
* the logger for AbstractSimpleRepositoryHandler
|
||||||
|
*/
|
||||||
private static final Logger logger =
|
private static final Logger logger =
|
||||||
LoggerFactory.getLogger(AbstractSimpleRepositoryHandler.class);
|
LoggerFactory.getLogger(AbstractSimpleRepositoryHandler.class);
|
||||||
|
|
||||||
//~--- constructors ---------------------------------------------------------
|
private FileSystem fileSystem;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs ...
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param storeFactory
|
|
||||||
* @param fileSystem
|
|
||||||
*/
|
|
||||||
public AbstractSimpleRepositoryHandler(ConfigurationStoreFactory storeFactory,
|
public AbstractSimpleRepositoryHandler(ConfigurationStoreFactory storeFactory,
|
||||||
FileSystem fileSystem)
|
FileSystem fileSystem) {
|
||||||
{
|
|
||||||
super(storeFactory);
|
super(storeFactory);
|
||||||
this.fileSystem = fileSystem;
|
this.fileSystem = fileSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repository
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Repository create(Repository repository)
|
public Repository create(Repository repository)
|
||||||
throws RepositoryException
|
throws RepositoryException {
|
||||||
{
|
|
||||||
File directory = getDirectory(repository);
|
File directory = getDirectory(repository);
|
||||||
|
|
||||||
if (directory.exists())
|
if (directory.exists()) {
|
||||||
{
|
|
||||||
throw RepositoryAlreadyExistsException.create(repository);
|
throw RepositoryAlreadyExistsException.create(repository);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkPath(directory);
|
checkPath(directory);
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
fileSystem.create(directory);
|
fileSystem.create(directory);
|
||||||
create(repository, directory);
|
create(repository, directory);
|
||||||
postCreate(repository, directory);
|
postCreate(repository, directory);
|
||||||
return repository;
|
return repository;
|
||||||
}
|
} catch (Exception ex) {
|
||||||
catch (Exception ex)
|
if (directory.exists()) {
|
||||||
{
|
logger.warn("delete repository directory {}, because of failed repository creation", directory);
|
||||||
if (directory.exists())
|
|
||||||
{
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
{
|
|
||||||
logger.debug(
|
|
||||||
"delete repository directory {}, because of failed repository creation",
|
|
||||||
directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fileSystem.destroy(directory);
|
fileSystem.destroy(directory);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.error("could not delete directory after failed repository creation: {}", directory, e);
|
logger.error("Could not destroy directory", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,40 +111,21 @@ public abstract class AbstractSimpleRepositoryHandler<C extends SimpleRepository
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repository
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String createResourcePath(Repository repository)
|
public String createResourcePath(Repository repository) {
|
||||||
{
|
|
||||||
StringBuilder path = new StringBuilder("/");
|
StringBuilder path = new StringBuilder("/");
|
||||||
|
|
||||||
path.append(getType().getName()).append("/").append(repository.getName());
|
path.append(getType().getName()).append("/").append(repository.getId());
|
||||||
|
|
||||||
return path.toString();
|
return path.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repository
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void delete(Repository repository) throws RepositoryException
|
public void delete(Repository repository)
|
||||||
{
|
throws RepositoryException {
|
||||||
File directory = getDirectory(repository);
|
File directory = getDirectory(repository);
|
||||||
|
|
||||||
if (directory.exists())
|
if (directory.exists()) {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
fileSystem.destroy(directory);
|
fileSystem.destroy(directory);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -189,32 +133,22 @@ public abstract class AbstractSimpleRepositoryHandler<C extends SimpleRepository
|
|||||||
}
|
}
|
||||||
cleanupEmptyDirectories(config.getRepositoryDirectory(),
|
cleanupEmptyDirectories(config.getRepositoryDirectory(),
|
||||||
directory.getParentFile());
|
directory.getParentFile());
|
||||||
}
|
} else {
|
||||||
else if (logger.isWarnEnabled())
|
logger.warn("repository {} not found", repository.getNamespaceAndName());
|
||||||
{
|
|
||||||
logger.warn("repository {} not found", repository);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void loadConfig()
|
public void loadConfig() {
|
||||||
{
|
|
||||||
super.loadConfig();
|
super.loadConfig();
|
||||||
|
|
||||||
if (config == null)
|
if (config == null) {
|
||||||
{
|
|
||||||
config = createInitialConfig();
|
config = createInitialConfig();
|
||||||
|
|
||||||
if (config != null)
|
if (config != null) {
|
||||||
{
|
|
||||||
File repositoryDirectory = config.getRepositoryDirectory();
|
File repositoryDirectory = config.getRepositoryDirectory();
|
||||||
|
|
||||||
if (repositoryDirectory == null)
|
if (repositoryDirectory == null) {
|
||||||
{
|
|
||||||
repositoryDirectory = new File(
|
repositoryDirectory = new File(
|
||||||
baseDirectory,
|
baseDirectory,
|
||||||
DIRECTORY_REPOSITORY.concat(File.separator).concat(
|
DIRECTORY_REPOSITORY.concat(File.separator).concat(
|
||||||
@@ -228,107 +162,51 @@ public abstract class AbstractSimpleRepositoryHandler<C extends SimpleRepository
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repository
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void modify(Repository repository) throws RepositoryException
|
public void modify(Repository repository) {
|
||||||
{
|
|
||||||
|
|
||||||
// nothing todo
|
// nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repository
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public File getDirectory(Repository repository)
|
public File getDirectory(Repository repository) {
|
||||||
{
|
|
||||||
File directory = null;
|
File directory = null;
|
||||||
|
|
||||||
if (isConfigured())
|
if (isConfigured()) {
|
||||||
{
|
|
||||||
File repositoryDirectory = config.getRepositoryDirectory();
|
File repositoryDirectory = config.getRepositoryDirectory();
|
||||||
|
|
||||||
directory = new File(repositoryDirectory, repository.getName());
|
directory = new File(repositoryDirectory, repository.getId());
|
||||||
|
|
||||||
if (!IOUtil.isChild(repositoryDirectory, directory))
|
if (!IOUtil.isChild(repositoryDirectory, directory)) {
|
||||||
{
|
|
||||||
StringBuilder msg = new StringBuilder(directory.getPath());
|
StringBuilder msg = new StringBuilder(directory.getPath());
|
||||||
|
|
||||||
msg.append("is not a child of ").append(repositoryDirectory.getPath());
|
msg.append("is not a child of ").append(repositoryDirectory.getPath());
|
||||||
|
|
||||||
throw new ConfigurationException(msg.toString());
|
throw new ConfigurationException(msg.toString());
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new ConfigurationException("RepositoryHandler is not configured");
|
throw new ConfigurationException("RepositoryHandler is not configured");
|
||||||
}
|
}
|
||||||
|
|
||||||
return directory;
|
return directory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getVersionInformation()
|
public String getVersionInformation() {
|
||||||
{
|
|
||||||
return DEFAULT_VERSION_INFORMATION;
|
return DEFAULT_VERSION_INFORMATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repository
|
|
||||||
* @param directory
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
protected ExtendedCommand buildCreateCommand(Repository repository,
|
protected ExtendedCommand buildCreateCommand(Repository repository,
|
||||||
File directory)
|
File directory) {
|
||||||
{
|
|
||||||
throw new UnsupportedOperationException("method is not implemented");
|
throw new UnsupportedOperationException("method is not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repository
|
|
||||||
* @param directory
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
protected void create(Repository repository, File directory)
|
protected void create(Repository repository, File directory)
|
||||||
throws RepositoryException, IOException
|
throws RepositoryException, IOException {
|
||||||
{
|
|
||||||
ExtendedCommand cmd = buildCreateCommand(repository, directory);
|
ExtendedCommand cmd = buildCreateCommand(repository, directory);
|
||||||
CommandResult result = cmd.execute();
|
CommandResult result = cmd.execute();
|
||||||
|
|
||||||
if (!result.isSuccessfull())
|
if (!result.isSuccessfull()) {
|
||||||
{
|
|
||||||
StringBuilder msg = new StringBuilder("command exit with error ");
|
StringBuilder msg = new StringBuilder("command exit with error ");
|
||||||
|
|
||||||
msg.append(result.getReturnCode()).append(" and message: '");
|
msg.append(result.getReturnCode()).append(" and message: '");
|
||||||
@@ -338,56 +216,31 @@ public abstract class AbstractSimpleRepositoryHandler<C extends SimpleRepository
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected C createInitialConfig() {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
protected C createInitialConfig()
|
|
||||||
{
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repository
|
|
||||||
* @param directory
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
protected void postCreate(Repository repository, File directory)
|
protected void postCreate(Repository repository, File directory)
|
||||||
throws IOException, RepositoryException {}
|
throws IOException, RepositoryException {
|
||||||
|
}
|
||||||
//~--- get methods ----------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the content of a classpath resource or the given default content.
|
* Returns the content of a classpath resource or the given default content.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @param resource path of a classpath resource
|
* @param resource path of a classpath resource
|
||||||
* @param defaultContent default content to return
|
* @param defaultContent default content to return
|
||||||
*
|
|
||||||
* @return content of a classpath resource or defaultContent
|
* @return content of a classpath resource or defaultContent
|
||||||
*/
|
*/
|
||||||
protected String getStringFromResource(String resource, String defaultContent)
|
protected String getStringFromResource(String resource, String defaultContent) {
|
||||||
{
|
|
||||||
String content = defaultContent;
|
String content = defaultContent;
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
URL url = Resources.getResource(resource);
|
URL url = Resources.getResource(resource);
|
||||||
|
|
||||||
if (url != null)
|
if (url != null) {
|
||||||
{
|
|
||||||
content = Resources.toString(url, Charsets.UTF_8);
|
content = Resources.toString(url, Charsets.UTF_8);
|
||||||
}
|
}
|
||||||
}
|
} catch (IOException ex) {
|
||||||
catch (IOException ex)
|
|
||||||
{
|
|
||||||
logger.error("could not read resource", ex);
|
logger.error("could not read resource", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,45 +250,29 @@ public abstract class AbstractSimpleRepositoryHandler<C extends SimpleRepository
|
|||||||
/**
|
/**
|
||||||
* Returns true if the directory is a repository.
|
* Returns true if the directory is a repository.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @param directory directory to check
|
* @param directory directory to check
|
||||||
*
|
|
||||||
* @return true if the directory is a repository
|
* @return true if the directory is a repository
|
||||||
* @since 1.9
|
* @since 1.9
|
||||||
*/
|
*/
|
||||||
protected boolean isRepository(File directory)
|
protected boolean isRepository(File directory) {
|
||||||
{
|
|
||||||
return new File(directory, DOT.concat(getType().getName())).exists();
|
return new File(directory, DOT.concat(getType().getName())).exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check path for existing repositories
|
* Check path for existing repositories
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @param directory repository target directory
|
* @param directory repository target directory
|
||||||
*
|
|
||||||
* @throws RepositoryAlreadyExistsException
|
* @throws RepositoryAlreadyExistsException
|
||||||
*/
|
*/
|
||||||
private void checkPath(File directory) throws RepositoryAlreadyExistsException
|
private void checkPath(File directory) throws RepositoryAlreadyExistsException {
|
||||||
{
|
|
||||||
File repositoryDirectory = config.getRepositoryDirectory();
|
File repositoryDirectory = config.getRepositoryDirectory();
|
||||||
File parent = directory.getParentFile();
|
File parent = directory.getParentFile();
|
||||||
|
|
||||||
while ((parent != null) &&!repositoryDirectory.equals(parent))
|
while ((parent != null) && !repositoryDirectory.equals(parent)) {
|
||||||
{
|
|
||||||
if (logger.isTraceEnabled())
|
|
||||||
{
|
|
||||||
logger.trace("check {} for existing repository", parent);
|
logger.trace("check {} for existing repository", parent);
|
||||||
}
|
|
||||||
|
|
||||||
if (isRepository(parent))
|
if (isRepository(parent)) {
|
||||||
{
|
|
||||||
if (logger.isErrorEnabled())
|
|
||||||
{
|
|
||||||
logger.error("parent path {} is a repository", parent);
|
logger.error("parent path {} is a repository", parent);
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder buffer = new StringBuilder("repository with name ");
|
StringBuilder buffer = new StringBuilder("repository with name ");
|
||||||
buffer.append(directory.getName()).append(" already exists");
|
buffer.append(directory.getName()).append(" already exists");
|
||||||
@@ -446,49 +283,25 @@ public abstract class AbstractSimpleRepositoryHandler<C extends SimpleRepository
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void cleanupEmptyDirectories(File baseDirectory, File directory) {
|
||||||
* Method description
|
if (IOUtil.isChild(baseDirectory, directory)) {
|
||||||
*
|
if (IOUtil.isEmpty(directory)) {
|
||||||
*
|
|
||||||
* @param baseDirectory
|
|
||||||
* @param directory
|
|
||||||
*/
|
|
||||||
private void cleanupEmptyDirectories(File baseDirectory, File directory)
|
|
||||||
{
|
|
||||||
if (IOUtil.isChild(baseDirectory, directory))
|
|
||||||
{
|
|
||||||
if (IOUtil.isEmpty(directory))
|
|
||||||
{
|
|
||||||
|
|
||||||
// TODO use filesystem
|
// TODO use filesystem
|
||||||
if (directory.delete())
|
if (directory.delete()) {
|
||||||
{
|
|
||||||
if (logger.isInfoEnabled())
|
|
||||||
{
|
|
||||||
logger.info("successfully deleted directory {}", directory);
|
logger.info("successfully deleted directory {}", directory);
|
||||||
}
|
|
||||||
|
|
||||||
cleanupEmptyDirectories(baseDirectory, directory.getParentFile());
|
cleanupEmptyDirectories(baseDirectory, directory.getParentFile());
|
||||||
}
|
} else {
|
||||||
else if (logger.isWarnEnabled())
|
|
||||||
{
|
|
||||||
logger.warn("could not delete directory {}", directory);
|
logger.warn("could not delete directory {}", directory);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (logger.isDebugEnabled())
|
} else {
|
||||||
{
|
|
||||||
logger.debug("could not remove non empty directory {}", directory);
|
logger.debug("could not remove non empty directory {}", directory);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else if (logger.isWarnEnabled())
|
logger.warn("directory {} is not a child of {}", directory, baseDirectory);
|
||||||
{
|
|
||||||
logger.warn("directory {} is not a child of {}", directory,
|
|
||||||
baseDirectory);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- fields ---------------------------------------------------------------
|
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
private FileSystem fileSystem;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package sonia.scm.repository;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class NamespaceAndName {
|
||||||
|
|
||||||
|
private final String namespace;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
public NamespaceAndName(String namespace, String name) {
|
||||||
|
Preconditions.checkArgument(!Strings.isNullOrEmpty(namespace), "a non empty namespace is required");
|
||||||
|
Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "a non empty name is required");
|
||||||
|
this.namespace = namespace;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace() {
|
||||||
|
return namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getNamespace() + "/" + getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
NamespaceAndName that = (NamespaceAndName) o;
|
||||||
|
return Objects.equals(namespace, that.namespace) &&
|
||||||
|
Objects.equals(name, that.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(namespace, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package sonia.scm.repository;
|
||||||
|
|
||||||
|
import sonia.scm.config.ScmConfiguration;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Provider;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class NamespaceStrategyProvider implements Provider<NamespaceStrategy> {
|
||||||
|
|
||||||
|
private final Set<NamespaceStrategy> strategies;
|
||||||
|
private final ScmConfiguration scmConfiguration;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public NamespaceStrategyProvider(Set<NamespaceStrategy> strategies, ScmConfiguration scmConfiguration) {
|
||||||
|
this.strategies = strategies;
|
||||||
|
this.scmConfiguration = scmConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NamespaceStrategy get() {
|
||||||
|
String namespaceStrategy = scmConfiguration.getDefaultNamespaceStrategy();
|
||||||
|
|
||||||
|
for (NamespaceStrategy s : this.strategies) {
|
||||||
|
if (s.getClass().getCanonicalName().equals(namespaceStrategy)) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -48,6 +48,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
|
|||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
import javax.xml.bind.annotation.XmlElementWrapper;
|
import javax.xml.bind.annotation.XmlElementWrapper;
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
import javax.xml.bind.annotation.XmlTransient;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -99,9 +100,10 @@ public class Repository extends BasicPropertiesAware implements ModelObject, Per
|
|||||||
* @param type type of the {@link Repository}
|
* @param type type of the {@link Repository}
|
||||||
* @param name name of the {@link Repository}
|
* @param name name of the {@link Repository}
|
||||||
*/
|
*/
|
||||||
public Repository(String id, String type, String name) {
|
public Repository(String id, String type, String namespace, String name) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
this.namespace = namespace;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,44 +178,28 @@ public class Repository extends BasicPropertiesAware implements ModelObject, Per
|
|||||||
return healthCheckFailures;
|
return healthCheckFailures;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the unique id of the {@link Repository}.
|
|
||||||
*
|
|
||||||
* @return unique id
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the timestamp of the last modified date of the {@link Repository}.
|
|
||||||
*
|
|
||||||
* @return timestamp of the last modified date
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Long getLastModified() {
|
public Long getLastModified() {
|
||||||
return lastModified;
|
return lastModified;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the name of the {@link Repository}.
|
|
||||||
*
|
|
||||||
* @return name of the {@link Repository}
|
|
||||||
*/
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getNamespace() {
|
public String getNamespace() { return namespace; }
|
||||||
return namespace;
|
|
||||||
|
@XmlTransient
|
||||||
|
public NamespaceAndName getNamespaceAndName() {
|
||||||
|
return new NamespaceAndName(getNamespace(), getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the access permissions of the {@link Repository}.
|
|
||||||
*
|
|
||||||
* @return access permissions
|
|
||||||
*/
|
|
||||||
public List<Permission> getPermissions() {
|
public List<Permission> getPermissions() {
|
||||||
if (permissions == null) {
|
if (permissions == null) {
|
||||||
permissions = Lists.newArrayList();
|
permissions = Lists.newArrayList();
|
||||||
@@ -370,9 +356,7 @@ public class Repository extends BasicPropertiesAware implements ModelObject, Per
|
|||||||
* @since 1.17
|
* @since 1.17
|
||||||
*/
|
*/
|
||||||
public String createUrl(String baseUrl) {
|
public String createUrl(String baseUrl) {
|
||||||
String url = HttpUtil.append(baseUrl, type);
|
return HttpUtil.concatenate(baseUrl, type, namespace, name);
|
||||||
|
|
||||||
return HttpUtil.append(url, name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -49,27 +49,22 @@ public interface RepositoryDAO extends GenericDAO<Repository>
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if a repository with specified
|
* Returns true if a repository with specified
|
||||||
* type and name exists in the backend.
|
* namespace and name exists in the backend.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @param type type of the repository
|
* @param namespaceAndName namespace and name of the repository
|
||||||
* @param name name of the repository
|
|
||||||
*
|
*
|
||||||
* @return true if the repository exists
|
* @return true if the repository exists
|
||||||
*/
|
*/
|
||||||
public boolean contains(String type, String name);
|
boolean contains(NamespaceAndName namespaceAndName);
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the repository with the specified type and name or null
|
* Returns the repository with the specified namespace and name or null
|
||||||
* if no such repository exists in the backend.
|
* if no such repository exists in the backend.
|
||||||
*
|
*
|
||||||
*
|
* @return repository with the specified namespace and name or null
|
||||||
* @param type
|
|
||||||
* @param name
|
|
||||||
*
|
|
||||||
* @return repository with the specified type and name or null
|
|
||||||
*/
|
*/
|
||||||
public Repository get(String type, String name);
|
Repository get(NamespaceAndName namespaceAndName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,13 +43,5 @@ import java.io.File;
|
|||||||
public interface RepositoryDirectoryHandler extends RepositoryHandler
|
public interface RepositoryDirectoryHandler extends RepositoryHandler
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repository
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public File getDirectory(Repository repository);
|
public File getDirectory(Repository repository);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,18 +82,17 @@ public interface RepositoryManager
|
|||||||
//~--- get methods ----------------------------------------------------------
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a {@link Repository} by its type and name or
|
* Returns a {@link Repository} by its namespace and name or
|
||||||
* null if the {@link Repository} could not be found.
|
* null if the {@link Repository} could not be found.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @param type type of the {@link Repository}
|
* @param namespaceAndName namespace and name of the {@link Repository}
|
||||||
* @param name name of the {@link Repository}
|
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @return {@link Repository} by its type and name or null
|
* @return {@link Repository} by its namespace and name or null
|
||||||
* if the {@link Repository} could not be found
|
* if the {@link Repository} could not be found
|
||||||
*/
|
*/
|
||||||
public Repository get(String type, String name);
|
public Repository get(NamespaceAndName namespaceAndName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all configured repository types.
|
* Returns all configured repository types.
|
||||||
@@ -114,18 +113,6 @@ public interface RepositoryManager
|
|||||||
*/
|
*/
|
||||||
public Repository getFromRequest(HttpServletRequest request);
|
public Repository getFromRequest(HttpServletRequest request);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@link Repository} associated to the given type and path.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param type type of the repository (hg, git ...)
|
|
||||||
* @param uri
|
|
||||||
*
|
|
||||||
* @return the {@link Repository} associated to the given type and path
|
|
||||||
* @since 1.9
|
|
||||||
*/
|
|
||||||
public Repository getFromTypeAndUri(String type, String uri);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link Repository} associated to the request uri.
|
* Returns the {@link Repository} associated to the request uri.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -91,9 +91,9 @@ public class RepositoryManagerDecorator
|
|||||||
//~--- get methods ----------------------------------------------------------
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Repository get(String namespace, String name)
|
public Repository get(NamespaceAndName namespaceAndName)
|
||||||
{
|
{
|
||||||
return decorated.get(namespace, name);
|
return decorated.get(namespaceAndName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -135,21 +135,6 @@ public class RepositoryManagerDecorator
|
|||||||
return decorated.getFromRequest(request);
|
return decorated.getFromRequest(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param type
|
|
||||||
* @param uri
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Repository getFromTypeAndUri(String type, String uri)
|
|
||||||
{
|
|
||||||
return decorated.getFromTypeAndUri(type, uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -35,278 +35,86 @@ package sonia.scm.repository;
|
|||||||
|
|
||||||
//~--- non-JDK imports --------------------------------------------------------
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import com.google.common.base.Preconditions;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import sonia.scm.io.DirectoryFileFilter;
|
import sonia.scm.io.DirectoryFileFilter;
|
||||||
import sonia.scm.util.IOUtil;
|
import sonia.scm.util.IOUtil;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Sebastian Sdorra
|
* @author Sebastian Sdorra
|
||||||
* @since 1.11
|
* @since 1.11
|
||||||
*/
|
*/
|
||||||
public final class RepositoryUtil
|
public final class RepositoryUtil {
|
||||||
{
|
|
||||||
|
|
||||||
/** the logger for RepositoryUtil */
|
|
||||||
private static final Logger logger =
|
|
||||||
LoggerFactory.getLogger(RepositoryUtil.class);
|
|
||||||
|
|
||||||
//~--- constructors ---------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs ...
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private RepositoryUtil() {}
|
private RepositoryUtil() {}
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
public static List<File> searchRepositoryDirectories(File directory, String... names) {
|
||||||
|
List<File> repositories = new ArrayList<>();
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param directory
|
|
||||||
* @param names
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static List<File> searchRepositoryDirectories(File directory,
|
|
||||||
String... names)
|
|
||||||
{
|
|
||||||
List<File> repositories = new ArrayList<File>();
|
|
||||||
|
|
||||||
searchRepositoryDirectories(repositories, directory, Arrays.asList(names));
|
searchRepositoryDirectories(repositories, directory, Arrays.asList(names));
|
||||||
|
|
||||||
return repositories;
|
return repositories;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
@SuppressWarnings("squid:S2083") // ignore, because the path is validated at {@link #getRepositoryId(File, File)}
|
||||||
|
public static String getRepositoryId(AbstractRepositoryHandler handler, String directoryPath) throws IOException {
|
||||||
/**
|
return getRepositoryId(handler.getConfig().getRepositoryDirectory(), new File(directoryPath));
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param handler
|
|
||||||
* @param directoryPath
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static String getRepositoryName(AbstractRepositoryHandler handler,
|
|
||||||
String directoryPath)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
return getRepositoryName(handler.getConfig().getRepositoryDirectory(),
|
|
||||||
new File(directoryPath));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static String getRepositoryId(AbstractRepositoryHandler handler, File directory) throws IOException {
|
||||||
* Method description
|
return getRepositoryId(handler.getConfig(), directory);
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param config
|
|
||||||
* @param directoryPath
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static String getRepositoryName(SimpleRepositoryConfig config,
|
|
||||||
String directoryPath)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
return getRepositoryName(config.getRepositoryDirectory(),
|
|
||||||
new File(directoryPath));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static String getRepositoryId(SimpleRepositoryConfig config, File directory) throws IOException {
|
||||||
* Method description
|
return getRepositoryId(config.getRepositoryDirectory(), directory);
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param handler
|
|
||||||
* @param directory
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static String getRepositoryName(AbstractRepositoryHandler handler,
|
|
||||||
File directory)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
return getRepositoryName(handler.getConfig().getRepositoryDirectory(),
|
|
||||||
directory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static String getRepositoryId(File baseDirectory, File directory) throws IOException {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param config
|
|
||||||
* @param directory
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static String getRepositoryName(SimpleRepositoryConfig config,
|
|
||||||
File directory)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
return getRepositoryName(config.getRepositoryDirectory(), directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param baseDirectory
|
|
||||||
* @param directory
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static String getRepositoryName(File baseDirectory, File directory)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
String name = null;
|
|
||||||
String path = directory.getCanonicalPath();
|
String path = directory.getCanonicalPath();
|
||||||
int directoryLength = baseDirectory.getCanonicalPath().length();
|
String basePath = baseDirectory.getCanonicalPath();
|
||||||
|
|
||||||
if (directoryLength < path.length())
|
Preconditions.checkArgument(
|
||||||
{
|
path.startsWith(basePath),
|
||||||
name = IOUtil.trimSeperatorChars(path.substring(directoryLength));
|
"repository path %s is not in the main repository path %s", path, basePath
|
||||||
|
);
|
||||||
|
|
||||||
// replace windows path seperator
|
String id = IOUtil.trimSeperatorChars(path.substring(basePath.length()));
|
||||||
name = name.replaceAll("\\\\", "/");
|
|
||||||
}
|
Preconditions.checkArgument(
|
||||||
else if (logger.isWarnEnabled())
|
!id.contains("\\") && !id.contains("/"),
|
||||||
{
|
"got illegal repository directory with separators in id: %s", path
|
||||||
logger.warn("path is shorter as the main repository path");
|
);
|
||||||
|
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return name;
|
private static void searchRepositoryDirectories(List<File> repositories, File directory, List<String> names) {
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param handler
|
|
||||||
* @param directoryNames
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static List<String> getRepositoryNames(
|
|
||||||
AbstractRepositoryHandler handler, String... directoryNames)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
return getRepositoryNames(handler.getConfig(), directoryNames);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param config
|
|
||||||
* @param directoryNames
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static List<String> getRepositoryNames(SimpleRepositoryConfig config,
|
|
||||||
String... directoryNames)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
return getRepositoryNames(config.getRepositoryDirectory(), directoryNames);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param baseDirectory
|
|
||||||
* @param directoryNames
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static List<String> getRepositoryNames(File baseDirectory,
|
|
||||||
String... directoryNames)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
List<String> repositories = new ArrayList<String>();
|
|
||||||
List<File> repositoryFiles = searchRepositoryDirectories(baseDirectory,
|
|
||||||
directoryNames);
|
|
||||||
|
|
||||||
for (File file : repositoryFiles)
|
|
||||||
{
|
|
||||||
String name = getRepositoryName(baseDirectory, file);
|
|
||||||
|
|
||||||
if (name != null)
|
|
||||||
{
|
|
||||||
repositories.add(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return repositories;
|
|
||||||
}
|
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repositories
|
|
||||||
* @param directory
|
|
||||||
* @param names
|
|
||||||
*/
|
|
||||||
private static void searchRepositoryDirectories(List<File> repositories,
|
|
||||||
File directory, List<String> names)
|
|
||||||
{
|
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
|
|
||||||
for (String name : names)
|
for (String name : names) {
|
||||||
{
|
if (new File(directory, name).exists()) {
|
||||||
if (new File(directory, name).exists())
|
|
||||||
{
|
|
||||||
found = true;
|
found = true;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found)
|
if (found) {
|
||||||
{
|
|
||||||
repositories.add(directory);
|
repositories.add(directory);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
File[] directories = directory.listFiles(DirectoryFileFilter.instance);
|
File[] directories = directory.listFiles(DirectoryFileFilter.instance);
|
||||||
|
|
||||||
if (directories != null)
|
if (directories != null) {
|
||||||
{
|
for (File d : directories) {
|
||||||
for (File d : directories)
|
|
||||||
{
|
|
||||||
searchRepositoryDirectories(repositories, d, names);
|
searchRepositoryDirectories(repositories, d, names);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ import sonia.scm.cache.CacheManager;
|
|||||||
import sonia.scm.config.ScmConfiguration;
|
import sonia.scm.config.ScmConfiguration;
|
||||||
import sonia.scm.event.ScmEventBus;
|
import sonia.scm.event.ScmEventBus;
|
||||||
import sonia.scm.repository.ClearRepositoryCacheEvent;
|
import sonia.scm.repository.ClearRepositoryCacheEvent;
|
||||||
|
import sonia.scm.repository.NamespaceAndName;
|
||||||
import sonia.scm.repository.PostReceiveRepositoryHookEvent;
|
import sonia.scm.repository.PostReceiveRepositoryHookEvent;
|
||||||
import sonia.scm.repository.PreProcessorUtil;
|
import sonia.scm.repository.PreProcessorUtil;
|
||||||
import sonia.scm.repository.Repository;
|
import sonia.scm.repository.Repository;
|
||||||
@@ -186,8 +187,7 @@ public final class RepositoryServiceFactory
|
|||||||
* Creates a new RepositoryService for the given repository.
|
* Creates a new RepositoryService for the given repository.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @param type type of the repository
|
* @param namespaceAndName namespace and name of the repository
|
||||||
* @param name name of the repository
|
|
||||||
*
|
*
|
||||||
* @return a implementation of RepositoryService
|
* @return a implementation of RepositoryService
|
||||||
* for the given type of repository
|
* for the given type of repository
|
||||||
@@ -200,24 +200,19 @@ public final class RepositoryServiceFactory
|
|||||||
* @throws ScmSecurityException if current user has not read permissions
|
* @throws ScmSecurityException if current user has not read permissions
|
||||||
* for that repository
|
* for that repository
|
||||||
*/
|
*/
|
||||||
public RepositoryService create(String type, String name)
|
public RepositoryService create(NamespaceAndName namespaceAndName)
|
||||||
throws RepositoryNotFoundException
|
throws RepositoryNotFoundException
|
||||||
{
|
{
|
||||||
Preconditions.checkArgument(!Strings.isNullOrEmpty(type),
|
Preconditions.checkArgument(namespaceAndName != null,
|
||||||
"a non empty type is required");
|
"a non empty namespace and name is required");
|
||||||
Preconditions.checkArgument(!Strings.isNullOrEmpty(name),
|
|
||||||
"a non empty name is required");
|
|
||||||
|
|
||||||
Repository repository = repositoryManager.get(type, name);
|
Repository repository = repositoryManager.get(namespaceAndName);
|
||||||
|
|
||||||
if (repository == null)
|
if (repository == null)
|
||||||
{
|
{
|
||||||
StringBuilder msg =
|
String msg = "could not find a repository with namespace/name " + namespaceAndName;
|
||||||
new StringBuilder("could not find a repository with type ");
|
|
||||||
|
|
||||||
msg.append(type).append(" and name ").append(name);
|
throw new RepositoryNotFoundException(msg);
|
||||||
|
|
||||||
throw new RepositoryNotFoundException(msg.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return create(repository);
|
return create(repository);
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ package sonia.scm.repository.spi;
|
|||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
|
import sonia.scm.repository.NamespaceAndName;
|
||||||
import sonia.scm.repository.Repository;
|
import sonia.scm.repository.Repository;
|
||||||
import sonia.scm.repository.RepositoryException;
|
import sonia.scm.repository.RepositoryException;
|
||||||
import sonia.scm.repository.RepositoryHookEvent;
|
import sonia.scm.repository.RepositoryHookEvent;
|
||||||
@@ -72,50 +72,15 @@ public final class HookEventFacade
|
|||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
public HookEventHandler handle(String id) throws RepositoryException {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
public HookEventHandler handle(String id) throws RepositoryException
|
|
||||||
{
|
|
||||||
return handle(repositoryManagerProvider.get().get(id));
|
return handle(repositoryManagerProvider.get().get(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public HookEventHandler handle(NamespaceAndName namespaceAndName) throws RepositoryException {
|
||||||
* Method description
|
return handle(repositoryManagerProvider.get().get(namespaceAndName));
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param type
|
|
||||||
* @param repositoryName
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
public HookEventHandler handle(String type, String repositoryName)
|
|
||||||
throws RepositoryException
|
|
||||||
{
|
|
||||||
return handle(repositoryManagerProvider.get().get(type, repositoryName));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public HookEventHandler handle(Repository repository) throws RepositoryException
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repository
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
public HookEventHandler handle(Repository repository)
|
|
||||||
throws RepositoryException
|
|
||||||
{
|
{
|
||||||
if (repository == null)
|
if (repository == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -39,27 +39,23 @@ import com.google.common.annotations.VisibleForTesting;
|
|||||||
import com.google.common.base.CharMatcher;
|
import com.google.common.base.CharMatcher;
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import sonia.scm.config.ScmConfiguration;
|
import sonia.scm.config.ScmConfiguration;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Util method for the http protocol.
|
* Util method for the http protocol.
|
||||||
@@ -253,12 +249,22 @@ public final class HttpUtil
|
|||||||
//~--- methods --------------------------------------------------------------
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appends the suffix to given uri.
|
* Joins all path elements together separated by {@code {@link #SEPARATOR_PATH}}.
|
||||||
*
|
*
|
||||||
|
* @param pathElements path elements
|
||||||
|
*
|
||||||
|
* @return concatenated path
|
||||||
|
* @since 2.0.0
|
||||||
|
*/
|
||||||
|
public static String concatenate(String... pathElements) {
|
||||||
|
return Arrays.stream(pathElements).reduce(HttpUtil::append).orElse("");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends the suffix to given uri.
|
||||||
*
|
*
|
||||||
* @param uri uri
|
* @param uri uri
|
||||||
* @param suffix suffix
|
* @param suffix suffix
|
||||||
*
|
|
||||||
* @return
|
* @return
|
||||||
* @since 1.9
|
* @since 1.9
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,133 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.web.filter;
|
|
||||||
|
|
||||||
//~--- non-JDK imports --------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
import sonia.scm.config.ScmConfiguration;
|
|
||||||
import sonia.scm.repository.Repository;
|
|
||||||
import sonia.scm.repository.RepositoryManager;
|
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Sebastian Sdorra
|
|
||||||
*/
|
|
||||||
public abstract class RegexPermissionFilter extends PermissionFilter
|
|
||||||
{
|
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
public static final Pattern PATTERN_REPOSITORYNAME =
|
|
||||||
Pattern.compile("/[^/]+/([^/]+)(?:/.*)?");
|
|
||||||
|
|
||||||
//~--- constructors ---------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs ...
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param configuration
|
|
||||||
* @param repositoryManager
|
|
||||||
*/
|
|
||||||
public RegexPermissionFilter(ScmConfiguration configuration,
|
|
||||||
RepositoryManager repositoryManager)
|
|
||||||
{
|
|
||||||
super(configuration);
|
|
||||||
this.repositoryManager = repositoryManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
protected abstract String getType();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param request
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected Repository getRepository(HttpServletRequest request)
|
|
||||||
{
|
|
||||||
Repository repository = null;
|
|
||||||
String uri = request.getRequestURI();
|
|
||||||
|
|
||||||
uri = uri.substring(request.getContextPath().length());
|
|
||||||
|
|
||||||
Matcher m = PATTERN_REPOSITORYNAME.matcher(uri);
|
|
||||||
|
|
||||||
if (m.matches())
|
|
||||||
{
|
|
||||||
String repositoryname = m.group(1);
|
|
||||||
|
|
||||||
repository = getRepository(repositoryname);
|
|
||||||
}
|
|
||||||
|
|
||||||
return repository;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param name
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
protected Repository getRepository(String name)
|
|
||||||
{
|
|
||||||
return repositoryManager.get(getType(), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
//~--- fields ---------------------------------------------------------------
|
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
private RepositoryManager repositoryManager;
|
|
||||||
}
|
|
||||||
@@ -34,7 +34,7 @@ package sonia.scm.repository;
|
|||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -50,7 +50,7 @@ public class RepositoryTest
|
|||||||
@Test
|
@Test
|
||||||
public void testCreateUrl()
|
public void testCreateUrl()
|
||||||
{
|
{
|
||||||
Repository repository = new Repository("123", "hg", "test/repo");
|
Repository repository = new Repository("123", "hg", "test", "repo");
|
||||||
|
|
||||||
assertEquals("http://localhost:8080/scm/hg/test/repo",
|
assertEquals("http://localhost:8080/scm/hg/test/repo",
|
||||||
repository.createUrl("http://localhost:8080/scm"));
|
repository.createUrl("http://localhost:8080/scm"));
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package sonia.scm.repository;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.TemporaryFolder;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class RepositoryUtilTest {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private AbstractRepositoryHandler<SimpleRepositoryConfig> repositoryHandler;
|
||||||
|
|
||||||
|
private SimpleRepositoryConfig repositoryConfig = new SimpleRepositoryConfig();
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUpMocks() {
|
||||||
|
when(repositoryHandler.getConfig()).thenReturn(repositoryConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetRepositoryId() throws IOException {
|
||||||
|
File repositoryTypeRoot = temporaryFolder.newFolder();
|
||||||
|
repositoryConfig.setRepositoryDirectory(repositoryTypeRoot);
|
||||||
|
|
||||||
|
File repository = new File(repositoryTypeRoot, "abc");
|
||||||
|
String id = RepositoryUtil.getRepositoryId(repositoryHandler, repository.getPath());
|
||||||
|
assertEquals("abc", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testGetRepositoryIdWithInvalidPath() throws IOException {
|
||||||
|
File repositoryTypeRoot = temporaryFolder.newFolder();
|
||||||
|
repositoryConfig.setRepositoryDirectory(repositoryTypeRoot);
|
||||||
|
|
||||||
|
File repository = new File("/etc/abc");
|
||||||
|
String id = RepositoryUtil.getRepositoryId(repositoryHandler, repository.getPath());
|
||||||
|
assertEquals("abc", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testGetRepositoryIdWithInvalidPathButSameLength() throws IOException {
|
||||||
|
File repositoryTypeRoot = temporaryFolder.newFolder();
|
||||||
|
repositoryConfig.setRepositoryDirectory(repositoryTypeRoot);
|
||||||
|
|
||||||
|
File repository = new File(temporaryFolder.newFolder(), "abc");
|
||||||
|
|
||||||
|
String id = RepositoryUtil.getRepositoryId(repositoryHandler, repository.getPath());
|
||||||
|
assertEquals("abc", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testGetRepositoryIdWithInvalidId() throws IOException {
|
||||||
|
File repositoryTypeRoot = temporaryFolder.newFolder();
|
||||||
|
repositoryConfig.setRepositoryDirectory(repositoryTypeRoot);
|
||||||
|
|
||||||
|
File repository = new File(repositoryTypeRoot, "abc/123");
|
||||||
|
RepositoryUtil.getRepositoryId(repositoryHandler, repository.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -54,6 +54,18 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
public class HttpUtilTest
|
public class HttpUtilTest
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void concatenateTest() {
|
||||||
|
assertEquals(
|
||||||
|
"/scm/git/hitchhiker/tricia",
|
||||||
|
HttpUtil.concatenate("/scm", "git", "hitchhiker", "tricia")
|
||||||
|
);
|
||||||
|
assertEquals(
|
||||||
|
"scm/git/hitchhiker/tricia",
|
||||||
|
HttpUtil.concatenate("scm", "git", "hitchhiker", "tricia")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method description
|
* Method description
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -36,11 +36,11 @@ package sonia.scm.repository.xml;
|
|||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
|
import sonia.scm.repository.NamespaceAndName;
|
||||||
import sonia.scm.repository.Repository;
|
import sonia.scm.repository.Repository;
|
||||||
import sonia.scm.repository.RepositoryDAO;
|
import sonia.scm.repository.RepositoryDAO;
|
||||||
import sonia.scm.xml.AbstractXmlDAO;
|
|
||||||
import sonia.scm.store.ConfigurationStoreFactory;
|
import sonia.scm.store.ConfigurationStoreFactory;
|
||||||
|
import sonia.scm.xml.AbstractXmlDAO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -71,36 +71,18 @@ public class XmlRepositoryDAO
|
|||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param type
|
|
||||||
* @param name
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean contains(String type, String name)
|
public boolean contains(NamespaceAndName namespaceAndName)
|
||||||
{
|
{
|
||||||
return db.contains(type, name);
|
return db.contains(namespaceAndName);
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param type
|
|
||||||
* @param name
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Repository get(String type, String name)
|
public Repository get(NamespaceAndName namespaceAndName)
|
||||||
{
|
{
|
||||||
return db.get(type, name);
|
return db.get(namespaceAndName);
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
//~--- methods --------------------------------------------------------------
|
||||||
|
|||||||
@@ -35,34 +35,26 @@ package sonia.scm.repository.xml;
|
|||||||
|
|
||||||
//~--- non-JDK imports --------------------------------------------------------
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
|
import sonia.scm.repository.NamespaceAndName;
|
||||||
import sonia.scm.repository.Repository;
|
import sonia.scm.repository.Repository;
|
||||||
import sonia.scm.xml.XmlDatabase;
|
import sonia.scm.xml.XmlDatabase;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlAccessType;
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Sebastian Sdorra
|
|
||||||
*/
|
|
||||||
@XmlRootElement(name = "repository-db")
|
@XmlRootElement(name = "repository-db")
|
||||||
@XmlAccessorType(XmlAccessType.FIELD)
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
public class XmlRepositoryDatabase implements XmlDatabase<Repository>
|
public class XmlRepositoryDatabase implements XmlDatabase<Repository>
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs ...
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public XmlRepositoryDatabase()
|
public XmlRepositoryDatabase()
|
||||||
{
|
{
|
||||||
long c = System.currentTimeMillis();
|
long c = System.currentTimeMillis();
|
||||||
@@ -71,108 +63,43 @@ public class XmlRepositoryDatabase implements XmlDatabase<Repository>
|
|||||||
lastModified = c;
|
lastModified = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
static String createKey(NamespaceAndName namespaceAndName)
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param type
|
|
||||||
* @param name
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static String createKey(String type, String name)
|
|
||||||
{
|
{
|
||||||
return type.concat(":").concat(name);
|
return namespaceAndName.getNamespace() + ":" + namespaceAndName.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repository
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static String createKey(Repository repository)
|
static String createKey(Repository repository)
|
||||||
{
|
{
|
||||||
return createKey(repository.getType(), repository.getName());
|
return createKey(repository.getNamespaceAndName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repository
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void add(Repository repository)
|
public void add(Repository repository)
|
||||||
{
|
{
|
||||||
repositoryMap.put(createKey(repository), repository);
|
repositoryMap.put(createKey(repository), repository);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public boolean contains(NamespaceAndName namespaceAndName)
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param type
|
|
||||||
* @param name
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public boolean contains(String type, String name)
|
|
||||||
{
|
{
|
||||||
return repositoryMap.containsKey(createKey(type, name));
|
return repositoryMap.containsKey(createKey(namespaceAndName));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean contains(String id)
|
public boolean contains(String id)
|
||||||
{
|
{
|
||||||
return get(id) != null;
|
return get(id) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repository
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public boolean contains(Repository repository)
|
public boolean contains(Repository repository)
|
||||||
{
|
{
|
||||||
return repositoryMap.containsKey(createKey(repository));
|
return repositoryMap.containsKey(createKey(repository));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repository
|
|
||||||
*/
|
|
||||||
public void remove(Repository repository)
|
public void remove(Repository repository)
|
||||||
{
|
{
|
||||||
repositoryMap.remove(createKey(repository));
|
repositoryMap.remove(createKey(repository));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Repository remove(String id)
|
public Repository remove(String id)
|
||||||
{
|
{
|
||||||
@@ -183,12 +110,6 @@ public class XmlRepositoryDatabase implements XmlDatabase<Repository>
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Repository> values()
|
public Collection<Repository> values()
|
||||||
{
|
{
|
||||||
@@ -197,18 +118,9 @@ public class XmlRepositoryDatabase implements XmlDatabase<Repository>
|
|||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
/**
|
public Repository get(NamespaceAndName namespaceAndName)
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param type
|
|
||||||
* @param name
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public Repository get(String type, String name)
|
|
||||||
{
|
{
|
||||||
return repositoryMap.get(createKey(type, name));
|
return repositoryMap.get(createKey(namespaceAndName));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -298,6 +210,5 @@ public class XmlRepositoryDatabase implements XmlDatabase<Repository>
|
|||||||
/** Field description */
|
/** Field description */
|
||||||
@XmlJavaTypeAdapter(XmlRepositoryMapAdapter.class)
|
@XmlJavaTypeAdapter(XmlRepositoryMapAdapter.class)
|
||||||
@XmlElement(name = "repositories")
|
@XmlElement(name = "repositories")
|
||||||
private Map<String, Repository> repositoryMap = new LinkedHashMap<String,
|
private Map<String, Repository> repositoryMap = new LinkedHashMap<>();
|
||||||
Repository>();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,57 +37,28 @@ package sonia.scm.repository.xml;
|
|||||||
|
|
||||||
import sonia.scm.repository.Repository;
|
import sonia.scm.repository.Repository;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Sebastian Sdorra
|
* @author Sebastian Sdorra
|
||||||
*/
|
*/
|
||||||
public class XmlRepositoryMapAdapter
|
public class XmlRepositoryMapAdapter extends XmlAdapter<XmlRepositoryList, Map<String, Repository>> {
|
||||||
extends XmlAdapter<XmlRepositoryList, Map<String, Repository>>
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repositoryMap
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public XmlRepositoryList marshal(Map<String, Repository> repositoryMap)
|
public XmlRepositoryList marshal(Map<String, Repository> repositoryMap) {
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
return new XmlRepositoryList(repositoryMap);
|
return new XmlRepositoryList(repositoryMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repositories
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Repository> unmarshal(XmlRepositoryList repositories)
|
public Map<String, Repository> unmarshal(XmlRepositoryList repositories) {
|
||||||
throws Exception
|
Map<String, Repository> repositoryMap = new LinkedHashMap<>();
|
||||||
{
|
|
||||||
Map<String, Repository> repositoryMap = new LinkedHashMap<String,
|
|
||||||
Repository>();
|
|
||||||
|
|
||||||
for (Repository repository : repositories)
|
for (Repository repository : repositories) {
|
||||||
{
|
|
||||||
repositoryMap.put(XmlRepositoryDatabase.createKey(repository),
|
repositoryMap.put(XmlRepositoryDatabase.createKey(repository),
|
||||||
repository);
|
repository);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,9 +30,9 @@
|
|||||||
*/
|
*/
|
||||||
package sonia.scm.repository;
|
package sonia.scm.repository;
|
||||||
|
|
||||||
|
import com.github.legman.Subscribe;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import com.google.common.eventbus.Subscribe;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import sonia.scm.EagerSingleton;
|
import sonia.scm.EagerSingleton;
|
||||||
|
|||||||
@@ -40,24 +40,21 @@ import org.eclipse.jgit.transport.PostReceiveHook;
|
|||||||
import org.eclipse.jgit.transport.PreReceiveHook;
|
import org.eclipse.jgit.transport.PreReceiveHook;
|
||||||
import org.eclipse.jgit.transport.ReceiveCommand;
|
import org.eclipse.jgit.transport.ReceiveCommand;
|
||||||
import org.eclipse.jgit.transport.ReceivePack;
|
import org.eclipse.jgit.transport.ReceivePack;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import sonia.scm.repository.GitRepositoryHandler;
|
import sonia.scm.repository.GitRepositoryHandler;
|
||||||
import sonia.scm.repository.RepositoryHookType;
|
import sonia.scm.repository.RepositoryHookType;
|
||||||
import sonia.scm.repository.RepositoryUtil;
|
import sonia.scm.repository.RepositoryUtil;
|
||||||
import sonia.scm.repository.spi.GitHookContextProvider;
|
import sonia.scm.repository.spi.GitHookContextProvider;
|
||||||
import sonia.scm.repository.spi.HookEventFacade;
|
import sonia.scm.repository.spi.HookEventFacade;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Sebastian Sdorra
|
* @author Sebastian Sdorra
|
||||||
@@ -131,15 +128,14 @@ public class GitReceiveHook implements PreReceiveHook, PostReceiveHook
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Repository repository = rpack.getRepository();
|
Repository repository = rpack.getRepository();
|
||||||
String repositoryName = resolveRepositoryName(repository);
|
String id = resolveRepositoryId(repository);
|
||||||
|
|
||||||
logger.trace("resolved repository name to {}", repositoryName);
|
logger.trace("resolved repository to id {}", id);
|
||||||
|
|
||||||
GitHookContextProvider context = new GitHookContextProvider(rpack,
|
GitHookContextProvider context = new GitHookContextProvider(rpack,
|
||||||
receiveCommands);
|
receiveCommands);
|
||||||
|
|
||||||
hookEventFacade.handle(GitRepositoryHandler.TYPE_NAME,
|
hookEventFacade.handle(id).fireHookEvent(type, context);
|
||||||
repositoryName).fireHookEvent(type, context);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -191,7 +187,7 @@ public class GitReceiveHook implements PreReceiveHook, PostReceiveHook
|
|||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
private String resolveRepositoryName(Repository repository) throws IOException
|
private String resolveRepositoryId(Repository repository) throws IOException
|
||||||
{
|
{
|
||||||
File directory;
|
File directory;
|
||||||
|
|
||||||
@@ -204,7 +200,7 @@ public class GitReceiveHook implements PreReceiveHook, PostReceiveHook
|
|||||||
directory = repository.getWorkTree();
|
directory = repository.getWorkTree();
|
||||||
}
|
}
|
||||||
|
|
||||||
return RepositoryUtil.getRepositoryName(handler, directory);
|
return RepositoryUtil.getRepositoryId(handler, directory);
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- fields ---------------------------------------------------------------
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ package sonia.scm.web;
|
|||||||
//~--- non-JDK imports --------------------------------------------------------
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
||||||
import org.eclipse.jgit.lib.Repository;
|
import org.eclipse.jgit.lib.Repository;
|
||||||
import org.eclipse.jgit.lib.RepositoryCache;
|
import org.eclipse.jgit.lib.RepositoryCache;
|
||||||
@@ -46,19 +46,17 @@ import org.eclipse.jgit.transport.resolver.RepositoryResolver;
|
|||||||
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
|
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
|
||||||
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
|
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
|
||||||
import org.eclipse.jgit.util.FS;
|
import org.eclipse.jgit.util.FS;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import sonia.scm.repository.GitConfig;
|
import sonia.scm.repository.GitConfig;
|
||||||
import sonia.scm.repository.GitRepositoryHandler;
|
import sonia.scm.repository.GitRepositoryHandler;
|
||||||
|
import sonia.scm.repository.RepositoryProvider;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -72,17 +70,11 @@ public class GitRepositoryResolver implements RepositoryResolver<HttpServletRequ
|
|||||||
|
|
||||||
//~--- constructors ---------------------------------------------------------
|
//~--- constructors ---------------------------------------------------------
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs ...
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param handler
|
|
||||||
*/
|
|
||||||
@Inject
|
@Inject
|
||||||
public GitRepositoryResolver(GitRepositoryHandler handler)
|
public GitRepositoryResolver(GitRepositoryHandler handler, RepositoryProvider repositoryProvider)
|
||||||
{
|
{
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
|
this.repositoryProvider = repositoryProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
//~--- methods --------------------------------------------------------------
|
||||||
@@ -101,26 +93,27 @@ public class GitRepositoryResolver implements RepositoryResolver<HttpServletRequ
|
|||||||
* @throws ServiceNotEnabledException
|
* @throws ServiceNotEnabledException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Repository open(HttpServletRequest request, String repositoryName)
|
public Repository open(HttpServletRequest request, String repositoryName) throws RepositoryNotFoundException, ServiceNotEnabledException
|
||||||
throws RepositoryNotFoundException, ServiceNotAuthorizedException,
|
|
||||||
ServiceNotEnabledException
|
|
||||||
{
|
{
|
||||||
Repository repository = null;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
sonia.scm.repository.Repository repo = repositoryProvider.get();
|
||||||
|
|
||||||
|
Preconditions.checkState(repo != null, "repository to handle not found");
|
||||||
|
Preconditions.checkState(GitRepositoryHandler.TYPE_NAME.equals(repo.getType()), "got a non git repository in GitRepositoryResolver of type " + repo.getType());
|
||||||
|
|
||||||
GitConfig config = handler.getConfig();
|
GitConfig config = handler.getConfig();
|
||||||
|
|
||||||
if (config.isValid())
|
if (config.isValid())
|
||||||
{
|
{
|
||||||
File gitdir = findRepository(config.getRepositoryDirectory(), repositoryName);
|
File gitdir = findRepository(config.getRepositoryDirectory(), repo.getId());
|
||||||
if (gitdir == null) {
|
if (gitdir == null) {
|
||||||
throw new RepositoryNotFoundException(repositoryName);
|
throw new RepositoryNotFoundException(repositoryName);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug("try to open git repository at {}", gitdir);
|
logger.debug("try to open git repository at {}", gitdir);
|
||||||
|
|
||||||
repository = RepositoryCache.open(FileKey.lenient(gitdir, FS.DETECTED), true);
|
return RepositoryCache.open(FileKey.lenient(gitdir, FS.DETECTED), true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -136,8 +129,6 @@ public class GitRepositoryResolver implements RepositoryResolver<HttpServletRequ
|
|||||||
{
|
{
|
||||||
throw new RepositoryNotFoundException(repositoryName, e);
|
throw new RepositoryNotFoundException(repositoryName, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return repository;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -168,6 +159,6 @@ public class GitRepositoryResolver implements RepositoryResolver<HttpServletRequ
|
|||||||
|
|
||||||
//~--- fields ---------------------------------------------------------------
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
/** Field description */
|
private final GitRepositoryHandler handler;
|
||||||
private GitRepositoryHandler handler;
|
private final RepositoryProvider repositoryProvider;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
package sonia.scm.web.lfs;
|
package sonia.scm.web.lfs;
|
||||||
|
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.github.legman.Subscribe;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2010, Sebastian Sdorra
|
* Copyright (c) 2010, Sebastian Sdorra
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
* <p>
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
*
|
* <p>
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
* 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
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
* contributors may be used to endorse or promote products derived from this
|
* contributors may be used to endorse or promote products derived from this
|
||||||
* software without specific prior written permission.
|
* software without specific prior written permission.
|
||||||
*
|
* <p>
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
@@ -24,50 +24,45 @@
|
|||||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
* <p>
|
||||||
* http://bitbucket.org/sdorra/scm-manager
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package sonia.scm.repository;
|
package sonia.scm.repository;
|
||||||
|
|
||||||
//~--- non-JDK imports --------------------------------------------------------
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
import sonia.scm.io.DefaultFileSystem;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import sonia.scm.store.ConfigurationStoreFactory;
|
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
import sonia.scm.io.DefaultFileSystem;
|
||||||
import sonia.scm.schedule.Scheduler;
|
import sonia.scm.schedule.Scheduler;
|
||||||
|
import sonia.scm.store.ConfigurationStoreFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Sebastian Sdorra
|
* @author Sebastian Sdorra
|
||||||
*/
|
*/
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class GitRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase
|
public class GitRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase {
|
||||||
{
|
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private Scheduler scheduler;
|
private Scheduler scheduler;
|
||||||
|
|
||||||
/**
|
@Mock
|
||||||
* Method description
|
private ConfigurationStoreFactory factory;
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param directory
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected void checkDirectory(File directory)
|
protected void checkDirectory(File directory) {
|
||||||
{
|
|
||||||
File head = new File(directory, "HEAD");
|
File head = new File(directory, "HEAD");
|
||||||
|
|
||||||
assertTrue(head.exists());
|
assertTrue(head.exists());
|
||||||
@@ -84,19 +79,10 @@ public class GitRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase
|
|||||||
assertTrue(refs.isDirectory());
|
assertTrue(refs.isDirectory());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param factory
|
|
||||||
* @param directory
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected RepositoryHandler createRepositoryHandler(ConfigurationStoreFactory factory,
|
protected RepositoryHandler createRepositoryHandler(ConfigurationStoreFactory factory,
|
||||||
File directory)
|
File directory) {
|
||||||
{
|
|
||||||
GitRepositoryHandler repositoryHandler = new GitRepositoryHandler(factory,
|
GitRepositoryHandler repositoryHandler = new GitRepositoryHandler(factory,
|
||||||
new DefaultFileSystem(), scheduler);
|
new DefaultFileSystem(), scheduler);
|
||||||
|
|
||||||
@@ -110,4 +96,19 @@ public class GitRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase
|
|||||||
|
|
||||||
return repositoryHandler;
|
return repositoryHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getDirectory() {
|
||||||
|
GitRepositoryHandler repositoryHandler = new GitRepositoryHandler(factory,
|
||||||
|
new DefaultFileSystem(), scheduler);
|
||||||
|
|
||||||
|
GitConfig gitConfig = new GitConfig();
|
||||||
|
gitConfig.setRepositoryDirectory(new File("/path"));
|
||||||
|
repositoryHandler.setConfig(gitConfig);
|
||||||
|
|
||||||
|
Repository repository = new Repository("id", "git", "Space", "Name");
|
||||||
|
|
||||||
|
File path = repositoryHandler.getDirectory(repository);
|
||||||
|
assertEquals("/path/id", path.getAbsolutePath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,9 @@
|
|||||||
package sonia.scm.repository;
|
package sonia.scm.repository;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link GitRepositoryPathMatcher}.
|
* Unit tests for {@link GitRepositoryPathMatcher}.
|
||||||
@@ -45,18 +47,18 @@ public class GitRepositoryPathMatcherTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsPathMatching() {
|
public void testIsPathMatching() {
|
||||||
assertFalse(pathMatcher.isPathMatching(repository("my-repo"), "my-repoo"));
|
assertFalse(pathMatcher.isPathMatching(repository("space", "my-repo"), "my-repoo"));
|
||||||
assertFalse(pathMatcher.isPathMatching(repository("my"), "my-repo"));
|
assertFalse(pathMatcher.isPathMatching(repository("space", "my"), "my-repo"));
|
||||||
assertFalse(pathMatcher.isPathMatching(repository("my"), "my-repo/with/path"));
|
assertFalse(pathMatcher.isPathMatching(repository("space", "my"), "my-repo/with/path"));
|
||||||
|
|
||||||
assertTrue(pathMatcher.isPathMatching(repository("my-repo"), "my-repo"));
|
assertTrue(pathMatcher.isPathMatching(repository("space", "my-repo"), "my-repo"));
|
||||||
assertTrue(pathMatcher.isPathMatching(repository("my-repo"), "my-repo.git"));
|
assertTrue(pathMatcher.isPathMatching(repository("space", "my-repo"), "my-repo.git"));
|
||||||
assertTrue(pathMatcher.isPathMatching(repository("my-repo"), "my-repo/with/path"));
|
assertTrue(pathMatcher.isPathMatching(repository("space", "my-repo"), "my-repo/with/path"));
|
||||||
assertTrue(pathMatcher.isPathMatching(repository("my-repo"), "my-repo.git/with/path"));
|
assertTrue(pathMatcher.isPathMatching(repository("space", "my-repo"), "my-repo.git/with/path"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Repository repository(String name) {
|
private Repository repository(String namespace, String name) {
|
||||||
return new Repository(name, GitRepositoryHandler.TYPE_NAME, name);
|
return new Repository(name, GitRepositoryHandler.TYPE_NAME, namespace, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,34 +38,31 @@ package sonia.scm.repository.spi;
|
|||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import com.google.common.io.Files;
|
import com.google.common.io.Files;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
|
|
||||||
import org.eclipse.jgit.api.CommitCommand;
|
import org.eclipse.jgit.api.CommitCommand;
|
||||||
import org.eclipse.jgit.api.Git;
|
import org.eclipse.jgit.api.Git;
|
||||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||||
import org.eclipse.jgit.revwalk.RevCommit;
|
import org.eclipse.jgit.revwalk.RevCommit;
|
||||||
import org.eclipse.jgit.transport.ScmTransportProtocol;
|
import org.eclipse.jgit.transport.ScmTransportProtocol;
|
||||||
import org.eclipse.jgit.transport.Transport;
|
import org.eclipse.jgit.transport.Transport;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.rules.TemporaryFolder;
|
import org.junit.rules.TemporaryFolder;
|
||||||
|
|
||||||
import sonia.scm.repository.Changeset;
|
import sonia.scm.repository.Changeset;
|
||||||
import sonia.scm.repository.GitRepositoryHandler;
|
import sonia.scm.repository.GitRepositoryHandler;
|
||||||
import sonia.scm.repository.Repository;
|
import sonia.scm.repository.Repository;
|
||||||
import sonia.scm.user.User;
|
import sonia.scm.user.User;
|
||||||
import sonia.scm.user.UserTestData;
|
import sonia.scm.user.UserTestData;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
import static org.mockito.Mockito.*;
|
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Sebastian Sdorra
|
* @author Sebastian Sdorra
|
||||||
@@ -88,8 +85,8 @@ public class AbstractRemoteCommandTestBase
|
|||||||
outgoingDirectory = tempFolder.newFile("outgoing");
|
outgoingDirectory = tempFolder.newFile("outgoing");
|
||||||
outgoingDirectory.delete();
|
outgoingDirectory.delete();
|
||||||
|
|
||||||
incomgingRepository = new Repository("1", "git", "incoming");
|
incomgingRepository = new Repository("1", "git", "space", "incoming");
|
||||||
outgoingRepository = new Repository("2", "git", "outgoing");
|
outgoingRepository = new Repository("2", "git", "space", "outgoing");
|
||||||
|
|
||||||
incoming = Git.init().setDirectory(incomingDirectory).setBare(false).call();
|
incoming = Git.init().setDirectory(incomingDirectory).setBare(false).call();
|
||||||
outgoing = Git.init().setDirectory(outgoingDirectory).setBare(false).call();
|
outgoing = Git.init().setDirectory(outgoingDirectory).setBare(false).call();
|
||||||
|
|||||||
@@ -35,14 +35,15 @@ package sonia.scm.web.lfs;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import static org.mockito.Matchers.matches;
|
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
import sonia.scm.repository.Repository;
|
import sonia.scm.repository.Repository;
|
||||||
import sonia.scm.store.BlobStoreFactory;
|
import sonia.scm.store.BlobStoreFactory;
|
||||||
|
|
||||||
|
import static org.mockito.Matchers.matches;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link LfsBlobStoreFactory}.
|
* Unit tests for {@link LfsBlobStoreFactory}.
|
||||||
*
|
*
|
||||||
@@ -59,7 +60,7 @@ public class LfsBlobStoreFactoryTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getBlobStore() throws Exception {
|
public void getBlobStore() throws Exception {
|
||||||
lfsBlobStoreFactory.getLfsBlobStore(new Repository("the-id", "GIT", "the-name"));
|
lfsBlobStoreFactory.getLfsBlobStore(new Repository("the-id", "GIT", "space", "the-name"));
|
||||||
|
|
||||||
// just make sure the right parameter is passed, as properly validating the return value is nearly impossible with
|
// just make sure the right parameter is passed, as properly validating the return value is nearly impossible with
|
||||||
// the return value (and should not be part of this test)
|
// the return value (and should not be part of this test)
|
||||||
|
|||||||
@@ -7,8 +7,9 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by omilke on 18.05.2017.
|
* Created by omilke on 18.05.2017.
|
||||||
@@ -18,14 +19,15 @@ public class LfsServletFactoryTest {
|
|||||||
@Test
|
@Test
|
||||||
public void buildBaseUri() throws Exception {
|
public void buildBaseUri() throws Exception {
|
||||||
|
|
||||||
|
String repositoryNamespace = "space";
|
||||||
String repositoryName = "git-lfs-demo";
|
String repositoryName = "git-lfs-demo";
|
||||||
|
|
||||||
String result = LfsServletFactory.buildBaseUri(new Repository("", "GIT", repositoryName), RequestWithUri(repositoryName, true));
|
String result = LfsServletFactory.buildBaseUri(new Repository("", "GIT", repositoryNamespace, repositoryName), RequestWithUri(repositoryName, true));
|
||||||
assertThat(result, is(equalTo("http://localhost:8081/scm/git/git-lfs-demo.git/info/lfs/objects/")));
|
assertThat(result, is(equalTo("http://localhost:8081/scm/git/git-lfs-demo.git/info/lfs/objects/")));
|
||||||
|
|
||||||
|
|
||||||
//result will be with dot-gix suffix, ide
|
//result will be with dot-gix suffix, ide
|
||||||
result = LfsServletFactory.buildBaseUri(new Repository("", "GIT", repositoryName), RequestWithUri(repositoryName, false));
|
result = LfsServletFactory.buildBaseUri(new Repository("", "GIT", repositoryNamespace, repositoryName), RequestWithUri(repositoryName, false));
|
||||||
assertThat(result, is(equalTo("http://localhost:8081/scm/git/git-lfs-demo.git/info/lfs/objects/")));
|
assertThat(result, is(equalTo("http://localhost:8081/scm/git/git-lfs-demo.git/info/lfs/objects/")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,20 +34,18 @@ package sonia.scm.repository.spi;
|
|||||||
//~--- non-JDK imports --------------------------------------------------------
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
import com.aragost.javahg.Repository;
|
import com.aragost.javahg.Repository;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import sonia.scm.repository.HgHookManager;
|
import sonia.scm.repository.HgHookManager;
|
||||||
import sonia.scm.repository.HgRepositoryHandler;
|
import sonia.scm.repository.HgRepositoryHandler;
|
||||||
import sonia.scm.repository.RepositoryHookType;
|
import sonia.scm.repository.RepositoryHookType;
|
||||||
import sonia.scm.repository.spi.javahg.HgLogChangesetCommand;
|
import sonia.scm.repository.spi.javahg.HgLogChangesetCommand;
|
||||||
import sonia.scm.web.HgUtil;
|
import sonia.scm.web.HgUtil;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Sebastian Sdorra
|
* @author Sebastian Sdorra
|
||||||
@@ -63,22 +61,12 @@ public class HgHookChangesetProvider implements HookChangesetProvider
|
|||||||
|
|
||||||
//~--- constructors ---------------------------------------------------------
|
//~--- constructors ---------------------------------------------------------
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs ...
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param handler
|
|
||||||
* @param repositoryName
|
|
||||||
* @param hookManager
|
|
||||||
* @param startRev
|
|
||||||
* @param type
|
|
||||||
*/
|
|
||||||
public HgHookChangesetProvider(HgRepositoryHandler handler,
|
public HgHookChangesetProvider(HgRepositoryHandler handler,
|
||||||
String repositoryName, HgHookManager hookManager, String startRev,
|
String id, HgHookManager hookManager, String startRev,
|
||||||
RepositoryHookType type)
|
RepositoryHookType type)
|
||||||
{
|
{
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
this.repositoryName = repositoryName;
|
this.id = id;
|
||||||
this.hookManager = hookManager;
|
this.hookManager = hookManager;
|
||||||
this.startRev = startRev;
|
this.startRev = startRev;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
@@ -136,7 +124,7 @@ public class HgHookChangesetProvider implements HookChangesetProvider
|
|||||||
private Repository open()
|
private Repository open()
|
||||||
{
|
{
|
||||||
File directory = handler.getConfig().getRepositoryDirectory();
|
File directory = handler.getConfig().getRepositoryDirectory();
|
||||||
File repositoryDirectory = new File(directory, repositoryName);
|
File repositoryDirectory = new File(directory, id);
|
||||||
|
|
||||||
// use HG_PENDING only for pre receive hooks
|
// use HG_PENDING only for pre receive hooks
|
||||||
boolean pending = type == RepositoryHookType.PRE_RECEIVE;
|
boolean pending = type == RepositoryHookType.PRE_RECEIVE;
|
||||||
@@ -155,7 +143,7 @@ public class HgHookChangesetProvider implements HookChangesetProvider
|
|||||||
private HgHookManager hookManager;
|
private HgHookManager hookManager;
|
||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
private String repositoryName;
|
private String id;
|
||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
private HookChangesetResponse response;
|
private HookChangesetResponse response;
|
||||||
|
|||||||
@@ -38,16 +38,16 @@ import sonia.scm.repository.HgRepositoryHandler;
|
|||||||
import sonia.scm.repository.RepositoryHookType;
|
import sonia.scm.repository.RepositoryHookType;
|
||||||
import sonia.scm.repository.api.HgHookBranchProvider;
|
import sonia.scm.repository.api.HgHookBranchProvider;
|
||||||
import sonia.scm.repository.api.HgHookMessageProvider;
|
import sonia.scm.repository.api.HgHookMessageProvider;
|
||||||
|
import sonia.scm.repository.api.HgHookTagProvider;
|
||||||
import sonia.scm.repository.api.HookBranchProvider;
|
import sonia.scm.repository.api.HookBranchProvider;
|
||||||
import sonia.scm.repository.api.HookFeature;
|
import sonia.scm.repository.api.HookFeature;
|
||||||
import sonia.scm.repository.api.HookMessageProvider;
|
import sonia.scm.repository.api.HookMessageProvider;
|
||||||
|
import sonia.scm.repository.api.HookTagProvider;
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import sonia.scm.repository.api.HgHookTagProvider;
|
|
||||||
import sonia.scm.repository.api.HookTagProvider;
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mercurial implementation of {@link HookContextProvider}.
|
* Mercurial implementation of {@link HookContextProvider}.
|
||||||
@@ -67,17 +67,16 @@ public class HgHookContextProvider extends HookContextProvider
|
|||||||
* Constructs a new instance.
|
* Constructs a new instance.
|
||||||
*
|
*
|
||||||
* @param handler mercurial repository handler
|
* @param handler mercurial repository handler
|
||||||
* @param repositoryName name of changed repository
|
* @param namespaceAndName namespace and name of changed repository
|
||||||
* @param hookManager mercurial hook manager
|
* @param hookManager mercurial hook manager
|
||||||
* @param startRev start revision
|
* @param startRev start revision
|
||||||
* @param type type of hook
|
* @param type type of hook
|
||||||
*/
|
*/
|
||||||
public HgHookContextProvider(HgRepositoryHandler handler,
|
public HgHookContextProvider(HgRepositoryHandler handler,
|
||||||
String repositoryName, HgHookManager hookManager, String startRev,
|
String id, HgHookManager hookManager, String startRev,
|
||||||
RepositoryHookType type)
|
RepositoryHookType type)
|
||||||
{
|
{
|
||||||
this.hookChangesetProvider = new HgHookChangesetProvider(handler,
|
this.hookChangesetProvider = new HgHookChangesetProvider(handler, id, hookManager, startRev, type);
|
||||||
repositoryName, hookManager, startRev, type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|||||||
@@ -39,10 +39,8 @@ import com.google.common.base.Stopwatch;
|
|||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import sonia.scm.SCMContext;
|
import sonia.scm.SCMContext;
|
||||||
import sonia.scm.config.ScmConfiguration;
|
import sonia.scm.config.ScmConfiguration;
|
||||||
import sonia.scm.repository.HgConfig;
|
import sonia.scm.repository.HgConfig;
|
||||||
@@ -60,19 +58,17 @@ import sonia.scm.web.cgi.CGIExecutor;
|
|||||||
import sonia.scm.web.cgi.CGIExecutorFactory;
|
import sonia.scm.web.cgi.CGIExecutorFactory;
|
||||||
import sonia.scm.web.cgi.EnvList;
|
import sonia.scm.web.cgi.EnvList;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Base64;
|
|
||||||
|
|
||||||
import java.util.Enumeration;
|
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -305,7 +301,7 @@ public class HgCGIServlet extends HttpServlet
|
|||||||
executor.setExceptionHandler(exceptionHandler);
|
executor.setExceptionHandler(exceptionHandler);
|
||||||
executor.setStatusCodeHandler(exceptionHandler);
|
executor.setStatusCodeHandler(exceptionHandler);
|
||||||
executor.setContentLengthWorkaround(true);
|
executor.setContentLengthWorkaround(true);
|
||||||
executor.getEnvironment().set(ENV_REPOSITORY_NAME, name);
|
executor.getEnvironment().set(ENV_REPOSITORY_NAME, repository.getNamespace() + "/" + repository.getName());
|
||||||
executor.getEnvironment().set(ENV_REPOSITORY_PATH,
|
executor.getEnvironment().set(ENV_REPOSITORY_PATH,
|
||||||
directory.getAbsolutePath());
|
directory.getAbsolutePath());
|
||||||
|
|
||||||
|
|||||||
@@ -40,13 +40,10 @@ import com.google.common.io.Closeables;
|
|||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
|
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.SecurityUtils;
|
||||||
import org.apache.shiro.subject.Subject;
|
import org.apache.shiro.subject.Subject;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import sonia.scm.repository.HgContext;
|
import sonia.scm.repository.HgContext;
|
||||||
import sonia.scm.repository.HgHookManager;
|
import sonia.scm.repository.HgHookManager;
|
||||||
import sonia.scm.repository.HgRepositoryHandler;
|
import sonia.scm.repository.HgRepositoryHandler;
|
||||||
@@ -62,19 +59,17 @@ import sonia.scm.security.Tokens;
|
|||||||
import sonia.scm.util.HttpUtil;
|
import sonia.scm.util.HttpUtil;
|
||||||
import sonia.scm.util.Util;
|
import sonia.scm.util.Util;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -167,27 +162,24 @@ public class HgHookCallbackServlet extends HttpServlet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param request
|
|
||||||
* @param response
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* @throws ServletException
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected void doPost(HttpServletRequest request,
|
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||||
HttpServletResponse response)
|
try {
|
||||||
throws ServletException, IOException
|
handlePostRequest(request, response);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.warn("error in hook callback execution, sending internal server error", ex);
|
||||||
|
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handlePostRequest(HttpServletRequest request, HttpServletResponse response) throws IOException
|
||||||
{
|
{
|
||||||
String strippedURI = HttpUtil.getStrippedURI(request);
|
String strippedURI = HttpUtil.getStrippedURI(request);
|
||||||
Matcher m = REGEX_URL.matcher(strippedURI);
|
Matcher m = REGEX_URL.matcher(strippedURI);
|
||||||
|
|
||||||
if (m.matches())
|
if (m.matches())
|
||||||
{
|
{
|
||||||
String repositoryId = getRepositoryName(request);
|
String id = getRepositoryId(request);
|
||||||
String type = m.group(1);
|
String type = m.group(1);
|
||||||
String challenge = request.getParameter(PARAM_CHALLENGE);
|
String challenge = request.getParameter(PARAM_CHALLENGE);
|
||||||
|
|
||||||
@@ -204,7 +196,7 @@ public class HgHookCallbackServlet extends HttpServlet
|
|||||||
authenticate(request, credentials);
|
authenticate(request, credentials);
|
||||||
}
|
}
|
||||||
|
|
||||||
hookCallback(response, repositoryId, type, challenge, node);
|
hookCallback(response, id, type, challenge, node);
|
||||||
}
|
}
|
||||||
else if (logger.isDebugEnabled())
|
else if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
@@ -227,13 +219,6 @@ public class HgHookCallbackServlet extends HttpServlet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param request
|
|
||||||
* @param credentials
|
|
||||||
*/
|
|
||||||
private void authenticate(HttpServletRequest request, String credentials)
|
private void authenticate(HttpServletRequest request, String credentials)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -270,18 +255,7 @@ public class HgHookCallbackServlet extends HttpServlet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void fireHook(HttpServletResponse response, String id,
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param response
|
|
||||||
* @param repositoryName
|
|
||||||
* @param node
|
|
||||||
* @param type
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
private void fireHook(HttpServletResponse response, String repositoryName,
|
|
||||||
String node, RepositoryHookType type)
|
String node, RepositoryHookType type)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
@@ -294,11 +268,10 @@ public class HgHookCallbackServlet extends HttpServlet
|
|||||||
contextProvider.get().setPending(true);
|
contextProvider.get().setPending(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
context = new HgHookContextProvider(handler, repositoryName, hookManager,
|
context = new HgHookContextProvider(handler, id, hookManager,
|
||||||
node, type);
|
node, type);
|
||||||
|
|
||||||
hookEventFacade.handle(HgRepositoryHandler.TYPE_NAME,
|
hookEventFacade.handle(id).fireHookEvent(type, context);
|
||||||
repositoryName).fireHookEvent(type, context);
|
|
||||||
|
|
||||||
printMessages(response, context);
|
printMessages(response, context);
|
||||||
}
|
}
|
||||||
@@ -306,7 +279,7 @@ public class HgHookCallbackServlet extends HttpServlet
|
|||||||
{
|
{
|
||||||
if (logger.isErrorEnabled())
|
if (logger.isErrorEnabled())
|
||||||
{
|
{
|
||||||
logger.error("could not find repository {}", repositoryName);
|
logger.error("could not find repository with id {}", id);
|
||||||
|
|
||||||
if (logger.isTraceEnabled())
|
if (logger.isTraceEnabled())
|
||||||
{
|
{
|
||||||
@@ -322,22 +295,7 @@ public class HgHookCallbackServlet extends HttpServlet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void hookCallback(HttpServletResponse response, String id, String typeName, String challenge, String node) throws IOException {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param response
|
|
||||||
* @param repositoryName
|
|
||||||
* @param typeName
|
|
||||||
* @param challenge
|
|
||||||
* @param node
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
private void hookCallback(HttpServletResponse response,
|
|
||||||
String repositoryName, String typeName, String challenge, String node)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
if (hookManager.isAcceptAble(challenge))
|
if (hookManager.isAcceptAble(challenge))
|
||||||
{
|
{
|
||||||
RepositoryHookType type = null;
|
RepositoryHookType type = null;
|
||||||
@@ -353,7 +311,7 @@ public class HgHookCallbackServlet extends HttpServlet
|
|||||||
|
|
||||||
if (type != null)
|
if (type != null)
|
||||||
{
|
{
|
||||||
fireHook(response, repositoryName, node, type);
|
fireHook(response, id, node, type);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -403,12 +361,12 @@ public class HgHookCallbackServlet extends HttpServlet
|
|||||||
* Method description
|
* Method description
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @param resonse
|
* @param response
|
||||||
* @param context
|
* @param context
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
private void printMessages(HttpServletResponse resonse,
|
private void printMessages(HttpServletResponse response,
|
||||||
HgHookContextProvider context)
|
HgHookContextProvider context)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
@@ -420,7 +378,7 @@ public class HgHookCallbackServlet extends HttpServlet
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
writer = resonse.getWriter();
|
writer = response.getWriter();
|
||||||
|
|
||||||
printMessages(writer, msgs);
|
printMessages(writer, msgs);
|
||||||
}
|
}
|
||||||
@@ -506,9 +464,9 @@ public class HgHookCallbackServlet extends HttpServlet
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private String getRepositoryName(HttpServletRequest request)
|
private String getRepositoryId(HttpServletRequest request)
|
||||||
{
|
{
|
||||||
String name = null;
|
String id = null;
|
||||||
String path = request.getParameter(PARAM_REPOSITORYPATH);
|
String path = request.getParameter(PARAM_REPOSITORYPATH);
|
||||||
|
|
||||||
if (Util.isNotEmpty(path))
|
if (Util.isNotEmpty(path))
|
||||||
@@ -520,11 +478,11 @@ public class HgHookCallbackServlet extends HttpServlet
|
|||||||
*/
|
*/
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
name = RepositoryUtil.getRepositoryName(handler, path);
|
id = RepositoryUtil.getRepositoryId(handler, path);
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
catch (IOException ex)
|
||||||
{
|
{
|
||||||
logger.error("could not find name of repository", ex);
|
logger.error("could not find namespace and name of repository", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (logger.isWarnEnabled())
|
else if (logger.isWarnEnabled())
|
||||||
@@ -532,7 +490,7 @@ public class HgHookCallbackServlet extends HttpServlet
|
|||||||
logger.warn("no repository path parameter found");
|
logger.warn("no repository path parameter found");
|
||||||
}
|
}
|
||||||
|
|
||||||
return name;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- fields ---------------------------------------------------------------
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2010, Sebastian Sdorra
|
* Copyright (c) 2010, Sebastian Sdorra
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
* <p>
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
*
|
* <p>
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
* 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
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
* contributors may be used to endorse or promote products derived from this
|
* contributors may be used to endorse or promote products derived from this
|
||||||
* software without specific prior written permission.
|
* software without specific prior written permission.
|
||||||
*
|
* <p>
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
@@ -24,43 +24,45 @@
|
|||||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
* <p>
|
||||||
* http://bitbucket.org/sdorra/scm-manager
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package sonia.scm.repository;
|
package sonia.scm.repository;
|
||||||
|
|
||||||
//~--- non-JDK imports --------------------------------------------------------
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
import sonia.scm.io.DefaultFileSystem;
|
import sonia.scm.io.DefaultFileSystem;
|
||||||
|
import sonia.scm.store.ConfigurationStoreFactory;
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import sonia.scm.store.ConfigurationStoreFactory;
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Sebastian Sdorra
|
* @author Sebastian Sdorra
|
||||||
*/
|
*/
|
||||||
public class HgRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
{
|
public class HgRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ConfigurationStoreFactory factory;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private com.google.inject.Provider<HgContext> provider;
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param directory
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected void checkDirectory(File directory)
|
protected void checkDirectory(File directory) {
|
||||||
{
|
|
||||||
File hgDirectory = new File(directory, ".hg");
|
File hgDirectory = new File(directory, ".hg");
|
||||||
|
|
||||||
assertTrue(hgDirectory.exists());
|
assertTrue(hgDirectory.exists());
|
||||||
@@ -73,19 +75,9 @@ public class HgRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase
|
|||||||
assertTrue(hgrc.length() > 0);
|
assertTrue(hgrc.length() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param factory
|
|
||||||
* @param directory
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected RepositoryHandler createRepositoryHandler(ConfigurationStoreFactory factory,
|
protected RepositoryHandler createRepositoryHandler(ConfigurationStoreFactory factory,
|
||||||
File directory)
|
File directory) {
|
||||||
{
|
|
||||||
HgRepositoryHandler handler = new HgRepositoryHandler(factory,
|
HgRepositoryHandler handler = new HgRepositoryHandler(factory,
|
||||||
new DefaultFileSystem(),
|
new DefaultFileSystem(),
|
||||||
new HgContextProvider());
|
new HgContextProvider());
|
||||||
@@ -97,5 +89,21 @@ public class HgRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase
|
|||||||
|
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getDirectory() {
|
||||||
|
HgRepositoryHandler repositoryHandler = new HgRepositoryHandler(factory,
|
||||||
|
new DefaultFileSystem(), provider);
|
||||||
|
|
||||||
|
HgConfig hgConfig = new HgConfig();
|
||||||
|
hgConfig.setRepositoryDirectory(new File("/path"));
|
||||||
|
hgConfig.setHgBinary("hg");
|
||||||
|
hgConfig.setPythonBinary("python");
|
||||||
|
repositoryHandler.setConfig(hgConfig);
|
||||||
|
|
||||||
|
Repository repository = new Repository("id", "git", "Space", "Name");
|
||||||
|
|
||||||
|
File path = repositoryHandler.getDirectory(repository);
|
||||||
|
assertEquals("/path/id", path.getAbsolutePath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//~--- non-JDK imports --------------------------------------------------------
|
|
||||||
|
|||||||
@@ -41,14 +41,11 @@ import com.aragost.javahg.Repository;
|
|||||||
import com.aragost.javahg.RepositoryConfiguration;
|
import com.aragost.javahg.RepositoryConfiguration;
|
||||||
import com.aragost.javahg.commands.AddCommand;
|
import com.aragost.javahg.commands.AddCommand;
|
||||||
import com.aragost.javahg.commands.CommitCommand;
|
import com.aragost.javahg.commands.CommitCommand;
|
||||||
|
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import com.google.common.io.Files;
|
import com.google.common.io.Files;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.rules.TemporaryFolder;
|
import org.junit.rules.TemporaryFolder;
|
||||||
|
|
||||||
import sonia.scm.AbstractTestBase;
|
import sonia.scm.AbstractTestBase;
|
||||||
import sonia.scm.repository.HgConfig;
|
import sonia.scm.repository.HgConfig;
|
||||||
import sonia.scm.repository.HgContext;
|
import sonia.scm.repository.HgContext;
|
||||||
@@ -58,15 +55,15 @@ import sonia.scm.user.User;
|
|||||||
import sonia.scm.user.UserTestData;
|
import sonia.scm.user.UserTestData;
|
||||||
import sonia.scm.util.MockUtil;
|
import sonia.scm.util.MockUtil;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
import static org.mockito.Mockito.*;
|
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Sebastian Sdorra
|
* @author Sebastian Sdorra
|
||||||
@@ -90,10 +87,8 @@ public abstract class IncomingOutgoingTestBase extends AbstractTestBase
|
|||||||
incomingDirectory = tempFolder.newFolder("incoming");
|
incomingDirectory = tempFolder.newFolder("incoming");
|
||||||
outgoingDirectory = tempFolder.newFolder("outgoing");
|
outgoingDirectory = tempFolder.newFolder("outgoing");
|
||||||
|
|
||||||
incomingRepository = new sonia.scm.repository.Repository("1", "hg",
|
incomingRepository = new sonia.scm.repository.Repository("1", "hg", "space", "incoming");
|
||||||
"incoming");
|
outgoingRepository = new sonia.scm.repository.Repository("2", "hg", "space", "outgoing");
|
||||||
outgoingRepository = new sonia.scm.repository.Repository("2", "hg",
|
|
||||||
"outgoing");
|
|
||||||
|
|
||||||
incoming = Repository.create(createConfig(temp), incomingDirectory);
|
incoming = Repository.create(createConfig(temp), incomingDirectory);
|
||||||
outgoing = Repository.create(createConfig(temp), outgoingDirectory);
|
outgoing = Repository.create(createConfig(temp), outgoingDirectory);
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package sonia.scm.web;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import sonia.scm.repository.HgConfig;
|
||||||
|
import sonia.scm.repository.HgRepositoryHandler;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.mockito.Matchers.anyInt;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import static sonia.scm.web.HgHookCallbackServlet.PARAM_REPOSITORYPATH;
|
||||||
|
|
||||||
|
public class HgHookCallbackServletTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldExtractCorrectRepositoryId() throws ServletException, IOException {
|
||||||
|
HgRepositoryHandler handler = mock(HgRepositoryHandler.class);
|
||||||
|
HgHookCallbackServlet servlet = new HgHookCallbackServlet(null, handler, null, null);
|
||||||
|
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||||
|
HttpServletResponse response = mock(HttpServletResponse.class);
|
||||||
|
HgConfig config = mock(HgConfig.class);
|
||||||
|
|
||||||
|
when(request.getContextPath()).thenReturn("http://example.com/scm");
|
||||||
|
when(request.getRequestURI()).thenReturn("http://example.com/scm/hook/hg/pretxnchangegroup");
|
||||||
|
when(request.getParameter(PARAM_REPOSITORYPATH)).thenReturn("/tmp/hg/12345");
|
||||||
|
|
||||||
|
when(handler.getConfig()).thenReturn(config);
|
||||||
|
when(config.getRepositoryDirectory()).thenReturn(new File("/tmp/hg"));
|
||||||
|
|
||||||
|
servlet.doPost(request, response);
|
||||||
|
|
||||||
|
verify(response, never()).sendError(anyInt());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -37,7 +37,6 @@ package sonia.scm.repository;
|
|||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import org.tmatesoft.svn.core.SVNCancelException;
|
import org.tmatesoft.svn.core.SVNCancelException;
|
||||||
import org.tmatesoft.svn.core.SVNErrorCode;
|
import org.tmatesoft.svn.core.SVNErrorCode;
|
||||||
import org.tmatesoft.svn.core.SVNErrorMessage;
|
import org.tmatesoft.svn.core.SVNErrorMessage;
|
||||||
@@ -45,21 +44,19 @@ import org.tmatesoft.svn.core.SVNException;
|
|||||||
import org.tmatesoft.svn.core.internal.io.fs.FSHook;
|
import org.tmatesoft.svn.core.internal.io.fs.FSHook;
|
||||||
import org.tmatesoft.svn.core.internal.io.fs.FSHookEvent;
|
import org.tmatesoft.svn.core.internal.io.fs.FSHookEvent;
|
||||||
import org.tmatesoft.svn.core.internal.io.fs.FSHooks;
|
import org.tmatesoft.svn.core.internal.io.fs.FSHooks;
|
||||||
|
|
||||||
import sonia.scm.repository.spi.AbstractSvnHookChangesetProvider;
|
import sonia.scm.repository.spi.AbstractSvnHookChangesetProvider;
|
||||||
import sonia.scm.repository.spi.HookEventFacade;
|
import sonia.scm.repository.spi.HookEventFacade;
|
||||||
import sonia.scm.repository.spi.SvnHookContextProvider;
|
import sonia.scm.repository.spi.SvnHookContextProvider;
|
||||||
import sonia.scm.repository.spi.SvnPostReceiveHookChangesetProvier;
|
import sonia.scm.repository.spi.SvnPostReceiveHookChangesetProvier;
|
||||||
import sonia.scm.repository.spi.SvnPreReceiveHookChangesetProvier;
|
import sonia.scm.repository.spi.SvnPreReceiveHookChangesetProvier;
|
||||||
import sonia.scm.util.AssertUtil;
|
import sonia.scm.util.AssertUtil;
|
||||||
import sonia.scm.util.IOUtil;
|
|
||||||
import sonia.scm.util.Util;
|
import sonia.scm.util.Util;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Sebastian Sdorra
|
* @author Sebastian Sdorra
|
||||||
@@ -166,12 +163,10 @@ public class SvnRepositoryHook implements FSHook
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
String name = getRepositoryName(directory);
|
String id = getRepositoryId(directory);
|
||||||
|
|
||||||
name = IOUtil.trimSeperatorChars(name);
|
|
||||||
|
|
||||||
//J-
|
//J-
|
||||||
hookEventFacade.handle(SvnRepositoryHandler.TYPE_NAME, name)
|
hookEventFacade.handle(id)
|
||||||
.fireHookEvent(
|
.fireHookEvent(
|
||||||
changesetProvider.getType(),
|
changesetProvider.getType(),
|
||||||
new SvnHookContextProvider(changesetProvider)
|
new SvnHookContextProvider(changesetProvider)
|
||||||
@@ -202,11 +197,11 @@ public class SvnRepositoryHook implements FSHook
|
|||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
private String getRepositoryName(File directory) throws IOException
|
private String getRepositoryId(File directory) throws IOException
|
||||||
{
|
{
|
||||||
AssertUtil.assertIsNotNull(directory);
|
AssertUtil.assertIsNotNull(directory);
|
||||||
|
|
||||||
return RepositoryUtil.getRepositoryName(handler, directory);
|
return RepositoryUtil.getRepositoryId(handler, directory);
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- fields ---------------------------------------------------------------
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|||||||
@@ -37,13 +37,10 @@ package sonia.scm.web;
|
|||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import org.tmatesoft.svn.core.internal.server.dav.DAVConfig;
|
import org.tmatesoft.svn.core.internal.server.dav.DAVConfig;
|
||||||
import org.tmatesoft.svn.core.internal.server.dav.DAVServlet;
|
import org.tmatesoft.svn.core.internal.server.dav.DAVServlet;
|
||||||
|
|
||||||
import sonia.scm.repository.Repository;
|
import sonia.scm.repository.Repository;
|
||||||
import sonia.scm.repository.RepositoryProvider;
|
import sonia.scm.repository.RepositoryProvider;
|
||||||
import sonia.scm.repository.RepositoryRequestListenerUtil;
|
import sonia.scm.repository.RepositoryRequestListenerUtil;
|
||||||
@@ -51,14 +48,13 @@ import sonia.scm.repository.SvnRepositoryHandler;
|
|||||||
import sonia.scm.util.AssertUtil;
|
import sonia.scm.util.AssertUtil;
|
||||||
import sonia.scm.util.HttpUtil;
|
import sonia.scm.util.HttpUtil;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletRequestWrapper;
|
import javax.servlet.http.HttpServletRequestWrapper;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -224,7 +220,7 @@ public class SvnDAVServlet extends DAVServlet
|
|||||||
pathInfo = pathInfo.substring(1);
|
pathInfo = pathInfo.substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pathInfo = pathInfo.substring(repository.getName().length());
|
pathInfo = pathInfo.substring(repository.getNamespace().length() + 1 + repository.getName().length());
|
||||||
}
|
}
|
||||||
|
|
||||||
return pathInfo;
|
return pathInfo;
|
||||||
@@ -249,7 +245,7 @@ public class SvnDAVServlet extends DAVServlet
|
|||||||
servletPath = servletPath.concat(HttpUtil.SEPARATOR_PATH);
|
servletPath = servletPath.concat(HttpUtil.SEPARATOR_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
servletPath = servletPath.concat(repository.getName());
|
servletPath = servletPath + repository.getNamespace() + "/" + repository.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
return servletPath;
|
return servletPath;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2010, Sebastian Sdorra
|
* Copyright (c) 2010, Sebastian Sdorra
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
* <p>
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
*
|
* <p>
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
* 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
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
* contributors may be used to endorse or promote products derived from this
|
* contributors may be used to endorse or promote products derived from this
|
||||||
* software without specific prior written permission.
|
* software without specific prior written permission.
|
||||||
*
|
* <p>
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
@@ -24,42 +24,56 @@
|
|||||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
* <p>
|
||||||
* http://bitbucket.org/sdorra/scm-manager
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package sonia.scm.repository;
|
package sonia.scm.repository;
|
||||||
|
|
||||||
//~--- non-JDK imports --------------------------------------------------------
|
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
import sonia.scm.io.DefaultFileSystem;
|
import sonia.scm.io.DefaultFileSystem;
|
||||||
|
import sonia.scm.repository.api.HookContextFactory;
|
||||||
import static org.junit.Assert.*;
|
import sonia.scm.repository.spi.HookEventFacade;
|
||||||
|
import sonia.scm.store.ConfigurationStore;
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
import sonia.scm.store.ConfigurationStoreFactory;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import sonia.scm.store.ConfigurationStoreFactory;
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Sebastian Sdorra
|
* @author Sebastian Sdorra
|
||||||
*/
|
*/
|
||||||
public class SvnRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
{
|
public class SvnRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ConfigurationStoreFactory factory;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ConfigurationStore store;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private com.google.inject.Provider<RepositoryManager> repositoryManagerProvider;
|
||||||
|
|
||||||
|
private HookContextFactory hookContextFactory = new HookContextFactory(mock(PreProcessorUtil.class));
|
||||||
|
|
||||||
|
private HookEventFacade facade = new HookEventFacade(repositoryManagerProvider, hookContextFactory);
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param directory
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected void checkDirectory(File directory)
|
protected void checkDirectory(File directory) {
|
||||||
{
|
|
||||||
File format = new File(directory, "format");
|
File format = new File(directory, "format");
|
||||||
|
|
||||||
assertTrue(format.exists());
|
assertTrue(format.exists());
|
||||||
@@ -71,19 +85,9 @@ public class SvnRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase
|
|||||||
assertTrue(db.isDirectory());
|
assertTrue(db.isDirectory());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param factory
|
|
||||||
* @param directory
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected RepositoryHandler createRepositoryHandler(ConfigurationStoreFactory factory,
|
protected RepositoryHandler createRepositoryHandler(ConfigurationStoreFactory factory,
|
||||||
File directory)
|
File directory) {
|
||||||
{
|
|
||||||
SvnRepositoryHandler handler = new SvnRepositoryHandler(factory,
|
SvnRepositoryHandler handler = new SvnRepositoryHandler(factory,
|
||||||
new DefaultFileSystem(), null);
|
new DefaultFileSystem(), null);
|
||||||
|
|
||||||
@@ -98,4 +102,20 @@ public class SvnRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase
|
|||||||
|
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getDirectory() {
|
||||||
|
when(factory.getStore(any(), any())).thenReturn(store);
|
||||||
|
SvnRepositoryHandler repositoryHandler = new SvnRepositoryHandler(factory,
|
||||||
|
new DefaultFileSystem(), facade);
|
||||||
|
|
||||||
|
SvnConfig svnConfig = new SvnConfig();
|
||||||
|
svnConfig.setRepositoryDirectory(new File("/path"));
|
||||||
|
repositoryHandler.setConfig(svnConfig);
|
||||||
|
|
||||||
|
Repository repository = new Repository("id", "svn", "Space", "Name");
|
||||||
|
|
||||||
|
File path = repositoryHandler.getDirectory(repository);
|
||||||
|
assertEquals("/path/id", path.getAbsolutePath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2010, Sebastian Sdorra
|
* Copyright (c) 2010, Sebastian Sdorra
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
* <p>
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
*
|
* <p>
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
* 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
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
* contributors may be used to endorse or promote products derived from this
|
* contributors may be used to endorse or promote products derived from this
|
||||||
* software without specific prior written permission.
|
* software without specific prior written permission.
|
||||||
*
|
* <p>
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
@@ -24,113 +24,67 @@
|
|||||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
* <p>
|
||||||
* http://bitbucket.org/sdorra/scm-manager
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package sonia.scm.repository;
|
package sonia.scm.repository;
|
||||||
|
|
||||||
//~--- non-JDK imports --------------------------------------------------------
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
import sonia.scm.Type;
|
import sonia.scm.Type;
|
||||||
import sonia.scm.io.DefaultFileSystem;
|
import sonia.scm.io.DefaultFileSystem;
|
||||||
|
import sonia.scm.store.ConfigurationStoreFactory;
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.util.HashSet;
|
||||||
import sonia.scm.store.ConfigurationStoreFactory;
|
import java.util.Set;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Sebastian Sdorra
|
* @author Sebastian Sdorra
|
||||||
*/
|
*/
|
||||||
public class DummyRepositoryHandler
|
public class DummyRepositoryHandler
|
||||||
extends AbstractSimpleRepositoryHandler<SimpleRepositoryConfig>
|
extends AbstractSimpleRepositoryHandler<SimpleRepositoryConfig> {
|
||||||
{
|
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
public static final String TYPE_DISPLAYNAME = "Dummy";
|
public static final String TYPE_DISPLAYNAME = "Dummy";
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
public static final String TYPE_NAME = "dummy";
|
public static final String TYPE_NAME = "dummy";
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
public static final Type TYPE = new Type(TYPE_NAME, TYPE_DISPLAYNAME);
|
public static final Type TYPE = new Type(TYPE_NAME, TYPE_DISPLAYNAME);
|
||||||
|
|
||||||
//~--- constructors ---------------------------------------------------------
|
private final Set<String> existingRepoNames = new HashSet<>();
|
||||||
|
|
||||||
/**
|
public DummyRepositoryHandler(ConfigurationStoreFactory storeFactory) {
|
||||||
* Constructs ...
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param storeFactory
|
|
||||||
*/
|
|
||||||
public DummyRepositoryHandler(ConfigurationStoreFactory storeFactory)
|
|
||||||
{
|
|
||||||
super(storeFactory, new DefaultFileSystem());
|
super(storeFactory, new DefaultFileSystem());
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Type getType()
|
public Type getType() {
|
||||||
{
|
|
||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repository
|
|
||||||
* @param directory
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected void create(Repository repository, File directory)
|
protected void create(Repository repository, File directory) throws RepositoryException {
|
||||||
throws RepositoryException, IOException
|
String key = repository.getNamespace() + "/" + repository.getName();
|
||||||
{
|
if (existingRepoNames.contains(key)) {
|
||||||
|
throw new RepositoryAlreadyExistsException("Repo exists");
|
||||||
// do nothing
|
} else {
|
||||||
|
existingRepoNames.add(key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected SimpleRepositoryConfig createInitialConfig()
|
protected SimpleRepositoryConfig createInitialConfig() {
|
||||||
{
|
|
||||||
return new SimpleRepositoryConfig();
|
return new SimpleRepositoryConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected Class<SimpleRepositoryConfig> getConfigClass()
|
protected Class<SimpleRepositoryConfig> getConfigClass() {
|
||||||
{
|
|
||||||
return SimpleRepositoryConfig.class;
|
return SimpleRepositoryConfig.class;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package sonia.scm.repository;
|
||||||
|
|
||||||
|
public class RepositoryBuilder {
|
||||||
|
|
||||||
|
private String id = "id-" + ++nextID;
|
||||||
|
private String contact = "test@example.com";
|
||||||
|
private String description = "";
|
||||||
|
private String namespace = "test";
|
||||||
|
private String name = "name";
|
||||||
|
private String type = "git";
|
||||||
|
|
||||||
|
private static int nextID = 0;
|
||||||
|
|
||||||
|
public RepositoryBuilder type(String type) {
|
||||||
|
this.type = type;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RepositoryBuilder contact(String contact) {
|
||||||
|
this.contact = contact;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RepositoryBuilder namespace(String namespace) {
|
||||||
|
this.namespace = namespace;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RepositoryBuilder name(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RepositoryBuilder description(String description) {
|
||||||
|
this.description = description;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Repository build() {
|
||||||
|
Repository repository = new Repository();
|
||||||
|
repository.setId(id);
|
||||||
|
repository.setType(type);
|
||||||
|
repository.setContact(contact);
|
||||||
|
repository.setNamespace(namespace);
|
||||||
|
repository.setName(name);
|
||||||
|
repository.setDescription(description);
|
||||||
|
return repository;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,154 +26,68 @@
|
|||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* http://bitbucket.org/sdorra/scm-manager
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package sonia.scm.repository;
|
package sonia.scm.repository;
|
||||||
|
|
||||||
/**
|
public final class RepositoryTestData {
|
||||||
*
|
|
||||||
* @author Sebastian Sdorra
|
|
||||||
*/
|
|
||||||
public final class RepositoryTestData
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
private RepositoryTestData() {
|
||||||
* Constructs ...
|
}
|
||||||
*
|
|
||||||
*/
|
|
||||||
private RepositoryTestData() {}
|
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
public static Repository create42Puzzle() {
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static Repository create42Puzzle()
|
|
||||||
{
|
|
||||||
return create42Puzzle(DummyRepositoryHandler.TYPE_NAME);
|
return create42Puzzle(DummyRepositoryHandler.TYPE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static Repository create42Puzzle(String type) {
|
||||||
* Method description
|
return new RepositoryBuilder()
|
||||||
*
|
.type(type)
|
||||||
*
|
.contact("douglas.adams@hitchhiker.com")
|
||||||
* @param type
|
.name("42Puzzle")
|
||||||
*
|
.description("The 42 Puzzle")
|
||||||
* @return
|
.build();
|
||||||
*/
|
|
||||||
public static Repository create42Puzzle(String type)
|
|
||||||
{
|
|
||||||
Repository repository = new Repository();
|
|
||||||
|
|
||||||
repository.setType(type);
|
|
||||||
repository.setContact("douglas.adams@hitchhiker.com");
|
|
||||||
repository.setName("42Puzzle");
|
|
||||||
repository.setDescription("The 42 Puzzle");
|
|
||||||
|
|
||||||
return repository;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static Repository createHappyVerticalPeopleTransporter() {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static Repository createHappyVerticalPeopleTransporter()
|
|
||||||
{
|
|
||||||
return createHappyVerticalPeopleTransporter(
|
return createHappyVerticalPeopleTransporter(
|
||||||
DummyRepositoryHandler.TYPE_NAME);
|
DummyRepositoryHandler.TYPE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static Repository createHappyVerticalPeopleTransporter(String type) {
|
||||||
* Method description
|
return new RepositoryBuilder()
|
||||||
*
|
.type(type)
|
||||||
*
|
.contact("zaphod.beeblebrox@hitchhiker.com")
|
||||||
*
|
.name("happyVerticalPeopleTransporter")
|
||||||
* @param type
|
.description("Happy Vertical People Transporter")
|
||||||
* @return
|
.build();
|
||||||
*/
|
|
||||||
public static Repository createHappyVerticalPeopleTransporter(String type)
|
|
||||||
{
|
|
||||||
Repository happyVerticalPeopleTransporter = new Repository();
|
|
||||||
|
|
||||||
happyVerticalPeopleTransporter.setType(type);
|
|
||||||
happyVerticalPeopleTransporter.setContact(
|
|
||||||
"zaphod.beeblebrox@hitchhiker.com");
|
|
||||||
happyVerticalPeopleTransporter.setName("happyVerticalPeopleTransporter");
|
|
||||||
happyVerticalPeopleTransporter.setDescription(
|
|
||||||
"Happy Vertical People Transporter");
|
|
||||||
|
|
||||||
return happyVerticalPeopleTransporter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static Repository createHeartOfGold() {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static Repository createHeartOfGold()
|
|
||||||
{
|
|
||||||
return createHeartOfGold(DummyRepositoryHandler.TYPE_NAME);
|
return createHeartOfGold(DummyRepositoryHandler.TYPE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static Repository createHeartOfGold(String type) {
|
||||||
* Method description
|
return new RepositoryBuilder()
|
||||||
*
|
.type(type)
|
||||||
*
|
.contact("zaphod.beeblebrox@hitchhiker.com")
|
||||||
*
|
.name("HeartOfGold")
|
||||||
* @param type
|
.description(
|
||||||
* @return
|
"Heart of Gold is the first prototype ship to successfully utilise the revolutionary Infinite Improbability Drive")
|
||||||
*/
|
.build();
|
||||||
public static Repository createHeartOfGold(String type)
|
|
||||||
{
|
|
||||||
Repository heartOfGold = new Repository();
|
|
||||||
|
|
||||||
heartOfGold.setType(type);
|
|
||||||
heartOfGold.setContact("zaphod.beeblebrox@hitchhiker.com");
|
|
||||||
heartOfGold.setName("HeartOfGold");
|
|
||||||
heartOfGold.setDescription(
|
|
||||||
"Heart of Gold is the first prototype ship to successfully utilise the revolutionary Infinite Improbability Drive");
|
|
||||||
|
|
||||||
return heartOfGold;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static Repository createRestaurantAtTheEndOfTheUniverse() {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static Repository createRestaurantAtTheEndOfTheUniverse()
|
|
||||||
{
|
|
||||||
return createRestaurantAtTheEndOfTheUniverse(
|
return createRestaurantAtTheEndOfTheUniverse(
|
||||||
DummyRepositoryHandler.TYPE_NAME);
|
DummyRepositoryHandler.TYPE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static Repository createRestaurantAtTheEndOfTheUniverse(String type) {
|
||||||
* Method description
|
return new RepositoryBuilder()
|
||||||
*
|
.type(type)
|
||||||
*
|
.contact("douglas.adams@hitchhiker.com")
|
||||||
* @param type
|
.name("RestaurantAtTheEndOfTheUniverse")
|
||||||
*
|
.description("The Restaurant at the End of the Universe")
|
||||||
* @return
|
.build();
|
||||||
*/
|
|
||||||
public static Repository createRestaurantAtTheEndOfTheUniverse(String type)
|
|
||||||
{
|
|
||||||
Repository repository = new Repository();
|
|
||||||
|
|
||||||
repository.setType(type);
|
|
||||||
repository.setContact("douglas.adams@hitchhiker.com");
|
|
||||||
repository.setName("RestaurantAtTheEndOfTheUniverse");
|
|
||||||
repository.setDescription("The Restaurant at the End of the Universe");
|
|
||||||
|
|
||||||
return repository;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2010, Sebastian Sdorra
|
* Copyright (c) 2010, Sebastian Sdorra
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
* <p>
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
*
|
* <p>
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
* 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
|
* 3. Neither the name of SCM-Manager; nor the names of its
|
||||||
* contributors may be used to endorse or promote products derived from this
|
* contributors may be used to endorse or promote products derived from this
|
||||||
* software without specific prior written permission.
|
* software without specific prior written permission.
|
||||||
*
|
* <p>
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
@@ -24,169 +24,88 @@
|
|||||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
* <p>
|
||||||
* http://bitbucket.org/sdorra/scm-manager
|
* http://bitbucket.org/sdorra/scm-manager
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package sonia.scm.repository;
|
package sonia.scm.repository;
|
||||||
|
|
||||||
//~--- non-JDK imports --------------------------------------------------------
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import sonia.scm.AbstractTestBase;
|
import sonia.scm.AbstractTestBase;
|
||||||
|
import sonia.scm.store.ConfigurationStoreFactory;
|
||||||
import sonia.scm.store.InMemoryConfigurationStoreFactory;
|
import sonia.scm.store.InMemoryConfigurationStoreFactory;
|
||||||
import sonia.scm.util.IOUtil;
|
import sonia.scm.util.IOUtil;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import java.io.File;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import sonia.scm.store.ConfigurationStoreFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Sebastian Sdorra
|
* @author Sebastian Sdorra
|
||||||
*/
|
*/
|
||||||
public abstract class SimpleRepositoryHandlerTestBase extends AbstractTestBase
|
public abstract class SimpleRepositoryHandlerTestBase extends AbstractTestBase {
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param directory
|
|
||||||
*/
|
|
||||||
protected abstract void checkDirectory(File directory);
|
protected abstract void checkDirectory(File directory);
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param factory
|
|
||||||
* @param directory
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
protected abstract RepositoryHandler createRepositoryHandler(
|
protected abstract RepositoryHandler createRepositoryHandler(
|
||||||
ConfigurationStoreFactory factory, File directory);
|
ConfigurationStoreFactory factory, File directory);
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreate() throws RepositoryException, IOException
|
public void testCreate() throws RepositoryException {
|
||||||
{
|
|
||||||
createRepository();
|
createRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
@Test(expected = RepositoryAlreadyExistsException.class)
|
|
||||||
public void testCreateExisitingRepository()
|
|
||||||
throws RepositoryException, IOException
|
|
||||||
{
|
|
||||||
createRepository();
|
|
||||||
createRepository();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateResourcePath() throws RepositoryException, IOException
|
public void testCreateResourcePath() throws RepositoryException {
|
||||||
{
|
|
||||||
Repository repository = createRepository();
|
Repository repository = createRepository();
|
||||||
String path = handler.createResourcePath(repository);
|
String path = handler.createResourcePath(repository);
|
||||||
|
|
||||||
assertNotNull(path);
|
assertNotNull(path);
|
||||||
assertTrue(path.trim().length() > 0);
|
assertTrue(path.trim().length() > 0);
|
||||||
assertTrue(path.contains(repository.getName()));
|
assertTrue(path.contains(repository.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testDelete() throws RepositoryException, IOException
|
public void testDelete() throws RepositoryException {
|
||||||
{
|
|
||||||
Repository repository = createRepository();
|
Repository repository = createRepository();
|
||||||
|
|
||||||
handler.delete(repository);
|
handler.delete(repository);
|
||||||
|
|
||||||
File directory = new File(baseDirectory, repository.getName());
|
File directory = new File(baseDirectory, repository.getId());
|
||||||
|
|
||||||
assertFalse(directory.exists());
|
assertFalse(directory.exists());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected void postSetUp() throws Exception
|
protected void postSetUp() {
|
||||||
{
|
|
||||||
InMemoryConfigurationStoreFactory storeFactory = new InMemoryConfigurationStoreFactory();
|
InMemoryConfigurationStoreFactory storeFactory = new InMemoryConfigurationStoreFactory();
|
||||||
baseDirectory = new File(contextProvider.getBaseDirectory(), "repositories");
|
baseDirectory = new File(contextProvider.getBaseDirectory(), "repositories");
|
||||||
IOUtil.mkdirs(baseDirectory);
|
IOUtil.mkdirs(baseDirectory);
|
||||||
handler = createRepositoryHandler(storeFactory, baseDirectory);
|
handler = createRepositoryHandler(storeFactory, baseDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected void preTearDown() throws Exception
|
protected void preTearDown() throws Exception {
|
||||||
{
|
if (handler != null) {
|
||||||
if (handler != null)
|
|
||||||
{
|
|
||||||
handler.close();
|
handler.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private Repository createRepository() throws RepositoryException {
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
private Repository createRepository() throws RepositoryException, IOException
|
|
||||||
{
|
|
||||||
Repository repository = RepositoryTestData.createHeartOfGold();
|
Repository repository = RepositoryTestData.createHeartOfGold();
|
||||||
|
|
||||||
handler.create(repository);
|
handler.create(repository);
|
||||||
|
|
||||||
File directory = new File(baseDirectory, repository.getName());
|
File directory = new File(baseDirectory, repository.getId());
|
||||||
|
|
||||||
assertTrue(directory.exists());
|
assertTrue(directory.exists());
|
||||||
assertTrue(directory.isDirectory());
|
assertTrue(directory.isDirectory());
|
||||||
@@ -195,11 +114,7 @@ public abstract class SimpleRepositoryHandlerTestBase extends AbstractTestBase
|
|||||||
return repository;
|
return repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- fields ---------------------------------------------------------------
|
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
protected File baseDirectory;
|
protected File baseDirectory;
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
private RepositoryHandler handler;
|
private RepositoryHandler handler;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,16 +57,8 @@ import sonia.scm.group.xml.XmlGroupDAO;
|
|||||||
import sonia.scm.io.DefaultFileSystem;
|
import sonia.scm.io.DefaultFileSystem;
|
||||||
import sonia.scm.io.FileSystem;
|
import sonia.scm.io.FileSystem;
|
||||||
import sonia.scm.net.SSLContextProvider;
|
import sonia.scm.net.SSLContextProvider;
|
||||||
import sonia.scm.net.ahc.AdvancedHttpClient;
|
import sonia.scm.net.ahc.*;
|
||||||
import sonia.scm.net.ahc.ContentTransformer;
|
import sonia.scm.plugin.*;
|
||||||
import sonia.scm.net.ahc.DefaultAdvancedHttpClient;
|
|
||||||
import sonia.scm.net.ahc.JsonContentTransformer;
|
|
||||||
import sonia.scm.net.ahc.XmlContentTransformer;
|
|
||||||
import sonia.scm.plugin.DefaultPluginLoader;
|
|
||||||
import sonia.scm.plugin.DefaultPluginManager;
|
|
||||||
import sonia.scm.plugin.ExtensionProcessor;
|
|
||||||
import sonia.scm.plugin.PluginLoader;
|
|
||||||
import sonia.scm.plugin.PluginManager;
|
|
||||||
import sonia.scm.repository.*;
|
import sonia.scm.repository.*;
|
||||||
import sonia.scm.repository.api.HookContextFactory;
|
import sonia.scm.repository.api.HookContextFactory;
|
||||||
import sonia.scm.repository.api.RepositoryServiceFactory;
|
import sonia.scm.repository.api.RepositoryServiceFactory;
|
||||||
@@ -78,32 +70,13 @@ import sonia.scm.resources.ResourceManager;
|
|||||||
import sonia.scm.resources.ScriptResourceServlet;
|
import sonia.scm.resources.ScriptResourceServlet;
|
||||||
import sonia.scm.schedule.QuartzScheduler;
|
import sonia.scm.schedule.QuartzScheduler;
|
||||||
import sonia.scm.schedule.Scheduler;
|
import sonia.scm.schedule.Scheduler;
|
||||||
import sonia.scm.security.AuthorizationChangedEventProducer;
|
import sonia.scm.security.*;
|
||||||
import sonia.scm.security.CipherHandler;
|
import sonia.scm.store.*;
|
||||||
import sonia.scm.security.CipherUtil;
|
|
||||||
import sonia.scm.security.ConfigurableLoginAttemptHandler;
|
|
||||||
import sonia.scm.security.DefaultKeyGenerator;
|
|
||||||
import sonia.scm.security.DefaultSecuritySystem;
|
|
||||||
import sonia.scm.security.KeyGenerator;
|
|
||||||
import sonia.scm.security.LoginAttemptHandler;
|
|
||||||
import sonia.scm.security.SecuritySystem;
|
|
||||||
import sonia.scm.store.BlobStoreFactory;
|
|
||||||
import sonia.scm.store.ConfigurationEntryStoreFactory;
|
|
||||||
import sonia.scm.store.ConfigurationStoreFactory;
|
|
||||||
import sonia.scm.store.DataStoreFactory;
|
|
||||||
import sonia.scm.store.FileBlobStoreFactory;
|
|
||||||
import sonia.scm.store.JAXBConfigurationEntryStoreFactory;
|
|
||||||
import sonia.scm.store.JAXBConfigurationStoreFactory;
|
|
||||||
import sonia.scm.store.JAXBDataStoreFactory;
|
|
||||||
import sonia.scm.template.MustacheTemplateEngine;
|
import sonia.scm.template.MustacheTemplateEngine;
|
||||||
import sonia.scm.template.TemplateEngine;
|
import sonia.scm.template.TemplateEngine;
|
||||||
import sonia.scm.template.TemplateEngineFactory;
|
import sonia.scm.template.TemplateEngineFactory;
|
||||||
import sonia.scm.template.TemplateServlet;
|
import sonia.scm.template.TemplateServlet;
|
||||||
import sonia.scm.url.RestJsonUrlProvider;
|
import sonia.scm.url.*;
|
||||||
import sonia.scm.url.RestXmlUrlProvider;
|
|
||||||
import sonia.scm.url.UrlProvider;
|
|
||||||
import sonia.scm.url.UrlProviderFactory;
|
|
||||||
import sonia.scm.url.WebUIUrlProvider;
|
|
||||||
import sonia.scm.user.DefaultUserManager;
|
import sonia.scm.user.DefaultUserManager;
|
||||||
import sonia.scm.user.UserDAO;
|
import sonia.scm.user.UserDAO;
|
||||||
import sonia.scm.user.UserManager;
|
import sonia.scm.user.UserManager;
|
||||||
@@ -224,6 +197,8 @@ public class ScmServletModule extends ServletModule
|
|||||||
ScmConfiguration config = getScmConfiguration();
|
ScmConfiguration config = getScmConfiguration();
|
||||||
CipherUtil cu = CipherUtil.getInstance();
|
CipherUtil cu = CipherUtil.getInstance();
|
||||||
|
|
||||||
|
bind(NamespaceStrategy.class).toProvider(NamespaceStrategyProvider.class);
|
||||||
|
|
||||||
// bind repository provider
|
// bind repository provider
|
||||||
ThrowingProviderBinder.create(binder()).bind(
|
ThrowingProviderBinder.create(binder()).bind(
|
||||||
RepositoryProvider.class, Repository.class).to(
|
RepositoryProvider.class, Repository.class).to(
|
||||||
@@ -351,10 +326,10 @@ public class ScmServletModule extends ServletModule
|
|||||||
// bind events
|
// bind events
|
||||||
// bind(LastModifiedUpdateListener.class);
|
// bind(LastModifiedUpdateListener.class);
|
||||||
|
|
||||||
Class<? extends NamespaceStrategy> namespaceStrategy = extensionProcessor.byExtensionPoint(NamespaceStrategy.class).iterator().next();
|
|
||||||
bind(NamespaceStrategy.class, namespaceStrategy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method description
|
* Method description
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -543,7 +543,8 @@ public class RepositoryImportResource
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
repository = new Repository(null, type, name);
|
// TODO #8783
|
||||||
|
// repository = new Repository(null, type, name);
|
||||||
manager.create(repository);
|
manager.create(repository);
|
||||||
}
|
}
|
||||||
catch (RepositoryAlreadyExistsException ex)
|
catch (RepositoryAlreadyExistsException ex)
|
||||||
@@ -738,7 +739,8 @@ public class RepositoryImportResource
|
|||||||
{
|
{
|
||||||
for (String repositoryName : repositoryNames)
|
for (String repositoryName : repositoryNames)
|
||||||
{
|
{
|
||||||
Repository repository = manager.get(type, repositoryName);
|
// TODO #8783
|
||||||
|
/*Repository repository = null; //manager.get(type, repositoryName);
|
||||||
|
|
||||||
if (repository != null)
|
if (repository != null)
|
||||||
{
|
{
|
||||||
@@ -748,7 +750,7 @@ public class RepositoryImportResource
|
|||||||
{
|
{
|
||||||
logger.warn("could not find imported repository {}",
|
logger.warn("could not find imported repository {}",
|
||||||
repositoryName);
|
repositoryName);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -556,42 +556,6 @@ public class RepositoryResource extends AbstractManagerResource<Repository, Repo
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@link Repository} with the specified type and name.
|
|
||||||
*
|
|
||||||
* @param type the type of the repository
|
|
||||||
* @param name the name of the repository
|
|
||||||
*
|
|
||||||
* @return the {@link Repository} with the specified type and name
|
|
||||||
*/
|
|
||||||
@GET
|
|
||||||
@Path("{type: [a-z]+}/{name: .*}")
|
|
||||||
@StatusCodes({
|
|
||||||
@ResponseCode(code = 200, condition = "success"),
|
|
||||||
@ResponseCode(code = 404, condition = "not found, no repository with the specified type and name available"),
|
|
||||||
@ResponseCode(code = 500, condition = "internal server error")
|
|
||||||
})
|
|
||||||
@TypeHint(Repository.class)
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
|
|
||||||
public Response getByTypeAndName(@PathParam("type") String type,
|
|
||||||
@PathParam("name") String name)
|
|
||||||
{
|
|
||||||
Response response;
|
|
||||||
Repository repository = repositoryManager.get(type, name);
|
|
||||||
|
|
||||||
if (repository != null)
|
|
||||||
{
|
|
||||||
prepareForReturn(repository);
|
|
||||||
response = Response.ok(repository).build();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
response = Response.status(Response.Status.NOT_FOUND).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link Changeset} from the given repository
|
* Returns the {@link Changeset} from the given repository
|
||||||
* with the specified revision.
|
* with the specified revision.
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
package sonia.scm.repository;
|
package sonia.scm.repository;
|
||||||
|
|
||||||
|
import org.apache.shiro.SecurityUtils;
|
||||||
import sonia.scm.plugin.Extension;
|
import sonia.scm.plugin.Extension;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The DefaultNamespaceStrategy returns the username of the currently logged in user as namespace.
|
||||||
|
* @since 2.0.0
|
||||||
|
*/
|
||||||
@Extension
|
@Extension
|
||||||
public class DefaultNamespaceStrategy implements NamespaceStrategy{
|
public class DefaultNamespaceStrategy implements NamespaceStrategy {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getNamespace() {
|
public String getNamespace() {
|
||||||
return "42";
|
return SecurityUtils.getSubject().getPrincipal().toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() {
|
||||||
executorService.shutdown();
|
executorService.shutdown();
|
||||||
|
|
||||||
for (RepositoryHandler handler : handlerMap.values()) {
|
for (RepositoryHandler handler : handlerMap.values()) {
|
||||||
@@ -177,40 +177,16 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager {
|
|||||||
getHandler(toDelete).delete(toDelete);
|
getHandler(toDelete).delete(toDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repository
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void importRepository(Repository repository)
|
public void importRepository(Repository repository)
|
||||||
throws RepositoryException, IOException {
|
throws RepositoryException, IOException {
|
||||||
create(repository, false);
|
create(repository, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void init(SCMContextProvider context) {
|
public void init(SCMContextProvider context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repository
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void modify(Repository repository) throws RepositoryException {
|
public void modify(Repository repository) throws RepositoryException {
|
||||||
logger.info("modify repository {} of type {}", repository.getName(), repository.getType());
|
logger.info("modify repository {} of type {}", repository.getName(), repository.getType());
|
||||||
@@ -226,23 +202,13 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repository
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void refresh(Repository repository)
|
public void refresh(Repository repository)
|
||||||
throws RepositoryException {
|
throws RepositoryException {
|
||||||
AssertUtil.assertIsNotNull(repository);
|
AssertUtil.assertIsNotNull(repository);
|
||||||
RepositoryPermissions.read(repository).check();
|
RepositoryPermissions.read(repository).check();
|
||||||
|
|
||||||
Repository fresh = repositoryDAO.get(repository.getType(),
|
Repository fresh = repositoryDAO.get(repository.getNamespaceAndName());
|
||||||
repository.getName());
|
|
||||||
|
|
||||||
if (fresh != null) {
|
if (fresh != null) {
|
||||||
fresh.copyProperties(repository);
|
fresh.copyProperties(repository);
|
||||||
@@ -251,16 +217,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Repository get(String id) {
|
public Repository get(String id) {
|
||||||
AssertUtil.assertIsNotEmpty(id);
|
AssertUtil.assertIsNotEmpty(id);
|
||||||
@@ -276,21 +233,13 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager {
|
|||||||
return repository;
|
return repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param type
|
|
||||||
* @param name
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Repository get(String type, String name) {
|
public Repository get(NamespaceAndName namespaceAndName) {
|
||||||
AssertUtil.assertIsNotEmpty(type);
|
AssertUtil.assertIsNotNull(namespaceAndName);
|
||||||
AssertUtil.assertIsNotEmpty(name);
|
AssertUtil.assertIsNotEmpty(namespaceAndName.getNamespace());
|
||||||
|
AssertUtil.assertIsNotEmpty(namespaceAndName.getName());
|
||||||
|
|
||||||
Repository repository = repositoryDAO.get(type, name);
|
Repository repository = repositoryDAO.get(namespaceAndName);
|
||||||
|
|
||||||
if (repository != null) {
|
if (repository != null) {
|
||||||
RepositoryPermissions.read(repository).check();
|
RepositoryPermissions.read(repository).check();
|
||||||
@@ -300,14 +249,6 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager {
|
|||||||
return repository;
|
return repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param comparator
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Repository> getAll(Comparator<Repository> comparator) {
|
public Collection<Repository> getAll(Comparator<Repository> comparator) {
|
||||||
List<Repository> repositories = Lists.newArrayList();
|
List<Repository> repositories = Lists.newArrayList();
|
||||||
@@ -330,28 +271,12 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager {
|
|||||||
return repositories;
|
return repositories;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Repository> getAll() {
|
public Collection<Repository> getAll() {
|
||||||
return getAll(null);
|
return getAll(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param comparator
|
|
||||||
* @param start
|
|
||||||
* @param limit
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Repository> getAll(Comparator<Repository> comparator,
|
public Collection<Repository> getAll(Comparator<Repository> comparator,
|
||||||
int start, int limit) {
|
int start, int limit) {
|
||||||
@@ -369,26 +294,11 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager {
|
|||||||
}, start, limit);
|
}, start, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param start
|
|
||||||
* @param limit
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Repository> getAll(int start, int limit) {
|
public Collection<Repository> getAll(int start, int limit) {
|
||||||
return getAll(null, start, limit);
|
return getAll(null, start, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Type> getConfiguredTypes() {
|
public Collection<Type> getConfiguredTypes() {
|
||||||
List<Type> validTypes = Lists.newArrayList();
|
List<Type> validTypes = Lists.newArrayList();
|
||||||
@@ -402,14 +312,6 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager {
|
|||||||
return validTypes;
|
return validTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param request
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Repository getFromRequest(HttpServletRequest request) {
|
public Repository getFromRequest(HttpServletRequest request) {
|
||||||
AssertUtil.assertIsNotNull(request);
|
AssertUtil.assertIsNotNull(request);
|
||||||
@@ -417,17 +319,28 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager {
|
|||||||
return getFromUri(HttpUtil.getStrippedURI(request));
|
return getFromUri(HttpUtil.getStrippedURI(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param type
|
|
||||||
* @param uri
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Repository getFromTypeAndUri(String type, String uri) {
|
public Repository getFromUri(String uri) {
|
||||||
|
AssertUtil.assertIsNotEmpty(uri);
|
||||||
|
|
||||||
|
if (uri.startsWith(HttpUtil.SEPARATOR_PATH)) {
|
||||||
|
uri = uri.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int typeSeparator = uri.indexOf(HttpUtil.SEPARATOR_PATH);
|
||||||
|
Repository repository = null;
|
||||||
|
|
||||||
|
if (typeSeparator > 0) {
|
||||||
|
String type = uri.substring(0, typeSeparator);
|
||||||
|
|
||||||
|
uri = uri.substring(typeSeparator + 1);
|
||||||
|
repository = getFromTypeAndUri(type, uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
return repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Repository getFromTypeAndUri(String type, String uri) {
|
||||||
if (Strings.isNullOrEmpty(type)) {
|
if (Strings.isNullOrEmpty(type)) {
|
||||||
throw new ArgumentIsInvalidException("argument type is required");
|
throw new ArgumentIsInvalidException("argument type is required");
|
||||||
}
|
}
|
||||||
@@ -464,80 +377,21 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager {
|
|||||||
return repository;
|
return repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param uri
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Repository getFromUri(String uri) {
|
|
||||||
AssertUtil.assertIsNotEmpty(uri);
|
|
||||||
|
|
||||||
if (uri.startsWith(HttpUtil.SEPARATOR_PATH)) {
|
|
||||||
uri = uri.substring(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int typeSeperator = uri.indexOf(HttpUtil.SEPARATOR_PATH);
|
|
||||||
Repository repository = null;
|
|
||||||
|
|
||||||
if (typeSeperator > 0) {
|
|
||||||
String type = uri.substring(0, typeSeperator);
|
|
||||||
|
|
||||||
uri = uri.substring(typeSeperator + 1);
|
|
||||||
repository = getFromTypeAndUri(type, uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
return repository;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param type
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public RepositoryHandler getHandler(String type) {
|
public RepositoryHandler getHandler(String type) {
|
||||||
return handlerMap.get(type);
|
return handlerMap.get(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Long getLastModified() {
|
public Long getLastModified() {
|
||||||
return repositoryDAO.getLastModified();
|
return repositoryDAO.getLastModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Type> getTypes() {
|
public Collection<Type> getTypes() {
|
||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param contextProvider
|
|
||||||
* @param handler
|
|
||||||
*/
|
|
||||||
private void addHandler(SCMContextProvider contextProvider,
|
private void addHandler(SCMContextProvider contextProvider,
|
||||||
RepositoryHandler handler) {
|
RepositoryHandler handler) {
|
||||||
AssertUtil.assertIsNotNull(handler);
|
AssertUtil.assertIsNotNull(handler);
|
||||||
@@ -561,19 +415,6 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager {
|
|||||||
types.add(type);
|
types.add(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repository
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @throws RepositoryException
|
|
||||||
*/
|
|
||||||
private RepositoryHandler getHandler(Repository repository)
|
private RepositoryHandler getHandler(Repository repository)
|
||||||
throws RepositoryException {
|
throws RepositoryException {
|
||||||
String type = repository.getType();
|
String type = repository.getType();
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ package sonia.scm.repository;
|
|||||||
|
|
||||||
//~--- non-JDK imports --------------------------------------------------------
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.github.legman.Subscribe;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|||||||
@@ -32,14 +32,15 @@
|
|||||||
|
|
||||||
package sonia.scm.repository;
|
package sonia.scm.repository;
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import java.util.Map;
|
import org.slf4j.Logger;
|
||||||
import java.util.Set;
|
import org.slf4j.LoggerFactory;
|
||||||
import javax.inject.Inject;
|
import sonia.scm.util.HttpUtil;
|
||||||
import org.slf4j.Logger;
|
import sonia.scm.util.Util;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import sonia.scm.util.HttpUtil;
|
import javax.inject.Inject;
|
||||||
import sonia.scm.util.Util;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RepositoryMatcher is able to check if a repository matches the requested path.
|
* RepositoryMatcher is able to check if a repository matches the requested path.
|
||||||
@@ -83,7 +84,22 @@ public final class RepositoryMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isPathMatching(Repository repository, String path) {
|
private boolean isPathMatching(Repository repository, String path) {
|
||||||
return getPathMatcherForType(repository.getType()).isPathMatching(repository, path);
|
|
||||||
|
String namespace = extractNamespace(path);
|
||||||
|
String remainingPath = path.substring(namespace.length() + 1);
|
||||||
|
|
||||||
|
return getPathMatcherForType(repository.getType()).isPathMatching(repository, remainingPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String extractNamespace(String path) {
|
||||||
|
if (path.startsWith(HttpUtil.SEPARATOR_PATH)) {
|
||||||
|
path = path.substring(1);
|
||||||
|
}
|
||||||
|
int namespaceSeparator = path.indexOf(HttpUtil.SEPARATOR_PATH);
|
||||||
|
if (namespaceSeparator > 0) {
|
||||||
|
return path.substring(0, namespaceSeparator);
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("no namespace in path " + path);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RepositoryPathMatcher getPathMatcherForType(String type) {
|
private RepositoryPathMatcher getPathMatcherForType(String type) {
|
||||||
|
|||||||
@@ -30,8 +30,8 @@
|
|||||||
*/
|
*/
|
||||||
package sonia.scm.security;
|
package sonia.scm.security;
|
||||||
|
|
||||||
|
import com.github.legman.Subscribe;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.eventbus.Subscribe;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import sonia.scm.EagerSingleton;
|
import sonia.scm.EagerSingleton;
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package sonia.scm.repository;
|
||||||
|
|
||||||
|
import com.github.sdorra.shiro.ShiroRule;
|
||||||
|
import com.github.sdorra.shiro.SubjectAware;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
@SubjectAware(configuration = "classpath:sonia/scm/shiro-001.ini")
|
||||||
|
public class DefaultNamespaceStrategyTest {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public ShiroRule shiroRule = new ShiroRule();
|
||||||
|
|
||||||
|
private DefaultNamespaceStrategy namespaceStrategy = new DefaultNamespaceStrategy();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SubjectAware(username = "trillian", password = "secret")
|
||||||
|
public void testNamespaceStrategy() {
|
||||||
|
assertEquals("trillian", namespaceStrategy.getNamespace());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -96,8 +96,6 @@ public class DefaultRepositoryManagerPerfTest {
|
|||||||
|
|
||||||
private final KeyGenerator keyGenerator = new DefaultKeyGenerator();
|
private final KeyGenerator keyGenerator = new DefaultKeyGenerator();
|
||||||
|
|
||||||
private final NamespaceStrategy namespaceStrategy = new DefaultNamespaceStrategy();
|
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private RepositoryHandler repositoryHandler;
|
private RepositoryHandler repositoryHandler;
|
||||||
|
|
||||||
@@ -114,7 +112,7 @@ public class DefaultRepositoryManagerPerfTest {
|
|||||||
when(repositoryHandler.getType()).thenReturn(new Type(REPOSITORY_TYPE, REPOSITORY_TYPE));
|
when(repositoryHandler.getType()).thenReturn(new Type(REPOSITORY_TYPE, REPOSITORY_TYPE));
|
||||||
Set<RepositoryHandler> handlerSet = ImmutableSet.of(repositoryHandler);
|
Set<RepositoryHandler> handlerSet = ImmutableSet.of(repositoryHandler);
|
||||||
RepositoryMatcher repositoryMatcher = new RepositoryMatcher(Collections.<RepositoryPathMatcher>emptySet());
|
RepositoryMatcher repositoryMatcher = new RepositoryMatcher(Collections.<RepositoryPathMatcher>emptySet());
|
||||||
|
NamespaceStrategy namespaceStrategy = mock(NamespaceStrategy.class);
|
||||||
repositoryManager = new DefaultRepositoryManager(
|
repositoryManager = new DefaultRepositoryManager(
|
||||||
configuration,
|
configuration,
|
||||||
contextProvider,
|
contextProvider,
|
||||||
@@ -133,9 +131,6 @@ public class DefaultRepositoryManagerPerfTest {
|
|||||||
ThreadContext.bind(securityManager);
|
ThreadContext.bind(securityManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tear down test objects.
|
|
||||||
*/
|
|
||||||
@After
|
@After
|
||||||
public void tearDown(){
|
public void tearDown(){
|
||||||
ThreadContext.unbindSecurityManager();
|
ThreadContext.unbindSecurityManager();
|
||||||
@@ -188,8 +183,8 @@ private long calculateAverage(List<Long> times) {
|
|||||||
when(repositoryDAO.getAll()).thenReturn(repositories.values());
|
when(repositoryDAO.getAll()).thenReturn(repositories.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Repository createTestRepository(int number){
|
private Repository createTestRepository(int number) {
|
||||||
Repository repository = new Repository(keyGenerator.createKey(), REPOSITORY_TYPE, "repo-" + number);
|
Repository repository = new Repository(keyGenerator.createKey(), REPOSITORY_TYPE, "namespace", "repo-" + number);
|
||||||
repository.getPermissions().add(new Permission("trillian", PermissionType.READ));
|
repository.getPermissions().add(new Permission("trillian", PermissionType.READ));
|
||||||
return repository;
|
return repository;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ import static org.junit.Assert.assertSame;
|
|||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
@@ -101,9 +102,8 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
|||||||
|
|
||||||
private ScmConfiguration configuration;
|
private ScmConfiguration configuration;
|
||||||
|
|
||||||
/**
|
private String mockedNamespace = "default_namespace";
|
||||||
* Tests {@link RepositoryManager#create(TypedObject)}.
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreate() throws RepositoryException {
|
public void testCreate() throws RepositoryException {
|
||||||
Repository heartOfGold = createTestRepository();
|
Repository heartOfGold = createTestRepository();
|
||||||
@@ -113,9 +113,6 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
|||||||
assertRepositoriesEquals(dbRepo, heartOfGold);
|
assertRepositoriesEquals(dbRepo, heartOfGold);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link RepositoryManager#create(TypedObject)} without the required permissions.
|
|
||||||
*/
|
|
||||||
@SubjectAware(
|
@SubjectAware(
|
||||||
username = "unpriv"
|
username = "unpriv"
|
||||||
)
|
)
|
||||||
@@ -124,26 +121,17 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
|||||||
createTestRepository();
|
createTestRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link RepositoryManager#create(TypedObject)} with a already existing repository.
|
|
||||||
*/
|
|
||||||
@Test(expected = RepositoryAlreadyExistsException.class)
|
@Test(expected = RepositoryAlreadyExistsException.class)
|
||||||
public void testCreateExisting() throws RepositoryException {
|
public void testCreateExisting() throws RepositoryException {
|
||||||
createTestRepository();
|
createTestRepository();
|
||||||
createTestRepository();
|
createTestRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link RepositoryManager#delete(TypedObject)}.
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testDelete() throws RepositoryException {
|
public void testDelete() throws RepositoryException {
|
||||||
delete(manager, createTestRepository());
|
delete(manager, createTestRepository());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link RepositoryManager#delete(TypedObject)} without the required permissions.
|
|
||||||
*/
|
|
||||||
@SubjectAware(
|
@SubjectAware(
|
||||||
username = "unpriv"
|
username = "unpriv"
|
||||||
)
|
)
|
||||||
@@ -152,27 +140,17 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
|||||||
delete(manager, createTestRepository());
|
delete(manager, createTestRepository());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link RepositoryManager#delete(TypedObject)} with a non archived repository and with
|
|
||||||
* enabled archive mode.
|
|
||||||
*/
|
|
||||||
@Test(expected = RepositoryIsNotArchivedException.class)
|
@Test(expected = RepositoryIsNotArchivedException.class)
|
||||||
public void testDeleteNonArchived() throws RepositoryException {
|
public void testDeleteNonArchived() throws RepositoryException {
|
||||||
configuration.setEnableRepositoryArchive(true);
|
configuration.setEnableRepositoryArchive(true);
|
||||||
delete(manager, createTestRepository());
|
delete(manager, createTestRepository());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link RepositoryManager#delete(TypedObject)} with a non existing repository.
|
|
||||||
*/
|
|
||||||
@Test(expected = RepositoryNotFoundException.class)
|
@Test(expected = RepositoryNotFoundException.class)
|
||||||
public void testDeleteNotFound() throws RepositoryException {
|
public void testDeleteNotFound() throws RepositoryException {
|
||||||
manager.delete(createRepositoryWithId());
|
manager.delete(createRepositoryWithId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link RepositoryManager#delete(TypedObject)} with enabled archive mode.
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteWithEnabledArchive()
|
public void testDeleteWithEnabledArchive()
|
||||||
throws RepositoryException {
|
throws RepositoryException {
|
||||||
@@ -184,9 +162,6 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
|||||||
delete(drm, repository);
|
delete(drm, repository);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link RepositoryManager#get(java.lang.String)} .
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testGet() throws RepositoryException {
|
public void testGet() throws RepositoryException {
|
||||||
Repository heartOfGold = createTestRepository();
|
Repository heartOfGold = createTestRepository();
|
||||||
@@ -202,9 +177,6 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
|||||||
assertEquals(description, heartOfGold.getDescription());
|
assertEquals(description, heartOfGold.getDescription());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link RepositoryManager#get(java.lang.String)} without required privileges.
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
@SubjectAware(
|
@SubjectAware(
|
||||||
username = "crato"
|
username = "crato"
|
||||||
@@ -217,9 +189,6 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
|||||||
manager.get(heartOfGold.getId());
|
manager.get(heartOfGold.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link RepositoryManager#getAll()}.
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetAll() throws RepositoryException {
|
public void testGetAll() throws RepositoryException {
|
||||||
Repository heartOfGold = createTestRepository();
|
Repository heartOfGold = createTestRepository();
|
||||||
@@ -256,13 +225,10 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
|||||||
heartOfGold.getDescription().equals(heartReference.getDescription()));
|
heartOfGold.getDescription().equals(heartReference.getDescription()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link RepositoryManager#getAll()} with permission for 2 of 3 repositories.
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@SubjectAware(username = "dent")
|
@SubjectAware(username = "dent")
|
||||||
public void testGetAllWithPermissions() throws RepositoryException {
|
public void testGetAllWithPermissionsForTwoOrThreeRepos() throws RepositoryException {
|
||||||
// mock key generator
|
// mock key generator
|
||||||
KeyGenerator keyGenerator = mock(KeyGenerator.class);
|
KeyGenerator keyGenerator = mock(KeyGenerator.class);
|
||||||
Stack<String> keys = new Stack<>();
|
Stack<String> keys = new Stack<>();
|
||||||
@@ -302,9 +268,6 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests repository manager events.
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testEvents() throws RepositoryException {
|
public void testEvents() throws RepositoryException {
|
||||||
RepositoryManager repoManager = createRepositoryManager(false);
|
RepositoryManager repoManager = createRepositoryManager(false);
|
||||||
@@ -336,9 +299,6 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
|||||||
assertSame(HandlerEventType.DELETE, listener.postEvent);
|
assertSame(HandlerEventType.DELETE, listener.postEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link RepositoryManager#modify(TypedObject)}.
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testModify() throws RepositoryException {
|
public void testModify() throws RepositoryException {
|
||||||
Repository heartOfGold = createTestRepository();
|
Repository heartOfGold = createTestRepository();
|
||||||
@@ -352,10 +312,6 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
|||||||
assertEquals(hearReference.getDescription(), "prototype ship");
|
assertEquals(hearReference.getDescription(), "prototype ship");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link RepositoryManager#modify(TypedObject)} without
|
|
||||||
* the required permissions.
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
@SubjectAware(username = "crato")
|
@SubjectAware(username = "crato")
|
||||||
public void testModifyWithoutRequiredPermissions() throws RepositoryException {
|
public void testModifyWithoutRequiredPermissions() throws RepositoryException {
|
||||||
@@ -367,18 +323,11 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
|||||||
manager.modify(heartOfGold);
|
manager.modify(heartOfGold);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link RepositoryManager#modify(TypedObject)} with a non
|
|
||||||
* existing repository.
|
|
||||||
*/
|
|
||||||
@Test(expected = RepositoryNotFoundException.class)
|
@Test(expected = RepositoryNotFoundException.class)
|
||||||
public void testModifyNotFound() throws RepositoryException {
|
public void testModifyNotFound() throws RepositoryException {
|
||||||
manager.modify(createRepositoryWithId());
|
manager.modify(createRepositoryWithId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link RepositoryManager#refresh(ModelObject)}.
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testRefresh() throws RepositoryException {
|
public void testRefresh() throws RepositoryException {
|
||||||
Repository heartOfGold = createTestRepository();
|
Repository heartOfGold = createTestRepository();
|
||||||
@@ -389,10 +338,6 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
|||||||
assertEquals(description, heartOfGold.getDescription());
|
assertEquals(description, heartOfGold.getDescription());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link RepositoryManager#refresh(ModelObject)} without
|
|
||||||
* required permissions.
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
@SubjectAware(username = "crato")
|
@SubjectAware(username = "crato")
|
||||||
public void testRefreshWithoutRequiredPermissions() throws RepositoryException {
|
public void testRefreshWithoutRequiredPermissions() throws RepositoryException {
|
||||||
@@ -404,18 +349,11 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
|||||||
manager.refresh(heartOfGold);
|
manager.refresh(heartOfGold);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link RepositoryManager#refresh(ModelObject)} with a non existing
|
|
||||||
* repository.
|
|
||||||
*/
|
|
||||||
@Test(expected = RepositoryNotFoundException.class)
|
@Test(expected = RepositoryNotFoundException.class)
|
||||||
public void testRefreshNotFound() throws RepositoryException {
|
public void testRefreshNotFound() throws RepositoryException {
|
||||||
manager.refresh(createRepositoryWithId());
|
manager.refresh(createRepositoryWithId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests repository hooks.
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testRepositoryHook() throws RepositoryException {
|
public void testRepositoryHook() throws RepositoryException {
|
||||||
CountingReceiveHook hook = new CountingReceiveHook();
|
CountingReceiveHook hook = new CountingReceiveHook();
|
||||||
@@ -436,25 +374,96 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
|||||||
assertEquals(2, hook.eventsReceived);
|
assertEquals(2, hook.eventsReceived);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link RepositoryManager#getFromTypeAndUri(String, String)}.
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void getRepositoryFromRequestUriTest() throws RepositoryException {
|
public void testNamespaceSet() throws Exception {
|
||||||
|
RepositoryManager repoManager = createRepositoryManager(false);
|
||||||
|
Repository repository = spy(createTestRepository());
|
||||||
|
repository.setName("Testrepo");
|
||||||
|
((DefaultRepositoryManager) repoManager).create(repository);
|
||||||
|
assertEquals("default_namespace", repository.getNamespace());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getRepositoryFromRequestUri_withoutLeadingSlash() throws RepositoryException {
|
||||||
RepositoryManager m = createManager();
|
RepositoryManager m = createManager();
|
||||||
m.init(contextProvider);
|
m.init(contextProvider);
|
||||||
|
|
||||||
createRepository(m, new Repository("1", "hg", "scm"));
|
createUriTestRepositories(m);
|
||||||
createRepository(m, new Repository("2", "hg", "scm-test"));
|
|
||||||
createRepository(m, new Repository("3", "git", "project1/test-1"));
|
|
||||||
createRepository(m, new Repository("4", "git", "project1/test-2"));
|
|
||||||
|
|
||||||
assertEquals("scm", m.getFromUri("hg/scm").getName());
|
assertEquals("scm-test", m.getFromUri("hg/namespace/scm-test").getName());
|
||||||
assertEquals("scm-test", m.getFromUri("hg/scm-test").getName());
|
assertEquals("namespace", m.getFromUri("hg/namespace/scm-test").getNamespace());
|
||||||
assertEquals("scm-test", m.getFromUri("/hg/scm-test").getName());
|
}
|
||||||
assertEquals("project1/test-1", m.getFromUri("/git/project1/test-1").getName());
|
|
||||||
assertEquals("project1/test-1", m.getFromUri("/git/project1/test-1/ka/some/path").getName());
|
@Test
|
||||||
assertNull(m.getFromUri("/git/project1/test-3/ka/some/path"));
|
public void getRepositoryFromRequestUri_withLeadingSlash() throws RepositoryException {
|
||||||
|
RepositoryManager m = createManager();
|
||||||
|
m.init(contextProvider);
|
||||||
|
|
||||||
|
createUriTestRepositories(m);
|
||||||
|
|
||||||
|
assertEquals("scm-test", m.getFromUri("/hg/namespace/scm-test").getName());
|
||||||
|
assertEquals("namespace", m.getFromUri("/hg/namespace/scm-test").getNamespace());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getRepositoryFromRequestUri_withPartialName() throws RepositoryException {
|
||||||
|
RepositoryManager m = createManager();
|
||||||
|
m.init(contextProvider);
|
||||||
|
|
||||||
|
createUriTestRepositories(m);
|
||||||
|
|
||||||
|
assertEquals("scm", m.getFromUri("hg/namespace/scm").getName());
|
||||||
|
assertEquals("namespace", m.getFromUri("hg/namespace/scm").getNamespace());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getRepositoryFromRequestUri_withTrailingFilePath() throws RepositoryException {
|
||||||
|
RepositoryManager m = createManager();
|
||||||
|
m.init(contextProvider);
|
||||||
|
|
||||||
|
createUriTestRepositories(m);
|
||||||
|
|
||||||
|
assertEquals("test-1", m.getFromUri("/git/namespace/test-1/ka/some/path").getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getRepositoryFromRequestUri_forNotExistingRepositoryName() throws RepositoryException {
|
||||||
|
RepositoryManager m = createManager();
|
||||||
|
m.init(contextProvider);
|
||||||
|
|
||||||
|
createUriTestRepositories(m);
|
||||||
|
|
||||||
|
assertNull(m.getFromUri("/git/namespace/test-3/ka/some/path"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getRepositoryFromRequestUri_forWrongNamespace() throws RepositoryException {
|
||||||
|
RepositoryManager m = createManager();
|
||||||
|
m.init(contextProvider);
|
||||||
|
|
||||||
|
createUriTestRepositories(m);
|
||||||
|
|
||||||
|
assertNull(m.getFromUri("/git/other/other/test-2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldSetNamespace() throws RepositoryException {
|
||||||
|
Repository repository = new Repository(null, "hg", null, "scm");
|
||||||
|
manager.create(repository);
|
||||||
|
assertNotNull(repository.getId());
|
||||||
|
assertNotNull(repository.getNamespace());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createUriTestRepositories(RepositoryManager m) throws RepositoryException {
|
||||||
|
mockedNamespace = "namespace";
|
||||||
|
createRepository(m, new Repository("1", "hg", "namespace", "scm"));
|
||||||
|
createRepository(m, new Repository("2", "hg", "namespace", "scm-test"));
|
||||||
|
createRepository(m, new Repository("3", "git", "namespace", "test-1"));
|
||||||
|
createRepository(m, new Repository("4", "git", "namespace", "test-2"));
|
||||||
|
|
||||||
|
mockedNamespace = "other";
|
||||||
|
createRepository(m, new Repository("1", "hg", "other", "scm"));
|
||||||
|
createRepository(m, new Repository("2", "hg", "other", "scm-test"));
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
//~--- methods --------------------------------------------------------------
|
||||||
@@ -489,10 +498,11 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
|
|||||||
|
|
||||||
this.configuration = new ScmConfiguration();
|
this.configuration = new ScmConfiguration();
|
||||||
|
|
||||||
NamespaceStrategy namespaceStrategy = new DefaultNamespaceStrategy();
|
|
||||||
|
|
||||||
configuration.setEnableRepositoryArchive(archiveEnabled);
|
configuration.setEnableRepositoryArchive(archiveEnabled);
|
||||||
|
|
||||||
|
NamespaceStrategy namespaceStrategy = mock(NamespaceStrategy.class);
|
||||||
|
when(namespaceStrategy.getNamespace()).thenAnswer(invocation -> mockedNamespace);
|
||||||
|
|
||||||
return new DefaultRepositoryManager(configuration, contextProvider,
|
return new DefaultRepositoryManager(configuration, contextProvider,
|
||||||
keyGenerator, repositoryDAO, handlerSet, createRepositoryMatcher(), namespaceStrategy);
|
keyGenerator, repositoryDAO, handlerSet, createRepositoryMatcher(), namespaceStrategy);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,10 +31,13 @@
|
|||||||
package sonia.scm.repository;
|
package sonia.scm.repository;
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import java.util.Set;
|
|
||||||
import org.junit.Test;
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link RepositoryMatcher}.
|
* Unit tests for {@link RepositoryMatcher}.
|
||||||
@@ -54,11 +57,11 @@ public class RepositoryMatcherTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMatches() {
|
public void testMatches() {
|
||||||
assertFalse(matcher.matches(repository("hg", "scm"), "hg", "scm-test/ka"));
|
assertFalse(matcher.matches(repository("hg", "scm"), "hg", "namespace/scm-test/ka"));
|
||||||
assertFalse(matcher.matches(repository("git", "scm-test"), "hg", "scm-test"));
|
assertFalse(matcher.matches(repository("git", "scm-test"), "hg", "namespace/scm-test"));
|
||||||
|
|
||||||
assertTrue(matcher.matches(repository("hg", "scm-test"), "hg", "scm-test/ka"));
|
assertTrue(matcher.matches(repository("hg", "scm-test"), "hg", "namespace/scm-test/ka"));
|
||||||
assertTrue(matcher.matches(repository("hg", "scm-test"), "hg", "scm-test"));
|
assertTrue(matcher.matches(repository("hg", "scm-test"), "hg", "namespace/scm-test"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -68,7 +71,7 @@ public class RepositoryMatcherTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Repository repository(String type, String name) {
|
private Repository repository(String type, String name) {
|
||||||
return new Repository(type + "-" + name, type, name);
|
return new Repository(type + "-" + name, type, "namespace", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class AbcRepositoryPathMatcher implements RepositoryPathMatcher {
|
private static class AbcRepositoryPathMatcher implements RepositoryPathMatcher {
|
||||||
|
|||||||
Reference in New Issue
Block a user