diff --git a/scm-core/src/main/java/sonia/scm/boot/RestartEvent.java b/scm-core/src/main/java/sonia/scm/boot/RestartEvent.java
new file mode 100644
index 0000000000..244bc8f03c
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/boot/RestartEvent.java
@@ -0,0 +1,96 @@
+/**
+ * Copyright (c) 2014, 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.boot;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import sonia.scm.Stage;
+import sonia.scm.event.Event;
+
+/**
+ * This event can be used to force a restart of the webapp context. The restart
+ * event is useful during plugin development, because we don't have to restart
+ * the whole server, to see our changes. The restart event can only be used in
+ * stage {@link Stage#DEVELOPMENT}.
+ *
+ * @author Sebastian Sdorra
+ * @since 2.0.0
+ */
+@Event
+public class RestartEvent
+{
+
+ /**
+ * Constructs ...
+ *
+ *
+ * @param cause
+ * @param reason
+ */
+ public RestartEvent(Class> cause, String reason)
+ {
+ this.cause = cause;
+ this.reason = reason;
+ }
+
+ //~--- get methods ----------------------------------------------------------
+
+ /**
+ * The class which has fired the restart event.
+ *
+ *
+ * @return class which has fired the restart event
+ */
+ public Class> getCause()
+ {
+ return cause;
+ }
+
+ /**
+ * Returns the reason for the restart.
+ *
+ *
+ * @return reason for restart
+ */
+ public String getReason()
+ {
+ return reason;
+ }
+
+ //~--- fields ---------------------------------------------------------------
+
+ /** cause of restart */
+ private final Class> cause;
+
+ /** reason for restart */
+ private final String reason;
+}
diff --git a/scm-webapp/src/main/java/sonia/scm/boot/BootstrapContextFilter.java b/scm-webapp/src/main/java/sonia/scm/boot/BootstrapContextFilter.java
new file mode 100644
index 0000000000..bfa2218e76
--- /dev/null
+++ b/scm-webapp/src/main/java/sonia/scm/boot/BootstrapContextFilter.java
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2014, 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.boot;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import com.github.legman.Subscribe;
+
+import com.google.inject.servlet.GuiceFilter;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import sonia.scm.SCMContext;
+import sonia.scm.Stage;
+import sonia.scm.event.ScmEventBus;
+
+//~--- JDK imports ------------------------------------------------------------
+
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletException;
+
+/**
+ *
+ * @author Sebastian Sdorra
+ */
+public class BootstrapContextFilter extends GuiceFilter
+{
+
+ /**
+ * the logger for BootstrapContextFilter
+ */
+ private static final Logger logger =
+ LoggerFactory.getLogger(BootstrapContextFilter.class);
+
+ //~--- methods --------------------------------------------------------------
+
+ /**
+ * Restart the whole webapp context.
+ *
+ *
+ * @param event restart event
+ *
+ * @throws ServletException
+ */
+ @Subscribe(async = false)
+ public void handleRestartEvent(RestartEvent event) throws ServletException
+ {
+ logger.warn("received restart event from {} with reason: {}",
+ event.getCause(), event.getReason());
+
+ if (filterConfig == null)
+ {
+ logger.error("filter config is null, scm-manager is not initialized");
+ }
+ else
+ {
+
+ logger.warn(
+ "destroy filter pipeline, because of a received restart event");
+ destroy();
+ logger.warn(
+ "reinitialize filter pipeline, because of a received restart event");
+ super.init(filterConfig);
+ }
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param filterConfig
+ *
+ * @throws ServletException
+ */
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException
+ {
+ this.filterConfig = filterConfig;
+ super.init(filterConfig);
+
+ if (SCMContext.getContext().getStage() == Stage.DEVELOPMENT)
+ {
+ logger.info("register for restart events");
+ ScmEventBus.getInstance().register(this);
+ }
+ }
+
+ //~--- fields ---------------------------------------------------------------
+
+ /** Field description */
+ private FilterConfig filterConfig;
+}
diff --git a/scm-webapp/src/main/java/sonia/scm/boot/BootstrapContextListener.java b/scm-webapp/src/main/java/sonia/scm/boot/BootstrapContextListener.java
index 96f1a3748e..4f7a00ce56 100644
--- a/scm-webapp/src/main/java/sonia/scm/boot/BootstrapContextListener.java
+++ b/scm-webapp/src/main/java/sonia/scm/boot/BootstrapContextListener.java
@@ -33,15 +33,20 @@ package sonia.scm.boot;
//~--- non-JDK imports --------------------------------------------------------
+import com.github.legman.Subscribe;
+
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableList;
import com.google.common.io.Files;
+import com.google.inject.servlet.GuiceFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.SCMContext;
import sonia.scm.ScmContextListener;
+import sonia.scm.Stage;
+import sonia.scm.event.ScmEventBus;
import sonia.scm.plugin.Plugin;
import sonia.scm.plugin.PluginException;
import sonia.scm.plugin.PluginLoadException;
@@ -128,6 +133,7 @@ public class BootstrapContextListener implements ServletContextListener
}
}
+ context = null;
contextListener = null;
}
@@ -140,7 +146,8 @@ public class BootstrapContextListener implements ServletContextListener
@Override
public void contextInitialized(ServletContextEvent sce)
{
- ServletContext context = sce.getServletContext();
+ context = sce.getServletContext();
+
PluginIndex index = readCorePluginIndex(context);
File pluginDirectory = getPluginDirectory();
@@ -163,6 +170,42 @@ public class BootstrapContextListener implements ServletContextListener
}
contextListener.contextInitialized(sce);
+
+ // register for restart events
+ if (!registered
+ && (SCMContext.getContext().getStage() == Stage.DEVELOPMENT))
+ {
+ logger.info("register for restart events");
+ ScmEventBus.getInstance().register(this);
+ registered = true;
+ }
+ }
+
+ /**
+ * Restart the whole webapp context.
+ *
+ *
+ * @param event restart event
+ */
+ @Subscribe
+ public void handleRestartEvent(RestartEvent event)
+ {
+ logger.warn("received restart event from {} with reason: {}",
+ event.getCause(), event.getReason());
+
+ if (context == null)
+ {
+ logger.error("context is null, scm-manager is not initialized");
+ }
+ else
+ {
+ ServletContextEvent sce = new ServletContextEvent(context);
+
+ logger.warn("destroy context, because of a received restart event");
+ contextDestroyed(sce);
+ logger.warn("reinitialize context, because of a received restart event");
+ contextInitialized(sce);
+ }
}
/**
@@ -391,6 +434,12 @@ public class BootstrapContextListener implements ServletContextListener
//~--- fields ---------------------------------------------------------------
+ /** Field description */
+ private ServletContext context;
+
/** Field description */
private ScmContextListener contextListener;
+
+ /** Field description */
+ private boolean registered = false;
}
diff --git a/scm-webapp/src/main/webapp/WEB-INF/web.xml b/scm-webapp/src/main/webapp/WEB-INF/web.xml
index 97ea5d8b32..fb906270a4 100644
--- a/scm-webapp/src/main/webapp/WEB-INF/web.xml
+++ b/scm-webapp/src/main/webapp/WEB-INF/web.xml
@@ -48,12 +48,12 @@
- guiceFilter
- com.google.inject.servlet.GuiceFilter
+ BootstrapFilter
+ sonia.scm.boot.BootstrapContextFilter
- guiceFilter
+ BootstrapFilter
/*