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 22911041d4..b669cb63fa 100644 --- a/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java +++ b/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java @@ -70,8 +70,6 @@ public class PluginInformation implements PermissionObject, Validateable, Clonea private String author; private String category; private String avatarUrl; - private PluginCondition condition; - private PluginState state; @Override public PluginInformation clone() { @@ -83,10 +81,6 @@ public class PluginInformation implements PermissionObject, Validateable, Clonea clone.setAuthor(author); clone.setCategory(category); clone.setAvatarUrl(avatarUrl); - clone.setState(state); - if (condition != null) { - clone.setCondition(condition.clone()); - } return clone; } 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 5443b2328d..0000000000 --- a/scm-core/src/main/java/sonia/scm/plugin/PluginInformationComparator.java +++ /dev/null @@ -1,101 +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.getName(), other.getName()); - - 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 f674bdd2ba..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) { @@ -245,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 @@ -412,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/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 d7f4ecf515..07e182216f 100644 --- a/scm-core/src/test/java/sonia/scm/plugin/SmpArchiveTest.java +++ b/scm-core/src/test/java/sonia/scm/plugin/SmpArchiveTest.java @@ -113,7 +113,7 @@ public class SmpArchiveTest public void testGetPlugin() throws IOException { File archive = createArchive("sonia.sample", "1.0"); - Plugin plugin = SmpArchive.create(archive).getPlugin(); + InstalledPluginDescriptor plugin = SmpArchive.create(archive).getPlugin(); assertNotNull(plugin); diff --git a/scm-ui-components/packages/ui-components/src/CardColumn.js b/scm-ui-components/packages/ui-components/src/CardColumn.js index 65710c7be2..713e1bced3 100644 --- a/scm-ui-components/packages/ui-components/src/CardColumn.js +++ b/scm-ui-components/packages/ui-components/src/CardColumn.js @@ -46,7 +46,8 @@ type Props = { contentRight?: React.Node, footerLeft: React.Node, footerRight: React.Node, - link: string, + link?: string, + action?: () => void, // context props classes: any @@ -54,9 +55,11 @@ type Props = { class CardColumn extends React.Component { createLink = () => { - const { link } = this.props; + const { link, action } = this.props; if (link) { return ; + } else if (action) { + return {e.preventDefault(); action();}} href="#" />; } return null; }; diff --git a/scm-ui-components/packages/ui-components/src/buttons/ButtonGroup.js b/scm-ui-components/packages/ui-components/src/buttons/ButtonGroup.js index 2dcb56047c..b73688ebbf 100644 --- a/scm-ui-components/packages/ui-components/src/buttons/ButtonGroup.js +++ b/scm-ui-components/packages/ui-components/src/buttons/ButtonGroup.js @@ -14,7 +14,7 @@ class ButtonGroup extends React.Component { const childWrapper = []; React.Children.forEach(children, child => { if (child) { - childWrapper.push(

{child}

); + childWrapper.push(

{child}

); } }); diff --git a/scm-ui-components/packages/ui-types/src/Plugin.js b/scm-ui-components/packages/ui-types/src/Plugin.js index 3f4f9858c1..0114716757 100644 --- a/scm-ui-components/packages/ui-types/src/Plugin.js +++ b/scm-ui-components/packages/ui-types/src/Plugin.js @@ -1,7 +1,6 @@ //@flow import type {Collection, Links} from "./hal"; - export type Plugin = { name: string, version: string, @@ -10,6 +9,8 @@ export type Plugin = { author: string, category: string, avatarUrl: string, + pending: boolean, + dependencies: string[], _links: Links }; diff --git a/scm-ui/public/locales/de/admin.json b/scm-ui/public/locales/de/admin.json index 54ae1ab91a..20a1e0a004 100644 --- a/scm-ui/public/locales/de/admin.json +++ b/scm-ui/public/locales/de/admin.json @@ -29,7 +29,23 @@ "installedNavLink": "Installiert", "availableNavLink": "Verfügbar" }, - "noPlugins": "Keine Plugins gefunden." + "installPending": "Austehende Plugins installieren", + "noPlugins": "Keine Plugins gefunden.", + "modal": { + "title": "{{name}} Plugin installieren", + "restart": "Neustarten um Plugin zu aktivieren", + "install": "Installieren", + "installAndRestart": "Installieren und Neustarten", + "abort": "Abbrechen", + "author": "Autor", + "version": "Version", + "dependencyNotification": "Mit diesem Plugin werden folgende Abhängigkeiten mit installieren wenn sie noch nicht vorhanden sind!", + "dependencies": "Abhängigkeiten", + "successNotification": "Das Plugin wurde erfolgreich installiert. Um Änderungen an der UI zu sehen, muss die Seite neu geladen werden:", + "reload": "jetzt new laden", + "restartNotification": "Der SCM-Manager Kontext sollte nur neu gestartet werden, wenn aktuell niemand damit arbeitet.", + "installPending": "Die folgenden Plugins werden installiert und anschließend wir der SCM-Manager Kontext neu gestartet." + } }, "repositoryRole": { "navLink": "Berechtigungsrollen", diff --git a/scm-ui/public/locales/en/admin.json b/scm-ui/public/locales/en/admin.json index 2402f21423..2c9304ac85 100644 --- a/scm-ui/public/locales/en/admin.json +++ b/scm-ui/public/locales/en/admin.json @@ -6,7 +6,7 @@ "settingsNavLink": "Settings", "generalNavLink": "General" }, - "info": { + "info": { "currentAppVersion": "Current Application Version", "communityTitle": "Community Support", "communityIconAlt": "Community Support Icon", @@ -29,7 +29,23 @@ "installedNavLink": "Installed", "availableNavLink": "Available" }, - "noPlugins": "No plugins found." + "installPending": "Install pending plugins", + "noPlugins": "No plugins found.", + "modal": { + "title": "Install {{name}} Plugin", + "restart": "Restart to activate", + "install": "Install", + "installAndRestart": "Install and Restart", + "abort": "Abort", + "author": "Author", + "version": "Version", + "dependencyNotification": "With this plugin, the following dependencies are installed if they are not available yet!", + "dependencies": "Dependencies", + "successNotification": "Successful installed plugin. You have to reload the page, to see ui changes:", + "reload": "reload now", + "restartNotification": "Restarting the scm-manager context, should only be done if no one else is currently working with it.", + "installPending": "The following plugins will be installed and after installation the scm-manager context will be restarted." + } }, "repositoryRole": { "navLink": "Permission Roles", @@ -53,7 +69,7 @@ "permissions": "Permissions", "submit": "Save" }, - "delete" : { + "delete": { "button": "Löschen", "subtitle": "Berechtigungsrolle löschen", "confirmAlert": { diff --git a/scm-ui/src/admin/plugins/components/InstallPendingAction.js b/scm-ui/src/admin/plugins/components/InstallPendingAction.js new file mode 100644 index 0000000000..49a444de11 --- /dev/null +++ b/scm-ui/src/admin/plugins/components/InstallPendingAction.js @@ -0,0 +1,68 @@ +// @flow +import React from "react"; +import { Button } from "@scm-manager/ui-components"; +import type { PluginCollection } from "@scm-manager/ui-types"; +import { translate } from "react-i18next"; +import InstallPendingModal from "./InstallPendingModal"; + +type Props = { + collection: PluginCollection, + + // context props + t: string => string +}; + +type State = { + showModal: boolean +}; + +class InstallPendingAction extends React.Component { + constructor(props: Props) { + super(props); + this.state = { + showModal: false + }; + } + + openModal = () => { + this.setState({ + showModal: true + }); + }; + + closeModal = () => { + this.setState({ + showModal: false + }); + }; + + renderModal = () => { + const { showModal } = this.state; + const { collection } = this.props; + if (showModal) { + return ( + + ); + } + return null; + }; + + render() { + const { t } = this.props; + return ( + <> + {this.renderModal()} +