diff --git a/Jenkinsfile b/Jenkinsfile
index 0f586bf346..36135cf4a4 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -7,12 +7,15 @@ import com.cloudogu.ces.cesbuildlib.*
node('docker') {
// Change this as when we go back to default - necessary for proper SonarQube analysis
- mainBranch = "2.0.0-m3"
+ mainBranch = '2.0.0-m3'
properties([
// Keep only the last 10 build to preserve space
buildDiscarder(logRotator(numToKeepStr: '10')),
- disableConcurrentBuilds()
+ disableConcurrentBuilds(),
+ parameters([
+ string(name: 'dockerTag', trim: true, defaultValue: 'latest', description: 'Extra Docker Tag for cloudogu/scm-manager image')
+ ])
])
timeout(activity: true, time: 30, unit: 'MINUTES') {
@@ -51,9 +54,9 @@ node('docker') {
if (isMainBranch()) {
-// stage('Lifecycle') {
-// nexusPolicyEvaluation iqApplication: selectedApplication('scm'), iqScanPatterns: [[scanPattern: 'scm-server/target/scm-server-app.zip']], iqStage: 'build'
-// }
+ stage('Lifecycle') {
+ nexusPolicyEvaluation iqApplication: selectedApplication('scm'), iqScanPatterns: [[scanPattern: 'scm-server/target/scm-server-app.zip']], iqStage: 'build'
+ }
stage('Archive') {
archiveArtifacts 'scm-webapp/target/scm-webapp.war'
@@ -66,6 +69,13 @@ node('docker') {
docker.withRegistry('', 'hub.docker.com-cesmarvin') {
image.push(dockerImageTag)
image.push('latest')
+ if (!'latest'.equals(params.dockerTag)) {
+ image.push(params.dockerTag)
+
+ def newDockerTag = "2.0.0-${commitHash.substring(0,7)}-dev-${params.dockerTag}"
+ currentBuild.description = newDockerTag
+ image.push(newDockerTag)
+ }
}
}
@@ -92,7 +102,7 @@ String mainBranch
Maven setupMavenBuild() {
// Keep this version number in sync with .mvn/maven-wrapper.properties
- Maven mvn = new MavenInDocker(this, "3.5.2-jdk-8")
+ Maven mvn = new MavenInDocker(this, '3.5.2-jdk-8')
if (isMainBranch()) {
// Release starts javadoc, which takes very long, so do only for certain branches
diff --git a/docs/dtd/plugin/2.0.0-01.dtd b/docs/dtd/plugin/2.0.0-01.dtd
index eec149f3e8..954a2c2219 100644
--- a/docs/dtd/plugin/2.0.0-01.dtd
+++ b/docs/dtd/plugin/2.0.0-01.dtd
@@ -29,46 +29,28 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
@@ -121,4 +103,4 @@
-
\ No newline at end of file
+
diff --git a/docs/logo/favicon_16x16px.ico b/docs/logo/favicon_16x16px.ico
new file mode 100644
index 0000000000..3436795fdf
Binary files /dev/null and b/docs/logo/favicon_16x16px.ico differ
diff --git a/docs/logo/favicon_16x16px_transparent.ico b/docs/logo/favicon_16x16px_transparent.ico
new file mode 100644
index 0000000000..e5803f340d
Binary files /dev/null and b/docs/logo/favicon_16x16px_transparent.ico differ
diff --git a/docs/logo/scm-manager_logo.ai b/docs/logo/scm-manager_logo.ai
new file mode 100644
index 0000000000..6fe98a15e0
--- /dev/null
+++ b/docs/logo/scm-manager_logo.ai
@@ -0,0 +1 @@
+%!PS-Adobe-2.0
%%Creator: Adobe Photoshop(TM) Pen Path Export 7.0
%%Title: (scm-manager_logo.ai)
%%DocumentNeededResources: procset Adobe_packedarray 2.0 0
%%+ procset Adobe_IllustratorA_AI3 1.0 1
%%ColorUsage: Black&White
%%BoundingBox: 0 0 800 275
%%HiResBoundingBox: 0 0 800 275
%AI3_Cropmarks: 0 0 800 275
%%DocumentPreview: None
%%EndComments
%%BeginProlog
%%IncludeResource: procset Adobe_packedarray 2.0 0
Adobe_packedarray /initialize get exec
%%IncludeResource: procset Adobe_IllustratorA_AI3 1.0 1
%%EndProlog
%%BeginSetup
Adobe_IllustratorA_AI3 /initialize get exec
n
%%EndSetup
0.0 0.0 0.0 1.0 k
0 i 0 J 0 j 1 w 4 M []0 d
%%Note:
%%Trailer
%%EOF
\ No newline at end of file
diff --git a/docs/logo/scm-manager_logo.jpg b/docs/logo/scm-manager_logo.jpg
new file mode 100644
index 0000000000..f518e3f2b2
Binary files /dev/null and b/docs/logo/scm-manager_logo.jpg differ
diff --git a/docs/logo/scm-manager_logo.png b/docs/logo/scm-manager_logo.png
new file mode 100644
index 0000000000..90a17c7ee4
Binary files /dev/null and b/docs/logo/scm-manager_logo.png differ
diff --git a/docs/logo/scm-manager_logo_img.jpg b/docs/logo/scm-manager_logo_img.jpg
new file mode 100644
index 0000000000..f2d3b35b66
Binary files /dev/null and b/docs/logo/scm-manager_logo_img.jpg differ
diff --git a/docs/logo/scm-manager_logo_img.png b/docs/logo/scm-manager_logo_img.png
new file mode 100644
index 0000000000..f349fc5d22
Binary files /dev/null and b/docs/logo/scm-manager_logo_img.png differ
diff --git a/docs/logo/scm-manager_logo_img_neg.jpg b/docs/logo/scm-manager_logo_img_neg.jpg
new file mode 100644
index 0000000000..1b56b5e627
Binary files /dev/null and b/docs/logo/scm-manager_logo_img_neg.jpg differ
diff --git a/docs/logo/scm-manager_logo_img_neg.png b/docs/logo/scm-manager_logo_img_neg.png
new file mode 100644
index 0000000000..796a02882c
Binary files /dev/null and b/docs/logo/scm-manager_logo_img_neg.png differ
diff --git a/docs/logo/scm-manager_logo_neg.jpg b/docs/logo/scm-manager_logo_neg.jpg
new file mode 100644
index 0000000000..0d6704d0e3
Binary files /dev/null and b/docs/logo/scm-manager_logo_neg.jpg differ
diff --git a/docs/logo/scm-manager_logo_neg.png b/docs/logo/scm-manager_logo_neg.png
new file mode 100644
index 0000000000..3eb75aa3ee
Binary files /dev/null and b/docs/logo/scm-manager_logo_neg.png differ
diff --git a/docs/logo/scm-manager_logo_neg1.jpg b/docs/logo/scm-manager_logo_neg1.jpg
new file mode 100644
index 0000000000..d776c6b6e6
Binary files /dev/null and b/docs/logo/scm-manager_logo_neg1.jpg differ
diff --git a/docs/logo/scm-manager_logo_neg1.png b/docs/logo/scm-manager_logo_neg1.png
new file mode 100644
index 0000000000..817785710b
Binary files /dev/null and b/docs/logo/scm-manager_logo_neg1.png differ
diff --git a/docs/logo/scm-manager_logo_pos1.jpg b/docs/logo/scm-manager_logo_pos1.jpg
new file mode 100644
index 0000000000..fd2533c198
Binary files /dev/null and b/docs/logo/scm-manager_logo_pos1.jpg differ
diff --git a/docs/logo/scm-manager_logo_pos1.png b/docs/logo/scm-manager_logo_pos1.png
new file mode 100644
index 0000000000..b911417358
Binary files /dev/null and b/docs/logo/scm-manager_logo_pos1.png differ
diff --git a/pom.xml b/pom.xml
index ba06282720..3ab3cb82a3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -437,8 +437,15 @@
sonia.scm.mavensmp-maven-plugin
- 1.0.0-alpha-4
+ 1.0.0-alpha-6
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+ 2.8.2
+
+
@@ -633,7 +640,6 @@
org.apache.maven.pluginsmaven-deploy-plugin
- 2.7
diff --git a/scm-core/src/main/java/sonia/scm/IllegalIdentifierChangeException.java b/scm-core/src/main/java/sonia/scm/IllegalIdentifierChangeException.java
new file mode 100644
index 0000000000..63b9d0d4fc
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/IllegalIdentifierChangeException.java
@@ -0,0 +1,21 @@
+package sonia.scm;
+
+import java.util.Collections;
+
+public class IllegalIdentifierChangeException extends BadRequestException {
+
+ private static final String CODE = "thbsUFokjk";
+
+ public IllegalIdentifierChangeException(ContextEntry.ContextBuilder context, String message) {
+ super(context.build(), message);
+ }
+
+ public IllegalIdentifierChangeException(String message) {
+ super(Collections.emptyList(), message);
+ }
+
+ @Override
+ public String getCode() {
+ return CODE;
+ }
+}
diff --git a/scm-core/src/main/java/sonia/scm/api/v2/resources/HalAppender.java b/scm-core/src/main/java/sonia/scm/api/v2/resources/HalAppender.java
index 6afb542646..b313f68af8 100644
--- a/scm-core/src/main/java/sonia/scm/api/v2/resources/HalAppender.java
+++ b/scm-core/src/main/java/sonia/scm/api/v2/resources/HalAppender.java
@@ -2,6 +2,8 @@ package sonia.scm.api.v2.resources;
import de.otto.edison.hal.HalRepresentation;
+import java.util.List;
+
/**
* The {@link HalAppender} can be used within an {@link HalEnricher} to append hateoas links to a json response.
*
@@ -34,6 +36,14 @@ public interface HalAppender {
*/
void appendEmbedded(String rel, HalRepresentation embeddedItem);
+ /**
+ * Appends a list of embedded objects to the json response.
+ *
+ * @param rel name of relation
+ * @param embeddedItems embedded objects
+ */
+ void appendEmbedded(String rel, List embeddedItems);
+
/**
* Builder for link arrays.
*/
diff --git a/scm-core/src/main/java/sonia/scm/config/ScmConfiguration.java b/scm-core/src/main/java/sonia/scm/config/ScmConfiguration.java
index 8d3db8b348..4afbb6a895 100644
--- a/scm-core/src/main/java/sonia/scm/config/ScmConfiguration.java
+++ b/scm-core/src/main/java/sonia/scm/config/ScmConfiguration.java
@@ -73,7 +73,12 @@ public class ScmConfiguration implements Configuration {
* Default plugin url
*/
public static final String DEFAULT_PLUGINURL =
- "http://plugins.scm-manager.org/scm-plugin-backend/api/{version}/plugins?os={os}&arch={arch}&snapshot=false";
+ "http://download.scm-manager.org/api/v2/plugins.json?os={os}&arch={arch}&snapshot=false&version={version}";
+
+ /**
+ * Default url for login information (plugin and feature tips on the login page).
+ */
+ public static final String DEFAULT_LOGIN_INFO_URL = "https://login-info.scm-manager.org/api/v1/login-info";
/**
* Default plugin url from version 1.0
@@ -156,7 +161,6 @@ public class ScmConfiguration implements Configuration {
* 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
@@ -177,6 +181,9 @@ public class ScmConfiguration implements Configuration {
@XmlElement(name = "namespace-strategy")
private String namespaceStrategy = "UsernameNamespaceStrategy";
+ @XmlElement(name = "login-info-url")
+ private String loginInfoUrl = DEFAULT_LOGIN_INFO_URL;
+
/**
* Calls the {@link sonia.scm.ConfigChangedListener#configChanged(Object)}
@@ -210,12 +217,12 @@ public class ScmConfiguration implements Configuration {
this.forceBaseUrl = other.forceBaseUrl;
this.baseUrl = other.baseUrl;
this.disableGroupingGrid = other.disableGroupingGrid;
- this.enableRepositoryArchive = other.enableRepositoryArchive;
this.skipFailedAuthenticators = other.skipFailedAuthenticators;
this.loginAttemptLimit = other.loginAttemptLimit;
this.loginAttemptLimitTimeout = other.loginAttemptLimitTimeout;
this.enabledXsrfProtection = other.enabledXsrfProtection;
this.namespaceStrategy = other.namespaceStrategy;
+ this.loginInfoUrl = other.loginInfoUrl;
}
/**
@@ -334,10 +341,6 @@ public class ScmConfiguration implements Configuration {
return enableProxy;
}
- public boolean isEnableRepositoryArchive() {
- return enableRepositoryArchive;
- }
-
public boolean isForceBaseUrl() {
return forceBaseUrl;
}
@@ -350,6 +353,9 @@ public class ScmConfiguration implements Configuration {
return namespaceStrategy;
}
+ public String getLoginInfoUrl() {
+ return loginInfoUrl;
+ }
/**
* Returns true if failed authenticators are skipped.
@@ -381,16 +387,6 @@ public class ScmConfiguration implements Configuration {
this.enableProxy = enableProxy;
}
- /**
- * Enable or disable the repository archive. Default is disabled.
- *
- * @param enableRepositoryArchive true to disable the repository archive
- * @since 1.14
- */
- public void setEnableRepositoryArchive(boolean enableRepositoryArchive) {
- this.enableRepositoryArchive = enableRepositoryArchive;
- }
-
public void setForceBaseUrl(boolean forceBaseUrl) {
this.forceBaseUrl = forceBaseUrl;
}
@@ -477,6 +473,10 @@ public class ScmConfiguration implements Configuration {
this.namespaceStrategy = namespaceStrategy;
}
+ public void setLoginInfoUrl(String loginInfoUrl) {
+ this.loginInfoUrl = loginInfoUrl;
+ }
+
@Override
// Only for permission checks, don't serialize to XML
@XmlTransient
diff --git a/scm-core/src/main/java/sonia/scm/group/ExternalGroupNames.java b/scm-core/src/main/java/sonia/scm/group/ExternalGroupNames.java
deleted file mode 100644
index 179e488236..0000000000
--- a/scm-core/src/main/java/sonia/scm/group/ExternalGroupNames.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package sonia.scm.group;
-
-import java.util.Collection;
-
-/**
- * This class represents all associated groups which are provided by external systems for a certain user.
- *
- * @author Sebastian Sdorra
- * @since 2.0.0
- */
-public class ExternalGroupNames extends GroupNames {
- public ExternalGroupNames() {
- }
-
- public ExternalGroupNames(String groupName, String... groupNames) {
- super(groupName, groupNames);
- }
-
- public ExternalGroupNames(Collection collection) {
- super(collection);
- }
-}
diff --git a/scm-core/src/main/java/sonia/scm/group/GroupCollector.java b/scm-core/src/main/java/sonia/scm/group/GroupCollector.java
new file mode 100644
index 0000000000..4546db1bc4
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/group/GroupCollector.java
@@ -0,0 +1,10 @@
+package sonia.scm.group;
+
+import java.util.Set;
+
+public interface GroupCollector {
+
+ String AUTHENTICATED = "_authenticated";
+
+ Set collect(String principal);
+}
diff --git a/scm-core/src/main/java/sonia/scm/group/GroupNames.java b/scm-core/src/main/java/sonia/scm/group/GroupNames.java
deleted file mode 100644
index c28f9f5ef1..0000000000
--- a/scm-core/src/main/java/sonia/scm/group/GroupNames.java
+++ /dev/null
@@ -1,187 +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.group;
-
-//~--- non-JDK imports --------------------------------------------------------
-
-import com.google.common.base.Joiner;
-import com.google.common.base.Objects;
-import com.google.common.collect.Lists;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-
-//~--- JDK imports ------------------------------------------------------------
-
-/**
- * This class represents all associated groups for a user.
- *
- * @author Sebastian Sdorra
- * @since 1.21
- */
-public class GroupNames implements Serializable, Iterable
-{
-
- /**
- * Group for all authenticated users
- * @since 1.31
- */
- public static final String AUTHENTICATED = "_authenticated";
-
- /** Field description */
- private static final long serialVersionUID = 8615685985213897947L;
-
- //~--- constructors ---------------------------------------------------------
-
- /**
- * Constructs ...
- *
- */
- public GroupNames()
- {
- this(Collections.emptyList());
- }
-
- /**
- * Constructs ...
- *
- *
- * @param groupName
- * @param groupNames
- */
- public GroupNames(String groupName, String... groupNames)
- {
- this(Lists.asList(groupName, groupNames));
- }
-
- /**
- * Constructs ...
- *
- *
- * @param collection
- */
- public GroupNames(Collection collection)
- {
- this.collection = Collections.unmodifiableCollection(collection);
- }
-
- //~--- methods --------------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @param groupName
- *
- * @return
- */
- public boolean contains(String groupName)
- {
- return collection.contains(groupName);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean equals(Object obj)
- {
- if (obj == null)
- {
- return false;
- }
-
- if (getClass() != obj.getClass())
- {
- return false;
- }
-
- final GroupNames other = (GroupNames) obj;
-
- return Objects.equal(collection, other.collection);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int hashCode()
- {
- return Objects.hashCode(collection);
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- @Override
- public Iterator iterator()
- {
- return collection.iterator();
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- @Override
- public String toString()
- {
- return Joiner.on(", ").join(collection);
- }
-
- //~--- get methods ----------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @return
- */
- public Collection getCollection()
- {
- return collection;
- }
-
-
- //~--- fields ---------------------------------------------------------------
- /** Field description */
- private final Collection collection;
-}
diff --git a/scm-core/src/main/java/sonia/scm/group/GroupResolver.java b/scm-core/src/main/java/sonia/scm/group/GroupResolver.java
new file mode 100644
index 0000000000..5aba63c93b
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/group/GroupResolver.java
@@ -0,0 +1,10 @@
+package sonia.scm.group;
+
+import sonia.scm.plugin.ExtensionPoint;
+
+import java.util.Set;
+
+@ExtensionPoint
+public interface GroupResolver {
+ Set resolve(String principal);
+}
diff --git a/scm-core/src/main/java/sonia/scm/plugin/AvailablePlugin.java b/scm-core/src/main/java/sonia/scm/plugin/AvailablePlugin.java
new file mode 100644
index 0000000000..db8d96ca15
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/plugin/AvailablePlugin.java
@@ -0,0 +1,32 @@
+package sonia.scm.plugin;
+
+import com.google.common.base.Preconditions;
+
+public class AvailablePlugin implements Plugin {
+
+ private final AvailablePluginDescriptor pluginDescriptor;
+ private final boolean pending;
+
+ public AvailablePlugin(AvailablePluginDescriptor pluginDescriptor) {
+ this(pluginDescriptor, false);
+ }
+
+ private AvailablePlugin(AvailablePluginDescriptor pluginDescriptor, boolean pending) {
+ this.pluginDescriptor = pluginDescriptor;
+ this.pending = pending;
+ }
+
+ @Override
+ public AvailablePluginDescriptor getDescriptor() {
+ return pluginDescriptor;
+ }
+
+ public boolean isPending() {
+ return pending;
+ }
+
+ public AvailablePlugin install() {
+ Preconditions.checkState(!pending, "installation is already pending");
+ return new AvailablePlugin(pluginDescriptor, true);
+ }
+}
diff --git a/scm-core/src/main/java/sonia/scm/plugin/AvailablePluginDescriptor.java b/scm-core/src/main/java/sonia/scm/plugin/AvailablePluginDescriptor.java
new file mode 100644
index 0000000000..1c164a0d81
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/plugin/AvailablePluginDescriptor.java
@@ -0,0 +1,47 @@
+package sonia.scm.plugin;
+
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * @since 2.0.0
+ */
+public class AvailablePluginDescriptor implements PluginDescriptor {
+
+ private final PluginInformation information;
+ private final PluginCondition condition;
+ private final Set dependencies;
+ private final String url;
+ private final String checksum;
+
+ public AvailablePluginDescriptor(PluginInformation information, PluginCondition condition, Set dependencies, String url, String checksum) {
+ this.information = information;
+ this.condition = condition;
+ this.dependencies = dependencies;
+ this.url = url;
+ this.checksum = checksum;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public Optional getChecksum() {
+ return Optional.ofNullable(checksum);
+ }
+
+ @Override
+ public PluginInformation getInformation() {
+ return information;
+ }
+
+ @Override
+ public PluginCondition getCondition() {
+ return condition;
+ }
+
+ @Override
+ public Set getDependencies() {
+ return dependencies;
+ }
+}
diff --git a/scm-core/src/main/java/sonia/scm/plugin/PluginWrapper.java b/scm-core/src/main/java/sonia/scm/plugin/InstalledPlugin.java
similarity index 83%
rename from scm-core/src/main/java/sonia/scm/plugin/PluginWrapper.java
rename to scm-core/src/main/java/sonia/scm/plugin/InstalledPlugin.java
index 46c3a4a980..2021d4d00f 100644
--- a/scm-core/src/main/java/sonia/scm/plugin/PluginWrapper.java
+++ b/scm-core/src/main/java/sonia/scm/plugin/InstalledPlugin.java
@@ -36,27 +36,27 @@ package sonia.scm.plugin;
import java.nio.file.Path;
/**
- * Wrapper for a {@link Plugin}. The wrapper holds the directory,
+ * Wrapper for a {@link InstalledPluginDescriptor}. The wrapper holds the directory,
* {@link ClassLoader} and {@link WebResourceLoader} of a plugin.
*
* @author Sebastian Sdorra
* @since 2.0.0
*/
-public final class PluginWrapper
+public final class InstalledPlugin implements Plugin
{
/**
* Constructs a new plugin wrapper.
*
- * @param plugin wrapped plugin
+ * @param descriptor wrapped plugin
* @param classLoader plugin class loader
* @param webResourceLoader web resource loader
* @param directory plugin directory
*/
- public PluginWrapper(Plugin plugin, ClassLoader classLoader,
- WebResourceLoader webResourceLoader, Path directory)
+ public InstalledPlugin(InstalledPluginDescriptor descriptor, ClassLoader classLoader,
+ WebResourceLoader webResourceLoader, Path directory)
{
- this.plugin = plugin;
+ this.descriptor = descriptor;
this.classLoader = classLoader;
this.webResourceLoader = webResourceLoader;
this.directory = directory;
@@ -94,18 +94,19 @@ public final class PluginWrapper
*/
public String getId()
{
- return plugin.getInformation().getId();
+ return descriptor.getInformation().getId();
}
/**
- * Returns the plugin.
+ * Returns the plugin descriptor.
*
*
- * @return plugin
+ * @return plugin descriptor
*/
- public Plugin getPlugin()
+ @Override
+ public InstalledPluginDescriptor getDescriptor()
{
- return plugin;
+ return descriptor;
}
/**
@@ -128,7 +129,7 @@ public final class PluginWrapper
private final Path directory;
/** plugin */
- private final Plugin plugin;
+ private final InstalledPluginDescriptor descriptor;
/** plugin web resource loader */
private final WebResourceLoader webResourceLoader;
diff --git a/scm-core/src/main/java/sonia/scm/plugin/InstalledPluginDescriptor.java b/scm-core/src/main/java/sonia/scm/plugin/InstalledPluginDescriptor.java
new file mode 100644
index 0000000000..88ae4c5dff
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/plugin/InstalledPluginDescriptor.java
@@ -0,0 +1,259 @@
+/**
+ * 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.plugin;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableSet;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.Set;
+
+//~--- JDK imports ------------------------------------------------------------
+
+/**
+ *
+ * @author Sebastian Sdorra
+ */
+@XmlRootElement(name = "plugin")
+@XmlAccessorType(XmlAccessType.FIELD)
+public final class InstalledPluginDescriptor extends ScmModule implements PluginDescriptor
+{
+
+ /**
+ * Constructs ...
+ *
+ */
+ InstalledPluginDescriptor() {}
+
+ /**
+ * Constructs ...
+ *
+ *
+ * @param scmVersion
+ * @param information
+ * @param resources
+ * @param condition
+ * @param childFirstClassLoader
+ * @param dependencies
+ */
+ public InstalledPluginDescriptor(int scmVersion, PluginInformation information,
+ PluginResources resources, PluginCondition condition,
+ boolean childFirstClassLoader, Set dependencies)
+ {
+ this.scmVersion = scmVersion;
+ this.information = information;
+ this.resources = resources;
+ this.condition = condition;
+ this.childFirstClassLoader = childFirstClassLoader;
+ this.dependencies = dependencies;
+ }
+
+ //~--- methods --------------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ * @param obj
+ *
+ * @return
+ */
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+
+ if (getClass() != obj.getClass())
+ {
+ return false;
+ }
+
+ final InstalledPluginDescriptor other = (InstalledPluginDescriptor) obj;
+
+ return Objects.equal(scmVersion, other.scmVersion)
+ && Objects.equal(condition, other.condition)
+ && Objects.equal(information, other.information)
+ && Objects.equal(resources, other.resources)
+ && Objects.equal(childFirstClassLoader, other.childFirstClassLoader)
+ && Objects.equal(dependencies, other.dependencies);
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public int hashCode()
+ {
+ return Objects.hashCode(scmVersion, condition, information, resources,
+ childFirstClassLoader, dependencies);
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public String toString()
+ {
+ //J-
+ return MoreObjects.toStringHelper(this)
+ .add("scmVersion", scmVersion)
+ .add("condition", condition)
+ .add("information", information)
+ .add("resources", resources)
+ .add("childFirstClassLoader", childFirstClassLoader)
+ .add("dependencies", dependencies)
+ .toString();
+ //J+
+ }
+
+ //~--- get methods ----------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public PluginCondition getCondition()
+ {
+ return condition;
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ *
+ * @since 2.0.0
+ */
+ @Override
+ public Set getDependencies()
+ {
+ if (dependencies == null)
+ {
+ dependencies = ImmutableSet.of();
+ }
+
+ return dependencies;
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public PluginInformation getInformation()
+ {
+ return information;
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ public PluginResources getResources()
+ {
+ return resources;
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ public int getScmVersion()
+ {
+ return scmVersion;
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ public boolean isChildFirstClassLoader()
+ {
+ return childFirstClassLoader;
+ }
+
+ //~--- fields ---------------------------------------------------------------
+
+ /** Field description */
+ @XmlElement(name = "child-first-classloader")
+ private boolean childFirstClassLoader;
+
+ /** Field description */
+ @XmlElement(name = "conditions")
+ private PluginCondition condition;
+
+ /** Field description */
+ @XmlElement(name = "dependency")
+ @XmlElementWrapper(name = "dependencies")
+ private Set dependencies;
+
+ /** Field description */
+ @XmlElement(name = "information")
+ private PluginInformation information;
+
+ /** Field description */
+ private PluginResources resources;
+
+ /** Field description */
+ @XmlElement(name = "scm-version")
+ private int scmVersion = 1;
+}
diff --git a/scm-core/src/main/java/sonia/scm/plugin/Plugin.java b/scm-core/src/main/java/sonia/scm/plugin/Plugin.java
index e8fd166e78..8b440f8ab9 100644
--- a/scm-core/src/main/java/sonia/scm/plugin/Plugin.java
+++ b/scm-core/src/main/java/sonia/scm/plugin/Plugin.java
@@ -1,255 +1,6 @@
-/**
- * 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.plugin;
-//~--- non-JDK imports --------------------------------------------------------
+public interface Plugin {
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableSet;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import javax.xml.bind.annotation.XmlRootElement;
-import java.util.Set;
-
-//~--- JDK imports ------------------------------------------------------------
-
-/**
- *
- * @author Sebastian Sdorra
- */
-@XmlRootElement
-@XmlAccessorType(XmlAccessType.FIELD)
-public final class Plugin extends ScmModule
-{
-
- /**
- * Constructs ...
- *
- */
- Plugin() {}
-
- /**
- * Constructs ...
- *
- *
- * @param scmVersion
- * @param information
- * @param resources
- * @param condition
- * @param childFirstClassLoader
- * @param dependencies
- */
- public Plugin(int scmVersion, PluginInformation information,
- PluginResources resources, PluginCondition condition,
- boolean childFirstClassLoader, Set dependencies)
- {
- this.scmVersion = scmVersion;
- this.information = information;
- this.resources = resources;
- this.condition = condition;
- this.childFirstClassLoader = childFirstClassLoader;
- this.dependencies = dependencies;
- }
-
- //~--- methods --------------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @param obj
- *
- * @return
- */
- @Override
- public boolean equals(Object obj)
- {
- if (obj == null)
- {
- return false;
- }
-
- if (getClass() != obj.getClass())
- {
- return false;
- }
-
- final Plugin other = (Plugin) obj;
-
- return Objects.equal(scmVersion, other.scmVersion)
- && Objects.equal(condition, other.condition)
- && Objects.equal(information, other.information)
- && Objects.equal(resources, other.resources)
- && Objects.equal(childFirstClassLoader, other.childFirstClassLoader)
- && Objects.equal(dependencies, other.dependencies);
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- @Override
- public int hashCode()
- {
- return Objects.hashCode(scmVersion, condition, information, resources,
- childFirstClassLoader, dependencies);
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- @Override
- public String toString()
- {
- //J-
- return MoreObjects.toStringHelper(this)
- .add("scmVersion", scmVersion)
- .add("condition", condition)
- .add("information", information)
- .add("resources", resources)
- .add("childFirstClassLoader", childFirstClassLoader)
- .add("dependencies", dependencies)
- .toString();
- //J+
- }
-
- //~--- get methods ----------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @return
- */
- public PluginCondition getCondition()
- {
- return condition;
- }
-
- /**
- * Method description
- *
- *
- * @return
- *
- * @since 2.0.0
- */
- public Set getDependencies()
- {
- if (dependencies == null)
- {
- dependencies = ImmutableSet.of();
- }
-
- return dependencies;
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- public PluginInformation getInformation()
- {
- return information;
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- public PluginResources getResources()
- {
- return resources;
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- public int getScmVersion()
- {
- return scmVersion;
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- public boolean isChildFirstClassLoader()
- {
- return childFirstClassLoader;
- }
-
- //~--- fields ---------------------------------------------------------------
-
- /** Field description */
- @XmlElement(name = "child-first-classloader")
- private boolean childFirstClassLoader;
-
- /** Field description */
- @XmlElement(name = "conditions")
- private PluginCondition condition;
-
- /** Field description */
- @XmlElement(name = "dependency")
- @XmlElementWrapper(name = "dependencies")
- private Set dependencies;
-
- /** Field description */
- private PluginInformation information;
-
- /** Field description */
- private PluginResources resources;
-
- /** Field description */
- @XmlElement(name = "scm-version")
- private int scmVersion = 1;
+ PluginDescriptor getDescriptor();
}
diff --git a/scm-core/src/main/java/sonia/scm/plugin/PluginCenter.java b/scm-core/src/main/java/sonia/scm/plugin/PluginCenter.java
deleted file mode 100644
index e1598e0490..0000000000
--- a/scm-core/src/main/java/sonia/scm/plugin/PluginCenter.java
+++ /dev/null
@@ -1,120 +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.plugin;
-
-//~--- JDK imports ------------------------------------------------------------
-
-import java.io.Serializable;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import javax.xml.bind.annotation.XmlRootElement;
-
-/**
- *
- * @author Sebastian Sdorra
- */
-@XmlRootElement(name = "plugin-center")
-@XmlAccessorType(XmlAccessType.FIELD)
-public class PluginCenter implements Serializable
-{
-
- /** Field description */
- private static final long serialVersionUID = -6414175308610267397L;
-
- //~--- get methods ----------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @return
- */
- public Set getPlugins()
- {
- return plugins;
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- public Set getRepositories()
- {
- return repositories;
- }
-
- //~--- set methods ----------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @param plugins
- */
- public void setPlugins(Set plugins)
- {
- this.plugins = plugins;
- }
-
- /**
- * Method description
- *
- *
- * @param repositories
- */
- public void setRepositories(Set repositories)
- {
- this.repositories = repositories;
- }
-
- //~--- fields ---------------------------------------------------------------
-
- /** Field description */
- @XmlElement(name = "plugin")
- @XmlElementWrapper(name = "plugins")
- private Set plugins = new HashSet();
-
- /** Field description */
- @XmlElement(name = "repository")
- @XmlElementWrapper(name = "repositories")
- private Set repositories = new HashSet();
-}
diff --git a/scm-core/src/main/java/sonia/scm/plugin/PluginDescriptor.java b/scm-core/src/main/java/sonia/scm/plugin/PluginDescriptor.java
new file mode 100644
index 0000000000..6e800faff0
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/plugin/PluginDescriptor.java
@@ -0,0 +1,13 @@
+package sonia.scm.plugin;
+
+import java.util.Set;
+
+public interface PluginDescriptor {
+
+ PluginInformation getInformation();
+
+ PluginCondition getCondition();
+
+ Set getDependencies();
+
+}
diff --git a/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java b/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java
index 6de52c3cca..b669cb63fa 100644
--- a/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java
+++ b/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java
@@ -1,19 +1,19 @@
/**
* 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.
+ * 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.
+ * 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.
- *
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -24,558 +24,82 @@
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
+ *
* http://bitbucket.org/sdorra/scm-manager
- *
*/
-
package sonia.scm.plugin;
//~--- non-JDK imports --------------------------------------------------------
import com.github.sdorra.ssp.PermissionObject;
import com.github.sdorra.ssp.StaticPermissions;
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Objects;
+import lombok.Data;
import sonia.scm.Validateable;
import sonia.scm.util.Util;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
//~--- JDK imports ------------------------------------------------------------
/**
- *
* @author Sebastian Sdorra
*/
+@Data
@StaticPermissions(
- value = "plugin",
- generatedClass = "PluginPermissions",
+ value = "plugin",
+ generatedClass = "PluginPermissions",
permissions = {},
- globalPermissions = { "read", "manage" },
+ globalPermissions = {"read", "manage"},
custom = true, customGlobal = true
)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "plugin-information")
-public class PluginInformation
- implements PermissionObject, Validateable, Cloneable, Serializable
-{
+public class PluginInformation implements PermissionObject, Validateable, Cloneable, Serializable {
- /** Field description */
private static final long serialVersionUID = 461382048865977206L;
- //~--- methods --------------------------------------------------------------
+ private String name;
+ private String version;
+ private String displayName;
+ private String description;
+ private String author;
+ private String category;
+ private String avatarUrl;
- /**
- * Method description
- *
- *
- * @return
- *
- * @since 1.11
- */
@Override
- public PluginInformation clone()
- {
+ public PluginInformation clone() {
PluginInformation clone = new PluginInformation();
-
- clone.setArtifactId(artifactId);
+ clone.setName(name);
+ clone.setVersion(version);
+ clone.setDisplayName(displayName);
+ clone.setDescription(description);
clone.setAuthor(author);
clone.setCategory(category);
- clone.setTags(tags);
-
- if (condition != null)
- {
- clone.setCondition(condition.clone());
- }
-
- clone.setDescription(description);
- clone.setGroupId(groupId);
- clone.setName(name);
-
- if (Util.isNotEmpty(screenshots))
- {
- clone.setScreenshots(new ArrayList(screenshots));
- }
-
- clone.setState(state);
- clone.setUrl(url);
- clone.setVersion(version);
- clone.setWiki(wiki);
-
+ clone.setAvatarUrl(avatarUrl);
return clone;
}
- /**
- * Method description
- *
- *
- * @param obj
- *
- * @return
- */
@Override
- public boolean equals(Object obj)
- {
- if (obj == null)
- {
- return false;
- }
-
- if (getClass() != obj.getClass())
- {
- return false;
- }
-
- final PluginInformation other = (PluginInformation) obj;
-
- //J-
- return Objects.equal(artifactId, other.artifactId)
- && Objects.equal(author, other.author)
- && Objects.equal(category, other.category)
- && Objects.equal(tags, other.tags)
- && Objects.equal(condition, other.condition)
- && Objects.equal(description, other.description)
- && Objects.equal(groupId, other.groupId)
- && Objects.equal(name, other.name)
- && Objects.equal(screenshots, other.screenshots)
- && Objects.equal(state, other.state)
- && Objects.equal(url, other.url)
- && Objects.equal(version, other.version)
- && Objects.equal(wiki, other.wiki);
- //J+
+ public String getId() {
+ return getName(true);
}
- /**
- * Method description
- *
- *
- * @return
- */
- @Override
- public int hashCode()
- {
- return Objects.hashCode(artifactId, author, category, tags, condition,
- description, groupId, name, screenshots, state, url, version, wiki);
- }
+ public String getName(boolean withVersion) {
+ StringBuilder id = new StringBuilder(name);
- /**
- * Method description
- *
- *
- * @return
- */
- @Override
- public String toString()
- {
- //J-
- return MoreObjects.toStringHelper(this)
- .add("artifactId", artifactId)
- .add("author", author)
- .add("category", category)
- .add("tags", tags)
- .add("condition", condition)
- .add("description", description)
- .add("groupId", groupId)
- .add("name", name)
- .add("screenshots", screenshots)
- .add("state", state)
- .add("url", url)
- .add("version", version)
- .add("wiki", wiki)
- .toString();
- //J+
- }
-
- //~--- get methods ----------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @return
- */
- public String getArtifactId()
- {
- return artifactId;
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- public String getAuthor()
- {
- return author;
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- public String getCategory()
- {
- return category;
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- public PluginCondition getCondition()
- {
- return condition;
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- public String getDescription()
- {
- return description;
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- public String getGroupId()
- {
- return groupId;
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- @Override
- public String getId()
- {
- return getId(true);
- }
-
- /**
- * Method description
- *
- *
- * @param withVersion
- *
- * @return
- * @since 1.21
- */
- public String getId(boolean withVersion)
- {
- StringBuilder id = new StringBuilder(groupId);
-
- id.append(":").append(artifactId);
-
- if (withVersion)
- {
+ if (withVersion) {
id.append(":").append(version);
}
-
return id.toString();
}
- /**
- * Method description
- *
- *
- * @return
- */
- public String getName()
- {
- return name;
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- public List getScreenshots()
- {
- return screenshots;
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- public PluginState getState()
- {
- return state;
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- public List getTags()
- {
- return tags;
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- public String getUrl()
- {
- return url;
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- public String getVersion()
- {
- return version;
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- public String getWiki()
- {
- return wiki;
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
@Override
- public boolean isValid()
- {
- return Util.isNotEmpty(groupId) && Util.isNotEmpty(artifactId)
- && Util.isNotEmpty(name) && Util.isNotEmpty(version);
+ public boolean isValid() {
+ return Util.isNotEmpty(name) && Util.isNotEmpty(version);
}
-
- //~--- set methods ----------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @param artifactId
- */
- public void setArtifactId(String artifactId)
- {
- this.artifactId = artifactId;
- }
-
- /**
- * Method description
- *
- *
- * @param author
- */
- public void setAuthor(String author)
- {
- this.author = author;
- }
-
- /**
- * Method description
- *
- *
- * @param category
- */
- public void setCategory(String category)
- {
- this.category = category;
- }
-
- /**
- * Method description
- *
- *
- * @param condition
- */
- public void setCondition(PluginCondition condition)
- {
- this.condition = condition;
- }
-
- /**
- * Method description
- *
- *
- * @param description
- */
- public void setDescription(String description)
- {
- this.description = description;
- }
-
- /**
- * Method description
- *
- *
- * @param groupId
- */
- public void setGroupId(String groupId)
- {
- this.groupId = groupId;
- }
-
- /**
- * Method description
- *
- *
- * @param name
- */
- public void setName(String name)
- {
- this.name = name;
- }
-
- /**
- * Method description
- *
- *
- * @param screenshots
- */
- public void setScreenshots(List screenshots)
- {
- this.screenshots = screenshots;
- }
-
- /**
- * Method description
- *
- *
- * @param state
- */
- public void setState(PluginState state)
- {
- this.state = state;
- }
-
- /**
- * Method description
- *
- *
- * @param tags
- */
- public void setTags(List tags)
- {
- this.tags = tags;
- }
-
- /**
- * Method description
- *
- *
- * @param url
- */
- public void setUrl(String url)
- {
- this.url = url;
- }
-
- /**
- * Method description
- *
- *
- * @param version
- */
- public void setVersion(String version)
- {
- this.version = version;
- }
-
- /**
- * Method description
- *
- *
- * @param wiki
- */
- public void setWiki(String wiki)
- {
- this.wiki = wiki;
- }
-
- //~--- fields ---------------------------------------------------------------
-
- /** Field description */
- private String artifactId;
-
- /** Field description */
- private String author;
-
- /** Field description */
- private String category;
-
- /** Field description */
- private PluginCondition condition;
-
- /** Field description */
- private String description;
-
- /** Field description */
- private String groupId;
-
- /** Field description */
- private String name;
-
- /** Field description */
- @XmlElement(name = "screenshot")
- @XmlElementWrapper(name = "screenshots")
- private List screenshots;
-
- /** Field description */
- private PluginState state;
-
- /** Field description */
- @XmlElement(name = "tag")
- @XmlElementWrapper(name = "tags")
- private List tags;
-
- /** Field description */
- private String url;
-
- /** Field description */
- private String version;
-
- /** Field description */
- private String wiki;
}
diff --git a/scm-core/src/main/java/sonia/scm/plugin/PluginInformationComparator.java b/scm-core/src/main/java/sonia/scm/plugin/PluginInformationComparator.java
deleted file mode 100644
index f44de35e8a..0000000000
--- a/scm-core/src/main/java/sonia/scm/plugin/PluginInformationComparator.java
+++ /dev/null
@@ -1,106 +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.plugin;
-
-//~--- non-JDK imports --------------------------------------------------------
-
-import sonia.scm.util.Util;
-
-//~--- JDK imports ------------------------------------------------------------
-
-import java.io.Serializable;
-
-import java.util.Comparator;
-
-/**
- *
- * @author Sebastian Sdorra
- * @since 1.6
- */
-public class PluginInformationComparator
- implements Comparator, Serializable
-{
-
- /** Field description */
- public static final PluginInformationComparator INSTANCE =
- new PluginInformationComparator();
-
- /** Field description */
- private static final long serialVersionUID = -8339752498853225668L;
-
- //~--- methods --------------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @param plugin
- * @param other
- *
- * @return
- */
- @Override
- public int compare(PluginInformation plugin, PluginInformation other)
- {
- int result = 0;
-
- result = Util.compare(plugin.getGroupId(), other.getGroupId());
-
- if (result == 0)
- {
- result = Util.compare(plugin.getArtifactId(), other.getArtifactId());
-
- if (result == 0)
- {
- PluginState state = plugin.getState();
- PluginState otherState = other.getState();
-
- if ((state != null) && (otherState != null))
- {
- result = state.getCompareValue() - otherState.getCompareValue();
- }
- else if ((state == null) && (otherState != null))
- {
- result = 1;
- }
- else if ((state != null) && (otherState == null))
- {
- result = -1;
- }
- }
- }
-
- return result;
- }
-}
diff --git a/scm-core/src/main/java/sonia/scm/plugin/PluginLoader.java b/scm-core/src/main/java/sonia/scm/plugin/PluginLoader.java
index 2d65d1cc98..e82d945024 100644
--- a/scm-core/src/main/java/sonia/scm/plugin/PluginLoader.java
+++ b/scm-core/src/main/java/sonia/scm/plugin/PluginLoader.java
@@ -68,7 +68,7 @@ public interface PluginLoader
*
* @return
*/
- public Collection getInstalledPlugins();
+ public Collection getInstalledPlugins();
/**
* Returns a {@link ClassLoader} which is able to load classes and resources
diff --git a/scm-core/src/main/java/sonia/scm/plugin/PluginManager.java b/scm-core/src/main/java/sonia/scm/plugin/PluginManager.java
index b1ec502fc4..b7b8f69519 100644
--- a/scm-core/src/main/java/sonia/scm/plugin/PluginManager.java
+++ b/scm-core/src/main/java/sonia/scm/plugin/PluginManager.java
@@ -33,113 +33,56 @@
package sonia.scm.plugin;
-//~--- JDK imports ------------------------------------------------------------
-
-import com.google.common.base.Predicate;
-import java.io.IOException;
-import java.io.InputStream;
-
-import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
/**
+ * The plugin manager is responsible for plugin related tasks, such as install, uninstall or updating.
*
* @author Sebastian Sdorra
*/
-public interface PluginManager
-{
+public interface PluginManager {
/**
- * Method description
- *
+ * Returns the available plugin with the given name.
+ * @param name of plugin
+ * @return optional available plugin.
*/
- public void clearCache();
+ Optional getAvailable(String name);
/**
- * Method description
- *
- *
- * @param id
+ * Returns the installed plugin with the given name.
+ * @param name of plugin
+ * @return optional installed plugin.
*/
- public void install(String id);
+ Optional getInstalled(String name);
+
/**
- * Installs a plugin package from a inputstream.
+ * Returns all installed plugins.
*
- *
- * @param packageStream package input stream
- *
- * @throws IOException
- * @since 1.21
+ * @return a list of installed plugins.
*/
- public void installPackage(InputStream packageStream) throws IOException;
+ List getInstalled();
/**
- * Method description
+ * Returns all available plugins. The list contains the plugins which are loaded from the plugin center, but without
+ * the installed plugins.
*
- *
- * @param id
+ * @return a list of available plugins.
*/
- public void uninstall(String id);
+ List getAvailable();
/**
- * Method description
+ * Installs the plugin with the given name from the list of available plugins.
*
- *
- * @param id
+ * @param name plugin name
+ * @param restartAfterInstallation restart context after plugin installation
*/
- public void update(String id);
-
- //~--- get methods ----------------------------------------------------------
+ void install(String name, boolean restartAfterInstallation);
/**
- * Method description
- *
- *
- * @param id
- *
- * @return
+ * Install all pending plugins and restart the scm context.
*/
- public PluginInformation get(String id);
-
- /**
- * Method description
- *
- *
- * @param filter
- *
- * @return
- */
- public Collection get(Predicate filter);
-
- /**
- * Method description
- *
- *
- * @return
- */
- public Collection getAll();
-
- /**
- * Method description
- *
- *
- * @return
- */
- public Collection getAvailable();
-
- /**
- * Method description
- *
- *
- * @return
- */
- public Collection getAvailableUpdates();
-
- /**
- * Method description
- *
- *
- * @return
- */
- public Collection getInstalled();
+ void installPendingAndRestart();
}
diff --git a/scm-core/src/main/java/sonia/scm/plugin/PluginRepository.java b/scm-core/src/main/java/sonia/scm/plugin/PluginRepository.java
deleted file mode 100644
index 1d4cc07338..0000000000
--- a/scm-core/src/main/java/sonia/scm/plugin/PluginRepository.java
+++ /dev/null
@@ -1,160 +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.plugin;
-
-//~--- non-JDK imports --------------------------------------------------------
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Objects;
-
-import java.io.Serializable;
-
-//~--- JDK imports ------------------------------------------------------------
-
-/**
- *
- * @author Sebastian Sdorra
- */
-public class PluginRepository implements Serializable
-{
-
- /** Field description */
- private static final long serialVersionUID = -9504354306304731L;
-
- //~--- constructors ---------------------------------------------------------
-
- /**
- * Constructs ...
- *
- */
- PluginRepository() {}
-
- /**
- * Constructs ...
- *
- *
- * @param id
- * @param url
- */
- public PluginRepository(String id, String url)
- {
- this.id = id;
- this.url = url;
- }
-
- //~--- methods --------------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @param obj
- *
- * @return
- */
- @Override
- public boolean equals(Object obj)
- {
- if (obj == null)
- {
- return false;
- }
-
- if (getClass() != obj.getClass())
- {
- return false;
- }
-
- final PluginRepository other = (PluginRepository) obj;
-
- return Objects.equal(id, other.id) && Objects.equal(url, other.url);
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- @Override
- public int hashCode()
- {
- return Objects.hashCode(id, url);
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- @Override
- public String toString()
- {
- return MoreObjects.toStringHelper(this).add("id", id).add("url",
- url).toString();
- }
-
- //~--- get methods ----------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @return
- */
- public String getId()
- {
- return id;
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- public String getUrl()
- {
- return url;
- }
-
- //~--- fields ---------------------------------------------------------------
-
- /** Field description */
- private String id;
-
- /** Field description */
- private String url;
-}
diff --git a/scm-core/src/main/java/sonia/scm/plugin/PluginState.java b/scm-core/src/main/java/sonia/scm/plugin/PluginState.java
deleted file mode 100644
index 39803d3455..0000000000
--- a/scm-core/src/main/java/sonia/scm/plugin/PluginState.java
+++ /dev/null
@@ -1,74 +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.plugin;
-
-/**
- *
- * @author Sebastian Sdorra
- */
-public enum PluginState
-{
- CORE(100), AVAILABLE(60), INSTALLED(80), NEWER_VERSION_INSTALLED(20),
- UPDATE_AVAILABLE(40);
-
- /**
- * Constructs ...
- *
- *
- * @param compareValue
- */
- private PluginState(int compareValue)
- {
- this.compareValue = compareValue;
- }
-
- //~--- get methods ----------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @since 1.6
- * @return
- */
- public int getCompareValue()
- {
- return compareValue;
- }
-
- //~--- fields ---------------------------------------------------------------
-
- /** Field description */
- private final int compareValue;
-}
diff --git a/scm-core/src/main/java/sonia/scm/plugin/Plugins.java b/scm-core/src/main/java/sonia/scm/plugin/Plugins.java
index 6359850712..f33a254581 100644
--- a/scm-core/src/main/java/sonia/scm/plugin/Plugins.java
+++ b/scm-core/src/main/java/sonia/scm/plugin/Plugins.java
@@ -65,7 +65,7 @@ public final class Plugins
{
try
{
- context = JAXBContext.newInstance(Plugin.class, ScmModule.class);
+ context = JAXBContext.newInstance(InstalledPluginDescriptor.class, ScmModule.class);
}
catch (JAXBException ex)
{
@@ -91,7 +91,7 @@ public final class Plugins
*
* @return
*/
- public static Plugin parsePluginDescriptor(Path path)
+ public static InstalledPluginDescriptor parsePluginDescriptor(Path path)
{
return parsePluginDescriptor(Files.asByteSource(path.toFile()));
}
@@ -104,15 +104,15 @@ public final class Plugins
*
* @return
*/
- public static Plugin parsePluginDescriptor(ByteSource data)
+ public static InstalledPluginDescriptor parsePluginDescriptor(ByteSource data)
{
Preconditions.checkNotNull(data, "data parameter is required");
- Plugin plugin;
+ InstalledPluginDescriptor plugin;
try (InputStream stream = data.openStream())
{
- plugin = (Plugin) context.createUnmarshaller().unmarshal(stream);
+ plugin = (InstalledPluginDescriptor) context.createUnmarshaller().unmarshal(stream);
}
catch (JAXBException ex)
{
diff --git a/scm-core/src/main/java/sonia/scm/plugin/SmpArchive.java b/scm-core/src/main/java/sonia/scm/plugin/SmpArchive.java
index 63d5e8fb8f..e1ea622bdf 100644
--- a/scm-core/src/main/java/sonia/scm/plugin/SmpArchive.java
+++ b/scm-core/src/main/java/sonia/scm/plugin/SmpArchive.java
@@ -206,7 +206,7 @@ public final class SmpArchive
*
* @throws IOException
*/
- public Plugin getPlugin() throws IOException
+ public InstalledPluginDescriptor getPlugin() throws IOException
{
if (plugin == null)
{
@@ -219,16 +219,10 @@ public final class SmpArchive
throw new PluginException("could not find information section");
}
- if (Strings.isNullOrEmpty(info.getGroupId()))
+ if (Strings.isNullOrEmpty(info.getName()))
{
throw new PluginException(
- "could not find groupId in plugin descriptor");
- }
-
- if (Strings.isNullOrEmpty(info.getArtifactId()))
- {
- throw new PluginException(
- "could not find artifactId in plugin descriptor");
+ "could not find name in plugin descriptor");
}
if (Strings.isNullOrEmpty(info.getVersion()))
@@ -251,9 +245,9 @@ public final class SmpArchive
*
* @throws IOException
*/
- private Plugin createPlugin() throws IOException
+ private InstalledPluginDescriptor createPlugin() throws IOException
{
- Plugin p = null;
+ InstalledPluginDescriptor p = null;
NonClosingZipInputStream zis = null;
try
@@ -418,5 +412,5 @@ public final class SmpArchive
private final ByteSource archive;
/** Field description */
- private Plugin plugin;
+ private InstalledPluginDescriptor plugin;
}
diff --git a/scm-core/src/main/java/sonia/scm/plugin/StatePluginPredicate.java b/scm-core/src/main/java/sonia/scm/plugin/StatePluginPredicate.java
deleted file mode 100644
index ef7836f74a..0000000000
--- a/scm-core/src/main/java/sonia/scm/plugin/StatePluginPredicate.java
+++ /dev/null
@@ -1,78 +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.plugin;
-
-//~--- non-JDK imports --------------------------------------------------------
-
-import com.google.common.base.Predicate;
-
-/**
- *
- * @author Sebastian Sdorra
- */
-public class StatePluginPredicate implements Predicate
-{
-
- /**
- * Constructs ...
- *
- *
- * @param state
- */
- public StatePluginPredicate(PluginState state)
- {
- this.state = state;
- }
-
- //~--- methods --------------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @param plugin
- *
- * @return
- */
- @Override
- public boolean apply(PluginInformation plugin)
- {
- return state == plugin.getState();
- }
-
- //~--- fields ---------------------------------------------------------------
-
- /** Field description */
- private final PluginState state;
-}
diff --git a/scm-core/src/main/java/sonia/scm/repository/Repository.java b/scm-core/src/main/java/sonia/scm/repository/Repository.java
index 5bb50db06f..463085a7ea 100644
--- a/scm-core/src/main/java/sonia/scm/repository/Repository.java
+++ b/scm-core/src/main/java/sonia/scm/repository/Repository.java
@@ -82,10 +82,9 @@ public class Repository extends BasicPropertiesAware implements ModelObject, Per
private String namespace;
private String name;
@XmlElement(name = "permission")
- private final Set permissions = new HashSet<>();
+ private Set permissions = new HashSet<>();
@XmlElement(name = "public")
private boolean publicReadable = false;
- private boolean archived = false;
private String type;
@@ -216,16 +215,6 @@ public class Repository extends BasicPropertiesAware implements ModelObject, Per
return type;
}
- /**
- * Returns true if the repository is archived.
- *
- * @return true if the repository is archived
- * @since 1.14
- */
- public boolean isArchived() {
- return archived;
- }
-
/**
* Returns {@code true} if the repository is healthy.
*
@@ -264,16 +253,6 @@ public class Repository extends BasicPropertiesAware implements ModelObject, Per
&& ((Util.isEmpty(contact)) || ValidationUtil.isMailAddressValid(contact));
}
- /**
- * Archive or un archive this repository.
- *
- * @param archived true to enable archive
- * @since 1.14
- */
- public void setArchived(boolean archived) {
- this.archived = archived;
- }
-
public void setContact(String contact) {
this.contact = contact;
}
@@ -331,6 +310,8 @@ public class Repository extends BasicPropertiesAware implements ModelObject, Per
try {
repository = (Repository) super.clone();
+ // fix permission reference on clone
+ repository.permissions = new HashSet<>(permissions);
} catch (CloneNotSupportedException ex) {
throw new RuntimeException(ex);
}
@@ -352,7 +333,6 @@ public class Repository extends BasicPropertiesAware implements ModelObject, Per
repository.setDescription(description);
repository.setPermissions(permissions);
repository.setPublicReadable(publicReadable);
- repository.setArchived(archived);
// do not copy health check results
}
@@ -381,7 +361,6 @@ public class Repository extends BasicPropertiesAware implements ModelObject, Per
&& Objects.equal(contact, other.contact)
&& Objects.equal(description, other.description)
&& Objects.equal(publicReadable, other.publicReadable)
- && Objects.equal(archived, other.archived)
&& Objects.equal(permissions, other.permissions)
&& Objects.equal(type, other.type)
&& Objects.equal(creationDate, other.creationDate)
@@ -393,7 +372,7 @@ public class Repository extends BasicPropertiesAware implements ModelObject, Per
@Override
public int hashCode() {
return Objects.hashCode(id, namespace, name, contact, description, publicReadable,
- archived, permissions, type, creationDate, lastModified, properties,
+ permissions, type, creationDate, lastModified, properties,
healthCheckFailures);
}
@@ -406,7 +385,6 @@ public class Repository extends BasicPropertiesAware implements ModelObject, Per
.add("contact", contact)
.add("description", description)
.add("publicReadable", publicReadable)
- .add("archived", archived)
.add("permissions", permissions)
.add("type", type)
.add("lastModified", lastModified)
diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryIsNotArchivedException.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryIsNotArchivedException.java
deleted file mode 100644
index a427050633..0000000000
--- a/scm-core/src/main/java/sonia/scm/repository/RepositoryIsNotArchivedException.java
+++ /dev/null
@@ -1,48 +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.repository;
-
-/**
- *
- * @author Sebastian Sdorra
- *
- * @since 1.14
- */
-public class RepositoryIsNotArchivedException extends RuntimeException {
-
- private static final long serialVersionUID = 7728748133123987511L;
-
- public RepositoryIsNotArchivedException() {
- super("Repository could not be deleted, because it is not archived.");
- }
-}
diff --git a/scm-core/src/main/java/sonia/scm/repository/api/AbstractDiffCommandBuilder.java b/scm-core/src/main/java/sonia/scm/repository/api/AbstractDiffCommandBuilder.java
new file mode 100644
index 0000000000..b5b2f2a08b
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/repository/api/AbstractDiffCommandBuilder.java
@@ -0,0 +1,68 @@
+package sonia.scm.repository.api;
+
+import sonia.scm.FeatureNotSupportedException;
+import sonia.scm.repository.Feature;
+import sonia.scm.repository.spi.DiffCommandRequest;
+
+import java.util.Set;
+
+abstract class AbstractDiffCommandBuilder {
+
+
+ /** request for the diff command implementation */
+ final DiffCommandRequest request = new DiffCommandRequest();
+
+ private final Set supportedFeatures;
+
+ AbstractDiffCommandBuilder(Set supportedFeatures) {
+ this.supportedFeatures = supportedFeatures;
+ }
+
+ /**
+ * Compute the incoming changes of the branch set with {@link #setRevision(String)} in respect to the changeset given
+ * here. In other words: What changes would be new to the ancestor changeset given here when the branch would
+ * be merged into it. Requires feature {@link sonia.scm.repository.Feature#INCOMING_REVISION}!
+ *
+ * @return {@code this}
+ */
+ public T setAncestorChangeset(String revision)
+ {
+ if (!supportedFeatures.contains(Feature.INCOMING_REVISION)) {
+ throw new FeatureNotSupportedException(Feature.INCOMING_REVISION.name());
+ }
+ request.setAncestorChangeset(revision);
+
+ return self();
+ }
+
+ /**
+ * Show the difference only for the given path.
+ *
+ *
+ * @param path path for difference
+ *
+ * @return {@code this}
+ */
+ public T setPath(String path)
+ {
+ request.setPath(path);
+ return self();
+ }
+
+ /**
+ * Show the difference only for the given revision or (using {@link #setAncestorChangeset(String)}) between this
+ * and another revision.
+ *
+ *
+ * @param revision revision for difference
+ *
+ * @return {@code this}
+ */
+ public T setRevision(String revision)
+ {
+ request.setRevision(revision);
+ return self();
+ }
+
+ abstract T self();
+}
diff --git a/scm-core/src/main/java/sonia/scm/repository/api/Command.java b/scm-core/src/main/java/sonia/scm/repository/api/Command.java
index e380727769..3249e54ec3 100644
--- a/scm-core/src/main/java/sonia/scm/repository/api/Command.java
+++ b/scm-core/src/main/java/sonia/scm/repository/api/Command.java
@@ -53,11 +53,6 @@ public enum Command
*/
BRANCHES,
- /**
- * @since 2.0
- */
- BRANCH,
-
/**
* @since 1.31
*/
@@ -71,10 +66,5 @@ public enum Command
/**
* @since 2.0
*/
- MODIFICATIONS,
-
- /**
- * @since 2.0
- */
- MERGE
+ MODIFICATIONS, MERGE, DIFF_RESULT, BRANCH;
}
diff --git a/scm-core/src/main/java/sonia/scm/repository/api/DiffCommandBuilder.java b/scm-core/src/main/java/sonia/scm/repository/api/DiffCommandBuilder.java
index 9e7094d5bf..18d4e11a7f 100644
--- a/scm-core/src/main/java/sonia/scm/repository/api/DiffCommandBuilder.java
+++ b/scm-core/src/main/java/sonia/scm/repository/api/DiffCommandBuilder.java
@@ -38,10 +38,8 @@ package sonia.scm.repository.api;
import com.google.common.base.Preconditions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import sonia.scm.FeatureNotSupportedException;
import sonia.scm.repository.Feature;
import sonia.scm.repository.spi.DiffCommand;
-import sonia.scm.repository.spi.DiffCommandRequest;
import sonia.scm.util.IOUtil;
import java.io.ByteArrayOutputStream;
@@ -72,7 +70,7 @@ import java.util.Set;
* @author Sebastian Sdorra
* @since 1.17
*/
-public final class DiffCommandBuilder
+public final class DiffCommandBuilder extends AbstractDiffCommandBuilder
{
/**
@@ -81,6 +79,9 @@ public final class DiffCommandBuilder
private static final Logger logger =
LoggerFactory.getLogger(DiffCommandBuilder.class);
+ /** implementation of the diff command */
+ private final DiffCommand diffCommand;
+
//~--- constructors ---------------------------------------------------------
/**
@@ -92,8 +93,8 @@ public final class DiffCommandBuilder
*/
DiffCommandBuilder(DiffCommand diffCommand, Set supportedFeatures)
{
+ super(supportedFeatures);
this.diffCommand = diffCommand;
- this.supportedFeatures = supportedFeatures;
}
//~--- methods --------------------------------------------------------------
@@ -162,54 +163,6 @@ public final class DiffCommandBuilder
return this;
}
-
- /**
- * Show the difference only for the given path.
- *
- *
- * @param path path for difference
- *
- * @return {@code this}
- */
- public DiffCommandBuilder setPath(String path)
- {
- request.setPath(path);
-
- return this;
- }
-
- /**
- * Show the difference only for the given revision or (using {@link #setAncestorChangeset(String)}) between this
- * and another revision.
- *
- *
- * @param revision revision for difference
- *
- * @return {@code this}
- */
- public DiffCommandBuilder setRevision(String revision)
- {
- request.setRevision(revision);
-
- return this;
- }
- /**
- * Compute the incoming changes of the branch set with {@link #setRevision(String)} in respect to the changeset given
- * here. In other words: What changes would be new to the ancestor changeset given here when the branch would
- * be merged into it. Requires feature {@link sonia.scm.repository.Feature#INCOMING_REVISION}!
- *
- * @return {@code this}
- */
- public DiffCommandBuilder setAncestorChangeset(String revision)
- {
- if (!supportedFeatures.contains(Feature.INCOMING_REVISION)) {
- throw new FeatureNotSupportedException(Feature.INCOMING_REVISION.name());
- }
- request.setAncestorChangeset(revision);
-
- return this;
- }
-
//~--- get methods ----------------------------------------------------------
/**
@@ -233,12 +186,8 @@ public final class DiffCommandBuilder
diffCommand.getDiffResult(request, outputStream);
}
- //~--- fields ---------------------------------------------------------------
-
- /** implementation of the diff command */
- private final DiffCommand diffCommand;
- private Set supportedFeatures;
-
- /** request for the diff command implementation */
- private final DiffCommandRequest request = new DiffCommandRequest();
+ @Override
+ DiffCommandBuilder self() {
+ return this;
+ }
}
diff --git a/scm-core/src/main/java/sonia/scm/repository/api/DiffFile.java b/scm-core/src/main/java/sonia/scm/repository/api/DiffFile.java
new file mode 100644
index 0000000000..a3b1bafe0b
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/repository/api/DiffFile.java
@@ -0,0 +1,12 @@
+package sonia.scm.repository.api;
+
+public interface DiffFile extends Iterable {
+
+ String getOldRevision();
+
+ String getNewRevision();
+
+ String getOldPath();
+
+ String getNewPath();
+}
diff --git a/scm-core/src/main/java/sonia/scm/repository/api/DiffLine.java b/scm-core/src/main/java/sonia/scm/repository/api/DiffLine.java
new file mode 100644
index 0000000000..193e5e75d5
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/repository/api/DiffLine.java
@@ -0,0 +1,12 @@
+package sonia.scm.repository.api;
+
+import java.util.OptionalInt;
+
+public interface DiffLine {
+
+ OptionalInt getOldLineNumber();
+
+ OptionalInt getNewLineNumber();
+
+ String getContent();
+}
diff --git a/scm-core/src/main/java/sonia/scm/repository/api/DiffResult.java b/scm-core/src/main/java/sonia/scm/repository/api/DiffResult.java
new file mode 100644
index 0000000000..b662db4e2d
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/repository/api/DiffResult.java
@@ -0,0 +1,8 @@
+package sonia.scm.repository.api;
+
+public interface DiffResult extends Iterable {
+
+ String getOldRevision();
+
+ String getNewRevision();
+}
diff --git a/scm-core/src/main/java/sonia/scm/repository/api/DiffResultCommandBuilder.java b/scm-core/src/main/java/sonia/scm/repository/api/DiffResultCommandBuilder.java
new file mode 100644
index 0000000000..7e152f3d0f
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/repository/api/DiffResultCommandBuilder.java
@@ -0,0 +1,41 @@
+package sonia.scm.repository.api;
+
+import com.google.common.base.Preconditions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import sonia.scm.repository.Feature;
+import sonia.scm.repository.spi.DiffResultCommand;
+
+import java.io.IOException;
+import java.util.Set;
+
+public class DiffResultCommandBuilder extends AbstractDiffCommandBuilder {
+
+ private static final Logger LOG = LoggerFactory.getLogger(DiffResultCommandBuilder.class);
+
+ private final DiffResultCommand diffResultCommand;
+
+ DiffResultCommandBuilder(DiffResultCommand diffResultCommand, Set supportedFeatures) {
+ super(supportedFeatures);
+ this.diffResultCommand = diffResultCommand;
+ }
+
+ /**
+ * Returns the content of the difference as parsed objects.
+ *
+ * @return content of the difference
+ */
+ public DiffResult getDiffResult() throws IOException {
+ Preconditions.checkArgument(request.isValid(),
+ "path and/or revision is required");
+
+ LOG.debug("create diff result for {}", request);
+
+ return diffResultCommand.getDiffResult(request);
+ }
+
+ @Override
+ DiffResultCommandBuilder self() {
+ return this;
+ }
+}
diff --git a/scm-core/src/main/java/sonia/scm/repository/api/Hunk.java b/scm-core/src/main/java/sonia/scm/repository/api/Hunk.java
new file mode 100644
index 0000000000..c8a3e1ebca
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/repository/api/Hunk.java
@@ -0,0 +1,24 @@
+package sonia.scm.repository.api;
+
+public interface Hunk extends Iterable {
+
+ default String getRawHeader() {
+ return String.format("@@ -%s +%s @@", getLineMarker(getOldStart(), getOldLineCount()), getLineMarker(getNewStart(), getNewLineCount()));
+ }
+
+ default String getLineMarker(int start, int lineCount) {
+ if (lineCount == 1) {
+ return Integer.toString(start);
+ } else {
+ return String.format("%s,%s", start, lineCount);
+ }
+ }
+
+ int getOldStart();
+
+ int getOldLineCount();
+
+ int getNewStart();
+
+ int getNewLineCount();
+}
diff --git a/scm-core/src/main/java/sonia/scm/repository/api/RepositoryService.java b/scm-core/src/main/java/sonia/scm/repository/api/RepositoryService.java
index 90978d75ea..5807ffa998 100644
--- a/scm-core/src/main/java/sonia/scm/repository/api/RepositoryService.java
+++ b/scm-core/src/main/java/sonia/scm/repository/api/RepositoryService.java
@@ -31,7 +31,6 @@
package sonia.scm.repository.api;
-import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.cache.CacheManager;
@@ -239,6 +238,21 @@ public final class RepositoryService implements Closeable {
return new DiffCommandBuilder(provider.getDiffCommand(), provider.getSupportedFeatures());
}
+ /**
+ * The diff command shows differences between revisions for a specified file
+ * or the entire revision.
+ *
+ * @return instance of {@link DiffResultCommandBuilder}
+ * @throws CommandNotSupportedException if the command is not supported
+ * by the implementation of the repository service provider.
+ */
+ public DiffResultCommandBuilder getDiffResultCommand() {
+ LOG.debug("create diff result command for repository {}",
+ repository.getNamespaceAndName());
+
+ return new DiffResultCommandBuilder(provider.getDiffResultCommand(), provider.getSupportedFeatures());
+ }
+
/**
* The incoming command shows new {@link Changeset}s found in a different
* repository location.
diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/DiffResultCommand.java b/scm-core/src/main/java/sonia/scm/repository/spi/DiffResultCommand.java
new file mode 100644
index 0000000000..ee50178d76
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/repository/spi/DiffResultCommand.java
@@ -0,0 +1,9 @@
+package sonia.scm.repository.spi;
+
+import sonia.scm.repository.api.DiffResult;
+
+import java.io.IOException;
+
+public interface DiffResultCommand {
+ DiffResult getDiffResult(DiffCommandRequest request) throws IOException;
+}
diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java b/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java
index a82eb7c30a..bf9cdf6a25 100644
--- a/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java
+++ b/scm-core/src/main/java/sonia/scm/repository/spi/RepositoryServiceProvider.java
@@ -158,6 +158,11 @@ public abstract class RepositoryServiceProvider implements Closeable
throw new CommandNotSupportedException(Command.DIFF);
}
+ public DiffResultCommand getDiffResultCommand()
+ {
+ throw new CommandNotSupportedException(Command.DIFF_RESULT);
+ }
+
/**
* Method description
*
diff --git a/scm-core/src/main/java/sonia/scm/security/AccessTokenBuilder.java b/scm-core/src/main/java/sonia/scm/security/AccessTokenBuilder.java
index 0924716bd8..afe81ac27f 100644
--- a/scm-core/src/main/java/sonia/scm/security/AccessTokenBuilder.java
+++ b/scm-core/src/main/java/sonia/scm/security/AccessTokenBuilder.java
@@ -99,15 +99,6 @@ public interface AccessTokenBuilder {
*/
AccessTokenBuilder scope(Scope scope);
- /**
- * Define the logged in user as member of the given groups.
- *
- * @param groups group names
- *
- * @return {@code this}
- */
- AccessTokenBuilder groups(String... groups);
-
/**
* Creates a new {@link AccessToken} with the provided settings.
*
diff --git a/scm-core/src/main/java/sonia/scm/security/DAORealmHelper.java b/scm-core/src/main/java/sonia/scm/security/DAORealmHelper.java
index ea3e7ce9f5..6ec64a67de 100644
--- a/scm-core/src/main/java/sonia/scm/security/DAORealmHelper.java
+++ b/scm-core/src/main/java/sonia/scm/security/DAORealmHelper.java
@@ -45,7 +45,6 @@ import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import sonia.scm.group.GroupDAO;
import sonia.scm.user.User;
import sonia.scm.user.UserDAO;
@@ -71,8 +70,6 @@ public final class DAORealmHelper {
private final UserDAO userDAO;
- private final GroupCollector groupCollector;
-
private final String realm;
//~--- constructors ---------------------------------------------------------
@@ -83,14 +80,12 @@ public final class DAORealmHelper {
*
* @param loginAttemptHandler login attempt handler for wrapping credentials matcher
* @param userDAO user dao
- * @param groupCollector collect groups for a principal
* @param realm name of realm
*/
- public DAORealmHelper(LoginAttemptHandler loginAttemptHandler, UserDAO userDAO, GroupCollector groupCollector, String realm) {
+ public DAORealmHelper(LoginAttemptHandler loginAttemptHandler, UserDAO userDAO, String realm) {
this.loginAttemptHandler = loginAttemptHandler;
this.realm = realm;
this.userDAO = userDAO;
- this.groupCollector = groupCollector;
}
//~--- get methods ----------------------------------------------------------
@@ -120,7 +115,7 @@ public final class DAORealmHelper {
UsernamePasswordToken upt = (UsernamePasswordToken) token;
String principal = upt.getUsername();
- return getAuthenticationInfo(principal, null, null, Collections.emptySet());
+ return getAuthenticationInfo(principal, null, null);
}
/**
@@ -135,7 +130,7 @@ public final class DAORealmHelper {
}
- private AuthenticationInfo getAuthenticationInfo(String principal, String credentials, Scope scope, Iterable groups) {
+ private AuthenticationInfo getAuthenticationInfo(String principal, String credentials, Scope scope) {
checkArgument(!Strings.isNullOrEmpty(principal), "username is required");
LOG.debug("try to authenticate {}", principal);
@@ -153,7 +148,6 @@ public final class DAORealmHelper {
collection.add(principal, realm);
collection.add(user, realm);
- collection.add(groupCollector.collect(principal, groups), realm);
collection.add(MoreObjects.firstNonNull(scope, Scope.empty()), realm);
String creds = credentials;
@@ -207,17 +201,17 @@ public final class DAORealmHelper {
return this;
}
- /**
- * With groups adds extra groups, besides those which come from the {@link GroupDAO}, to the authentication info.
- *
- * @param groups extra groups
- *
- * @return {@code this}
- */
- public AuthenticationInfoBuilder withGroups(Iterable groups) {
- this.groups = groups;
- return this;
- }
+// /**
+// * With groups adds extra groups, besides those which come from the {@link GroupDAO}, to the authentication info.
+// *
+// * @param groups extra groups
+// *
+// * @return {@code this}
+// */
+// public AuthenticationInfoBuilder withGroups(Iterable groups) {
+// this.groups = groups;
+// return this;
+// }
/**
* Build creates the authentication info from the given information.
@@ -225,7 +219,7 @@ public final class DAORealmHelper {
* @return authentication info
*/
public AuthenticationInfo build() {
- return getAuthenticationInfo(principal, credentials, scope, groups);
+ return getAuthenticationInfo(principal, credentials, scope);
}
}
diff --git a/scm-core/src/main/java/sonia/scm/security/DAORealmHelperFactory.java b/scm-core/src/main/java/sonia/scm/security/DAORealmHelperFactory.java
index ee2bf11e21..dd59de2ac8 100644
--- a/scm-core/src/main/java/sonia/scm/security/DAORealmHelperFactory.java
+++ b/scm-core/src/main/java/sonia/scm/security/DAORealmHelperFactory.java
@@ -30,7 +30,7 @@
*/
package sonia.scm.security;
-import sonia.scm.group.GroupDAO;
+import sonia.scm.cache.CacheManager;
import sonia.scm.user.UserDAO;
import javax.inject.Inject;
@@ -45,20 +45,19 @@ public final class DAORealmHelperFactory {
private final LoginAttemptHandler loginAttemptHandler;
private final UserDAO userDAO;
- private final GroupCollector groupCollector;
+ private final CacheManager cacheManager;
/**
* Constructs a new instance.
- *
* @param loginAttemptHandler login attempt handler
* @param userDAO user dao
- * @param groupDAO group dao
+ * @param cacheManager
*/
@Inject
- public DAORealmHelperFactory(LoginAttemptHandler loginAttemptHandler, UserDAO userDAO, GroupDAO groupDAO) {
+ public DAORealmHelperFactory(LoginAttemptHandler loginAttemptHandler, UserDAO userDAO, CacheManager cacheManager) {
this.loginAttemptHandler = loginAttemptHandler;
this.userDAO = userDAO;
- this.groupCollector = new GroupCollector(groupDAO);
+ this.cacheManager = cacheManager;
}
/**
@@ -69,7 +68,7 @@ public final class DAORealmHelperFactory {
* @return new {@link DAORealmHelper} instance.
*/
public DAORealmHelper create(String realm) {
- return new DAORealmHelper(loginAttemptHandler, userDAO, groupCollector, realm);
+ return new DAORealmHelper(loginAttemptHandler, userDAO, realm);
}
}
diff --git a/scm-core/src/main/java/sonia/scm/security/GroupCollector.java b/scm-core/src/main/java/sonia/scm/security/GroupCollector.java
deleted file mode 100644
index 56687af7ef..0000000000
--- a/scm-core/src/main/java/sonia/scm/security/GroupCollector.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package sonia.scm.security;
-
-import com.google.common.collect.ImmutableSet;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import sonia.scm.group.Group;
-import sonia.scm.group.GroupDAO;
-import sonia.scm.group.GroupNames;
-
-/**
- * Collect groups for a certain principal.
- * Warning: The class is only for internal use and should never used directly.
- */
-class GroupCollector {
-
- private static final Logger LOG = LoggerFactory.getLogger(GroupCollector.class);
-
- private final GroupDAO groupDAO;
-
- GroupCollector(GroupDAO groupDAO) {
- this.groupDAO = groupDAO;
- }
-
- GroupNames collect(String principal, Iterable groupNames) {
- ImmutableSet.Builder builder = ImmutableSet.builder();
-
- builder.add(GroupNames.AUTHENTICATED);
-
- for (String group : groupNames) {
- builder.add(group);
- }
-
- for (Group group : groupDAO.getAll()) {
- if (group.isMember(principal)) {
- builder.add(group.getName());
- }
- }
-
- GroupNames groups = new GroupNames(builder.build());
- LOG.debug("collected following groups for principal {}: {}", principal, groups);
- return groups;
- }
-}
diff --git a/scm-core/src/main/java/sonia/scm/security/SyncingRealmHelper.java b/scm-core/src/main/java/sonia/scm/security/SyncingRealmHelper.java
index d421d33f45..b2175f304a 100644
--- a/scm-core/src/main/java/sonia/scm/security/SyncingRealmHelper.java
+++ b/scm-core/src/main/java/sonia/scm/security/SyncingRealmHelper.java
@@ -32,24 +32,15 @@ import com.google.inject.Inject;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.subject.SimplePrincipalCollection;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import sonia.scm.AlreadyExistsException;
import sonia.scm.NotFoundException;
-import sonia.scm.group.ExternalGroupNames;
import sonia.scm.group.Group;
-import sonia.scm.group.GroupDAO;
import sonia.scm.group.GroupManager;
import sonia.scm.plugin.Extension;
import sonia.scm.user.User;
import sonia.scm.user.UserManager;
import sonia.scm.web.security.AdministrationContext;
-import java.util.Collection;
-import java.util.Collections;
-
-import static java.util.Arrays.asList;
-
/**
* Helper class for syncing realms. The class should simplify the creation of realms, which are syncing authenticated
* users with the local database.
@@ -60,12 +51,9 @@ import static java.util.Arrays.asList;
@Extension
public final class SyncingRealmHelper {
- private static final Logger LOG = LoggerFactory.getLogger(SyncingRealmHelper.class);
-
private final AdministrationContext ctx;
private final UserManager userManager;
private final GroupManager groupManager;
- private final GroupCollector groupCollector;
/**
* Constructs a new SyncingRealmHelper.
@@ -73,134 +61,28 @@ public final class SyncingRealmHelper {
* @param ctx administration context
* @param userManager user manager
* @param groupManager group manager
- * @param groupDAO group dao
*/
@Inject
- public SyncingRealmHelper(AdministrationContext ctx, UserManager userManager, GroupManager groupManager, GroupDAO groupDAO) {
+ public SyncingRealmHelper(AdministrationContext ctx, UserManager userManager, GroupManager groupManager) {
this.ctx = ctx;
this.userManager = userManager;
this.groupManager = groupManager;
- this.groupCollector = new GroupCollector(groupDAO);
}
- /**
- * Create {@link AuthenticationInfo} from user and groups.
- */
- public AuthenticationInfoBuilder.ForRealm authenticationInfo() {
- return new AuthenticationInfoBuilder().new ForRealm();
- }
-
- public class AuthenticationInfoBuilder {
- private String realm;
- private User user;
- private Collection groups = Collections.emptySet();
- private Collection externalGroups = Collections.emptySet();
-
- private AuthenticationInfo build() {
- return SyncingRealmHelper.this.createAuthenticationInfo(realm, user, groups, externalGroups);
- }
-
- public class ForRealm {
- private ForRealm() {
- }
-
- /**
- * Sets the realm.
- * @param realm name of the realm
- */
- public ForUser forRealm(String realm) {
- AuthenticationInfoBuilder.this.realm = realm;
- return AuthenticationInfoBuilder.this.new ForUser();
- }
- }
-
- public class ForUser {
- private ForUser() {
- }
-
- /**
- * Sets the user.
- * @param user authenticated user
- */
- public AuthenticationInfoBuilder.WithGroups andUser(User user) {
- AuthenticationInfoBuilder.this.user = user;
- return AuthenticationInfoBuilder.this.new WithGroups();
- }
- }
-
- public class WithGroups {
- private WithGroups() {
- }
-
- /**
- * Set the internal groups for the user.
- * @param groups groups of the authenticated user
- * @return builder step for groups
- */
- public WithGroups withGroups(String... groups) {
- return withGroups(asList(groups));
- }
-
- /**
- * Set the internal groups for the user.
- * @param groups groups of the authenticated user
- * @return builder step for groups
- */
- public WithGroups withGroups(Collection groups) {
- AuthenticationInfoBuilder.this.groups = groups;
- return this;
- }
-
- /**
- * Set the external groups for the user.
- * @param externalGroups external groups of the authenticated user
- * @return builder step for groups
- */
- public WithGroups withExternalGroups(String... externalGroups) {
- return withExternalGroups(asList(externalGroups));
- }
-
- /**
- * Set the external groups for the user.
- * @param externalGroups external groups of the authenticated user
- * @return builder step for groups
- */
- public WithGroups withExternalGroups(Collection externalGroups) {
- AuthenticationInfoBuilder.this.externalGroups = externalGroups;
- return this;
- }
-
- /**
- * Builds the {@link AuthenticationInfo} from the given options.
- *
- * @return complete autentication info
- */
- public AuthenticationInfo build() {
- return AuthenticationInfoBuilder.this.build();
- }
- }
- }
-
- //~--- methods --------------------------------------------------------------
-
/**
* Create {@link AuthenticationInfo} from user and groups.
*
*
* @param realm name of the realm
* @param user authenticated user
- * @param groups groups of the authenticated user
*
* @return authentication info
*/
- private AuthenticationInfo createAuthenticationInfo(String realm, User user,
- Collection groups, Collection externalGroups) {
+ public AuthenticationInfo createAuthenticationInfo(String realm, User user) {
SimplePrincipalCollection collection = new SimplePrincipalCollection();
collection.add(user.getId(), realm);
collection.add(user, realm);
- collection.add(groupCollector.collect(user.getId(), groups), realm);
- collection.add(new ExternalGroupNames(externalGroups), realm);
return new SimpleAuthenticationInfo(collection, user.getPassword());
}
diff --git a/scm-core/src/main/java/sonia/scm/util/IOUtil.java b/scm-core/src/main/java/sonia/scm/util/IOUtil.java
index 16f84d1031..4058c089f4 100644
--- a/scm-core/src/main/java/sonia/scm/util/IOUtil.java
+++ b/scm-core/src/main/java/sonia/scm/util/IOUtil.java
@@ -37,14 +37,11 @@ package sonia.scm.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
import sonia.scm.io.Command;
import sonia.scm.io.CommandResult;
import sonia.scm.io.SimpleCommand;
import sonia.scm.io.ZipUnArchiver;
-//~--- JDK imports ------------------------------------------------------------
-
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
@@ -55,12 +52,13 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
+//~--- JDK imports ------------------------------------------------------------
+
/**
*
* @author Sebastian Sdorra
diff --git a/scm-webapp/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilter.java b/scm-core/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilterBase.java
similarity index 74%
rename from scm-webapp/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilter.java
rename to scm-core/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilterBase.java
index 973b3af4cb..8b1868309b 100644
--- a/scm-webapp/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilter.java
+++ b/scm-core/src/main/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilterBase.java
@@ -1,16 +1,11 @@
package sonia.scm.web.filter;
-import sonia.scm.Priority;
import sonia.scm.config.ScmConfiguration;
-import sonia.scm.filter.Filters;
-import sonia.scm.filter.WebElement;
import sonia.scm.util.HttpUtil;
import sonia.scm.web.UserAgent;
import sonia.scm.web.UserAgentParser;
import sonia.scm.web.WebTokenGenerator;
-import sonia.scm.web.protocol.HttpProtocolServlet;
-import javax.inject.Inject;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@@ -18,14 +13,11 @@ import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Set;
-@Priority(Filters.PRIORITY_AUTHENTICATION)
-@WebElement(value = HttpProtocolServlet.PATTERN)
-public class HttpProtocolServletAuthenticationFilter extends AuthenticationFilter {
+public class HttpProtocolServletAuthenticationFilterBase extends AuthenticationFilter {
private final UserAgentParser userAgentParser;
- @Inject
- public HttpProtocolServletAuthenticationFilter(
+ protected HttpProtocolServletAuthenticationFilterBase(
ScmConfiguration configuration,
Set tokenGenerators,
UserAgentParser userAgentParser) {
diff --git a/scm-core/src/test/java/sonia/scm/plugin/AvailablePluginTest.java b/scm-core/src/test/java/sonia/scm/plugin/AvailablePluginTest.java
new file mode 100644
index 0000000000..bfdf74fdb1
--- /dev/null
+++ b/scm-core/src/test/java/sonia/scm/plugin/AvailablePluginTest.java
@@ -0,0 +1,32 @@
+package sonia.scm.plugin;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+@ExtendWith(MockitoExtension.class)
+class AvailablePluginTest {
+
+ @Mock
+ private AvailablePluginDescriptor descriptor;
+
+ @Test
+ void shouldReturnNewPendingPluginOnInstall() {
+ AvailablePlugin plugin = new AvailablePlugin(descriptor);
+ assertThat(plugin.isPending()).isFalse();
+
+ AvailablePlugin installed = plugin.install();
+ assertThat(installed.isPending()).isTrue();
+ }
+
+ @Test
+ void shouldThrowIllegalStateExceptionIfAlreadyPending() {
+ AvailablePlugin plugin = new AvailablePlugin(descriptor).install();
+ assertThrows(IllegalStateException.class, () -> plugin.install());
+ }
+
+}
diff --git a/scm-core/src/test/java/sonia/scm/plugin/SmpArchiveTest.java b/scm-core/src/test/java/sonia/scm/plugin/SmpArchiveTest.java
index 95addf388f..07e182216f 100644
--- a/scm-core/src/test/java/sonia/scm/plugin/SmpArchiveTest.java
+++ b/scm-core/src/test/java/sonia/scm/plugin/SmpArchiveTest.java
@@ -85,7 +85,7 @@ public class SmpArchiveTest
public void testExtract()
throws IOException, ParserConfigurationException, SAXException
{
- File archive = createArchive("sonia.sample", "sample", "1.0");
+ File archive = createArchive("sonia.sample", "1.0");
File target = tempFolder.newFolder();
IOUtil.mkdirs(target);
@@ -112,8 +112,8 @@ public class SmpArchiveTest
@Test
public void testGetPlugin() throws IOException
{
- File archive = createArchive("sonia.sample", "sample", "1.0");
- Plugin plugin = SmpArchive.create(archive).getPlugin();
+ File archive = createArchive("sonia.sample", "1.0");
+ InstalledPluginDescriptor plugin = SmpArchive.create(archive).getPlugin();
assertNotNull(plugin);
@@ -121,8 +121,7 @@ public class SmpArchiveTest
assertNotNull(info);
- assertEquals("sonia.sample", info.getGroupId());
- assertEquals("sample", info.getArtifactId());
+ assertEquals("sonia.sample", info.getName());
assertEquals("1.0", info.getVersion());
}
@@ -132,22 +131,9 @@ public class SmpArchiveTest
* @throws IOException
*/
@Test(expected = PluginException.class)
- public void testWithMissingArtifactId() throws IOException
+ public void testWithMissingName() throws IOException
{
- File archive = createArchive("sonia.sample", null, "1.0");
-
- SmpArchive.create(archive).getPlugin();
- }
-
- /**
- * Method description
- *
- * @throws IOException
- */
- @Test(expected = PluginException.class)
- public void testWithMissingGroupId() throws IOException
- {
- File archive = createArchive(null, "sample", "1.0");
+ File archive = createArchive( null, "1.0");
SmpArchive.create(archive).getPlugin();
}
@@ -160,7 +146,7 @@ public class SmpArchiveTest
@Test(expected = PluginException.class)
public void testWithMissingVersion() throws IOException
{
- File archive = createArchive("sonia.sample", "sample", null);
+ File archive = createArchive("sonia.sample", null);
SmpArchive.create(archive).getPlugin();
}
@@ -169,13 +155,12 @@ public class SmpArchiveTest
* Method description
*
*
- * @param groupId
- * @param artifactId
+ * @param name
* @param version
*
* @return
*/
- private File createArchive(String groupId, String artifactId, String version)
+ private File createArchive(String name, String version)
{
File archiveFile;
@@ -183,7 +168,7 @@ public class SmpArchiveTest
{
File descriptor = tempFolder.newFile();
- writeDescriptor(descriptor, groupId, artifactId, version);
+ writeDescriptor(descriptor, name, version);
archiveFile = tempFolder.newFile();
try (ZipOutputStream zos =
@@ -229,14 +214,13 @@ public class SmpArchiveTest
*
*
* @param descriptor
- * @param groupId
- * @param artifactId
+ * @param name
* @param version
*
* @throws IOException
*/
- private void writeDescriptor(File descriptor, String groupId,
- String artifactId, String version)
+ private void writeDescriptor(File descriptor, String name,
+ String version)
throws IOException
{
try
@@ -252,8 +236,7 @@ public class SmpArchiveTest
writer.writeStartDocument();
writer.writeStartElement("plugin");
writer.writeStartElement("information");
- writeElement(writer, "groupId", groupId);
- writeElement(writer, "artifactId", artifactId);
+ writeElement(writer, "name", name);
writeElement(writer, "version", version);
writer.writeEndElement();
diff --git a/scm-core/src/test/java/sonia/scm/repository/RepositoryTest.java b/scm-core/src/test/java/sonia/scm/repository/RepositoryTest.java
new file mode 100644
index 0000000000..6053e10ad5
--- /dev/null
+++ b/scm-core/src/test/java/sonia/scm/repository/RepositoryTest.java
@@ -0,0 +1,22 @@
+package sonia.scm.repository;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class RepositoryTest {
+
+ @Test
+ void shouldCreateNewPermissionOnClone() {
+ Repository repository = new Repository();
+ repository.setPermissions(Arrays.asList(new RepositoryPermission("one", "role", false)));
+
+ Repository cloned = repository.clone();
+ cloned.setPermissions(Arrays.asList(new RepositoryPermission("two", "role", false)));
+
+ assertThat(repository.getPermissions()).extracting(r -> r.getName()).containsOnly("one");
+ }
+
+}
diff --git a/scm-core/src/test/java/sonia/scm/repository/api/HunkTest.java b/scm-core/src/test/java/sonia/scm/repository/api/HunkTest.java
new file mode 100644
index 0000000000..086df81741
--- /dev/null
+++ b/scm-core/src/test/java/sonia/scm/repository/api/HunkTest.java
@@ -0,0 +1,53 @@
+package sonia.scm.repository.api;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.Iterator;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class HunkTest {
+
+ @Test
+ void shouldGetComplexHeader() {
+ String rawHeader = createHunk(2, 3, 4, 5).getRawHeader();
+
+ assertThat(rawHeader).isEqualTo("@@ -2,3 +4,5 @@");
+ }
+
+ @Test
+ void shouldReturnSingleNumberForOne() {
+ String rawHeader = createHunk(42, 1, 5, 1).getRawHeader();
+
+ assertThat(rawHeader).isEqualTo("@@ -42 +5 @@");
+ }
+
+ private Hunk createHunk(int oldStart, int oldLineCount, int newStart, int newLineCount) {
+ return new Hunk() {
+ @Override
+ public int getOldStart() {
+ return oldStart;
+ }
+
+ @Override
+ public int getOldLineCount() {
+ return oldLineCount;
+ }
+
+ @Override
+ public int getNewStart() {
+ return newStart;
+ }
+
+ @Override
+ public int getNewLineCount() {
+ return newLineCount;
+ }
+
+ @Override
+ public Iterator iterator() {
+ return null;
+ }
+ };
+ }
+}
diff --git a/scm-core/src/test/java/sonia/scm/security/DAORealmHelperTest.java b/scm-core/src/test/java/sonia/scm/security/DAORealmHelperTest.java
index 78dbd4fdd2..0fbcc20ac0 100644
--- a/scm-core/src/test/java/sonia/scm/security/DAORealmHelperTest.java
+++ b/scm-core/src/test/java/sonia/scm/security/DAORealmHelperTest.java
@@ -1,20 +1,16 @@
package sonia.scm.security;
-import com.google.common.collect.ImmutableList;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.PrincipalCollection;
-import org.junit.Ignore;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
-import sonia.scm.group.Group;
import sonia.scm.group.GroupDAO;
-import sonia.scm.group.GroupNames;
import sonia.scm.user.User;
import sonia.scm.user.UserDAO;
@@ -38,7 +34,7 @@ class DAORealmHelperTest {
@BeforeEach
void setUpObjectUnderTest() {
- helper = new DAORealmHelper(loginAttemptHandler, userDAO, new GroupCollector(groupDAO), "hitchhiker");
+ helper = new DAORealmHelper(loginAttemptHandler, userDAO, "hitchhiker");
}
@Test
@@ -73,29 +69,9 @@ class DAORealmHelperTest {
AuthenticationInfo authenticationInfo = helper.authenticationInfoBuilder("trillian").build();
PrincipalCollection principals = authenticationInfo.getPrincipals();
assertThat(principals.oneByType(User.class)).isSameAs(user);
- assertThat(principals.oneByType(GroupNames.class)).containsOnly("_authenticated");
assertThat(principals.oneByType(Scope.class)).isEmpty();
}
- @Test
- @Ignore
- void shouldReturnAuthenticationInfoWithGroups() {
- User user = new User("trillian");
- when(userDAO.get("trillian")).thenReturn(user);
-
- Group one = new Group("xml", "one", "trillian");
- Group two = new Group("xml", "two", "trillian");
- Group six = new Group("xml", "six", "dent");
- when(groupDAO.getAll()).thenReturn(ImmutableList.of(one, two, six));
-
- AuthenticationInfo authenticationInfo = helper.authenticationInfoBuilder("trillian")
- .withGroups(ImmutableList.of("three"))
- .build();
-
- PrincipalCollection principals = authenticationInfo.getPrincipals();
- assertThat(principals.oneByType(GroupNames.class)).containsOnly("_authenticated", "one", "two", "three");
- }
-
@Test
void shouldReturnAuthenticationInfoWithScope() {
User user = new User("trillian");
@@ -148,7 +124,6 @@ class DAORealmHelperTest {
PrincipalCollection principals = authenticationInfo.getPrincipals();
assertThat(principals.oneByType(User.class)).isSameAs(user);
- assertThat(principals.oneByType(GroupNames.class)).containsOnly("_authenticated");
assertThat(principals.oneByType(Scope.class)).isEmpty();
assertThat(authenticationInfo.getCredentials()).isNull();
diff --git a/scm-core/src/test/java/sonia/scm/security/GroupCollectorTest.java b/scm-core/src/test/java/sonia/scm/security/GroupCollectorTest.java
deleted file mode 100644
index 3fb59d1614..0000000000
--- a/scm-core/src/test/java/sonia/scm/security/GroupCollectorTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package sonia.scm.security;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import sonia.scm.group.Group;
-import sonia.scm.group.GroupDAO;
-import sonia.scm.group.GroupNames;
-
-import java.util.Collections;
-import java.util.List;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.when;
-
-@ExtendWith(MockitoExtension.class)
-class GroupCollectorTest {
-
- @Mock
- private GroupDAO groupDAO;
-
- @InjectMocks
- private GroupCollector collector;
-
- @Test
- void shouldAlwaysReturnAuthenticatedGroup() {
- GroupNames groupNames = collector.collect("trillian", Collections.emptySet());
- assertThat(groupNames).containsOnly("_authenticated");
- }
-
- @Nested
- class WithGroupsFromDao {
-
- @BeforeEach
- void setUpGroupsDao() {
- List groups = Lists.newArrayList(
- new Group("xml", "heartOfGold", "trillian"),
- new Group("xml", "g42", "dent", "prefect"),
- new Group("xml", "fjordsOfAfrican", "dent", "trillian")
- );
- when(groupDAO.getAll()).thenReturn(groups);
- }
-
- @Test
- void shouldReturnGroupsFromDao() {
- GroupNames groupNames = collector.collect("trillian", Collections.emptySet());
- assertThat(groupNames).contains("_authenticated", "heartOfGold", "fjordsOfAfrican");
- }
-
- @Test
- void shouldCombineGivenWithDao() {
- GroupNames groupNames = collector.collect("trillian", ImmutableList.of("awesome", "incredible"));
- assertThat(groupNames).contains("_authenticated", "heartOfGold", "fjordsOfAfrican", "awesome", "incredible");
- }
-
- }
-
-}
diff --git a/scm-core/src/test/java/sonia/scm/security/SyncingRealmHelperTest.java b/scm-core/src/test/java/sonia/scm/security/SyncingRealmHelperTest.java
index 20d1010b57..ca7c2efdc6 100644
--- a/scm-core/src/test/java/sonia/scm/security/SyncingRealmHelperTest.java
+++ b/scm-core/src/test/java/sonia/scm/security/SyncingRealmHelperTest.java
@@ -36,31 +36,30 @@ package sonia.scm.security;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.base.Throwables;
-import com.google.common.collect.Lists;
import org.apache.shiro.authc.AuthenticationInfo;
-import org.assertj.core.api.Assertions;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import sonia.scm.AlreadyExistsException;
-import sonia.scm.group.ExternalGroupNames;
import sonia.scm.group.Group;
-import sonia.scm.group.GroupDAO;
import sonia.scm.group.GroupManager;
-import sonia.scm.group.GroupNames;
import sonia.scm.user.User;
import sonia.scm.user.UserManager;
import sonia.scm.web.security.AdministrationContext;
import sonia.scm.web.security.PrivilegedAction;
import java.io.IOException;
-import java.util.List;
import static org.hamcrest.Matchers.hasItem;
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
//~--- JDK imports ------------------------------------------------------------
@@ -78,9 +77,6 @@ public class SyncingRealmHelperTest {
@Mock
private UserManager userManager;
- @Mock
- private GroupDAO groupDAO;
-
private SyncingRealmHelper helper;
/**
@@ -106,7 +102,7 @@ public class SyncingRealmHelperTest {
}
};
- helper = new SyncingRealmHelper(ctx, userManager, groupManager, groupDAO);
+ helper = new SyncingRealmHelper(ctx, userManager, groupManager);
}
/**
@@ -183,67 +179,15 @@ public class SyncingRealmHelperTest {
verify(userManager, times(1)).modify(user);
}
- @Test
- public void builderShouldSetInternalGroups() {
- AuthenticationInfo authenticationInfo = helper
- .authenticationInfo()
- .forRealm("unit-test")
- .andUser(new User("ziltoid"))
- .withGroups("internal")
- .build();
-
- GroupNames groupNames = authenticationInfo.getPrincipals().oneByType(GroupNames.class);
- Assertions.assertThat(groupNames.getCollection()).contains("_authenticated", "internal");
- }
-
- @Test
- public void builderShouldSetExternalGroups() {
- AuthenticationInfo authenticationInfo = helper
- .authenticationInfo()
- .forRealm("unit-test")
- .andUser(new User("ziltoid"))
- .withExternalGroups("external")
- .build();
-
- ExternalGroupNames groupNames = authenticationInfo.getPrincipals().oneByType(ExternalGroupNames.class);
- Assertions.assertThat(groupNames.getCollection()).containsOnly("external");
- }
@Test
public void builderShouldSetValues() {
User user = new User("ziltoid");
- AuthenticationInfo authInfo = helper
- .authenticationInfo()
- .forRealm("unit-test")
- .andUser(user)
- .build();
+ AuthenticationInfo authInfo = helper.createAuthenticationInfo("unit-test", user);
assertNotNull(authInfo);
assertEquals("ziltoid", authInfo.getPrincipals().getPrimaryPrincipal());
assertThat(authInfo.getPrincipals().getRealmNames(), hasItem("unit-test"));
assertEquals(user, authInfo.getPrincipals().oneByType(User.class));
}
-
- @Test
- public void shouldReturnCombinedGroupNames() {
- User user = new User("tricia");
-
- List groups = Lists.newArrayList(new Group("xml", "heartOfGold", "tricia"));
- when(groupDAO.getAll()).thenReturn(groups);
-
- AuthenticationInfo authInfo = helper
- .authenticationInfo()
- .forRealm("unit-test")
- .andUser(user)
- .withGroups("fjordsOfAfrican")
- .withExternalGroups("g42")
- .build();
-
-
- GroupNames groupNames = authInfo.getPrincipals().oneByType(GroupNames.class);
- Assertions.assertThat(groupNames).contains("_authenticated", "heartOfGold", "fjordsOfAfrican");
-
- ExternalGroupNames externalGroupNames = authInfo.getPrincipals().oneByType(ExternalGroupNames.class);
- Assertions.assertThat(externalGroupNames).contains("g42");
- }
}
diff --git a/scm-webapp/src/test/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilterTest.java b/scm-core/src/test/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilterBaseTest.java
similarity index 91%
rename from scm-webapp/src/test/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilterTest.java
rename to scm-core/src/test/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilterBaseTest.java
index ff493e2b84..1f9b4fad07 100644
--- a/scm-webapp/src/test/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilterTest.java
+++ b/scm-core/src/test/java/sonia/scm/web/filter/HttpProtocolServletAuthenticationFilterBaseTest.java
@@ -23,7 +23,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
-class HttpProtocolServletAuthenticationFilterTest {
+class HttpProtocolServletAuthenticationFilterBaseTest {
private ScmConfiguration configuration = new ScmConfiguration();
@@ -32,7 +32,7 @@ class HttpProtocolServletAuthenticationFilterTest {
@Mock
private UserAgentParser userAgentParser;
- private HttpProtocolServletAuthenticationFilter authenticationFilter;
+ private HttpProtocolServletAuthenticationFilterBase authenticationFilter;
@Mock
private HttpServletRequest request;
@@ -48,7 +48,7 @@ class HttpProtocolServletAuthenticationFilterTest {
@BeforeEach
void setUpObjectUnderTest() {
- authenticationFilter = new HttpProtocolServletAuthenticationFilter(configuration, tokenGenerators, userAgentParser);
+ authenticationFilter = new HttpProtocolServletAuthenticationFilterBase(configuration, tokenGenerators, userAgentParser);
}
@Test
diff --git a/scm-core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/scm-core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
new file mode 100644
index 0000000000..1f0955d450
--- /dev/null
+++ b/scm-core/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
@@ -0,0 +1 @@
+mock-maker-inline
diff --git a/scm-dao-xml/src/test/resources/sonia/scm/store/repositoryDaoMetadata.xml b/scm-dao-xml/src/test/resources/sonia/scm/store/repositoryDaoMetadata.xml
index 87aa3775ea..a9e84994dc 100644
--- a/scm-dao-xml/src/test/resources/sonia/scm/store/repositoryDaoMetadata.xml
+++ b/scm-dao-xml/src/test/resources/sonia/scm/store/repositoryDaoMetadata.xml
@@ -5,6 +5,5 @@
spaceexistingfalse
- falsexml
diff --git a/scm-it/src/test/java/sonia/scm/it/utils/TestData.java b/scm-it/src/test/java/sonia/scm/it/utils/TestData.java
index 20de47ffa4..c7d97a6891 100644
--- a/scm-it/src/test/java/sonia/scm/it/utils/TestData.java
+++ b/scm-it/src/test/java/sonia/scm/it/utils/TestData.java
@@ -123,23 +123,6 @@ public class TestData {
;
}
- public static void createUserPermission(String username, String roleName, String repositoryType) {
- String defaultPermissionUrl = TestData.getDefaultPermissionUrl(USER_SCM_ADMIN, USER_SCM_ADMIN, repositoryType);
- LOG.info("create permission with name {} and role {} using the endpoint: {}", username, roleName, defaultPermissionUrl);
- given(VndMediaType.REPOSITORY_PERMISSION)
- .when()
- .content("{\n" +
- "\t\"role\": " + roleName + ",\n" +
- "\t\"name\": \"" + username + "\",\n" +
- "\t\"groupPermission\": false\n" +
- "\t\n" +
- "}")
- .post(defaultPermissionUrl)
- .then()
- .statusCode(HttpStatus.SC_CREATED)
- ;
- }
-
public static List