bug 357814: Applies patch contributed by Stefan Zugal
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/Snap.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/Snap.java
index 189bc61..d39f124 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/Snap.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/Snap.java
@@ -30,4 +30,6 @@
String getContextPath();
Properties getSnapProperties();
+
+ void addHost(Host host);
}
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapFactoryMonitor.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapFactoryMonitor.java
index 11fcf9e..7318365 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapFactoryMonitor.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapFactoryMonitor.java
@@ -162,26 +162,32 @@
Bundle hostBundle = hostReference.getBundle();
- SnapLifecycleState newState = SnapLifecycleState.INIT_FAILED;
-
- Snap snap = this.factory.createSnap(new Host(hostBundle, servletContext, new RequestRouter(this.snapRegistry, servletContext)));
- try {
- logger.info("Initializing snap '{}'", snap.getContextPath());
- snap.init();
-
- newState = SnapLifecycleState.INIT_SUCCEEDED;
-
- logger.info("Publishing snap '{}'", snap.getContextPath());
- publishSnapService(snap, hostBundle);
-
- } catch (ServletException e) {
- this.eventLogger.log(SnapsLogEvents.SNAP_INIT_FAILURE, SnapUtils.boundContextPath(servletContext.getContextPath(), snap.getContextPath()));
- } finally {
- synchronized (this.snapStateMonitor) {
- if (newState == SnapLifecycleState.INIT_SUCCEEDED) {
- this.snap = snap;
- }
- }
+ Host host = new Host(hostBundle, servletContext, new RequestRouter(this.snapRegistry, servletContext));
+
+ synchronized (this.snapStateMonitor) {
+ if (this.factory.hasSnap()) {
+ Snap snap = this.factory.getSnap();
+ snap.addHost(host);
+ publishSnapService(snap, hostBundle);
+ } else {
+ SnapLifecycleState newState = SnapLifecycleState.INIT_FAILED;
+ Snap snap = this.factory.createSnap(host);
+ try {
+ logger.info("Initializing snap '{}'", snap.getContextPath());
+ snap.init();
+
+ newState = SnapLifecycleState.INIT_SUCCEEDED;
+
+ logger.info("Publishing snap '{}'", snap.getContextPath());
+ publishSnapService(snap, hostBundle);
+ } catch (ServletException e) {
+ this.eventLogger.log(SnapsLogEvents.SNAP_INIT_FAILURE, SnapUtils.boundContextPath(servletContext.getContextPath(), snap.getContextPath()));
+ } finally {
+ if (newState == SnapLifecycleState.INIT_SUCCEEDED) {
+ this.snap = snap;
+ }
+ }
+ }
}
}
}
@@ -217,7 +223,11 @@
private void unregisterHostListener() {
logger.info("No longer listening for hosts to be registered.");
- this.context.removeServiceListener(this);
+ try {
+ this.context.removeServiceListener(this);
+ } catch (IllegalStateException e) {
+ logger.warn("Could not remove host listener. Reason: " + e.getMessage());
+ }
}
public void serviceChanged(ServiceEvent event) {
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapHostDefinition.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapHostDefinition.java
index e84df10..c6374f5 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapHostDefinition.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapHostDefinition.java
@@ -11,19 +11,20 @@
package org.eclipse.virgo.snaps.core.internal;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import org.eclipse.virgo.snaps.core.internal.deployer.SnapFactory;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import org.eclipse.virgo.util.osgi.manifest.VersionRange;
import org.eclipse.virgo.util.osgi.manifest.parse.HeaderDeclaration;
import org.eclipse.virgo.util.osgi.manifest.parse.HeaderParser;
import org.eclipse.virgo.util.osgi.manifest.parse.HeaderParserFactory;
import org.eclipse.virgo.util.osgi.manifest.parse.ParserLogger;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public final class SnapHostDefinition {
@@ -46,18 +47,22 @@
return this.versionRange;
}
- public static SnapHostDefinition parse(String descriptor) {
+ public static Set<SnapHostDefinition> parse(String descriptor) {
HeaderParser parser = createHeaderParser();
List<HeaderDeclaration> header = parser.parseHeader(descriptor);
- if (header == null || header.size() != 1) {
+ if (header == null) {
logger.error("Invalid Snap-Host header '{}'", descriptor);
throw new IllegalArgumentException("Invalid Snap-Host header '" + descriptor + "'");
}
- HeaderDeclaration declaration = header.get(0);
- String factoryName = declaration.getNames().get(0);
- String rangeString = declaration.getAttributes().get(Constants.VERSION_ATTRIBUTE);
- return createSnapHostDefinition(factoryName, rangeString);
+ Set<SnapHostDefinition> hostDefinitions = new HashSet<SnapHostDefinition>();
+ for (HeaderDeclaration declaration:header) {
+ String factoryName = declaration.getNames().get(0);
+ String rangeString = declaration.getAttributes().get(Constants.VERSION_ATTRIBUTE);
+ hostDefinitions.add(createSnapHostDefinition(factoryName, rangeString));
+ }
+
+ return hostDefinitions;
}
public static SnapHostDefinition fromServiceReference(ServiceReference<SnapFactory> snapFactoryReference) {
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapUtils.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapUtils.java
index 2db87b3..664a1be 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapUtils.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/SnapUtils.java
@@ -11,11 +11,12 @@
package org.eclipse.virgo.snaps.core.internal;
+import java.util.Set;
+
import javax.servlet.http.HttpServletRequest;
-import org.osgi.framework.Bundle;
-
import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
+import org.osgi.framework.Bundle;
public final class SnapUtils {
@@ -48,7 +49,7 @@
return manifest.getHeader(HEADER_SNAP_HOST) != null;
}
- public static SnapHostDefinition getSnapHostHeader(BundleManifest manifest) {
+ public static Set<SnapHostDefinition> getSnapHostHeader(BundleManifest manifest) {
String header = manifest.getHeader(HEADER_SNAP_HOST);
return (header == null ? null : SnapHostDefinition.parse(header));
}
@@ -62,7 +63,7 @@
}
/**
- * Catenate the host and snap context paths, <i>unless</i> host context path ends with a path separator.<br/>
+ * Concatenate the host and snap context paths, <i>unless</i> host context path ends with a path separator.<br/>
* <code>null</code> {@link String}s are converted to the empty string <code>""</code>.
* @param hostContextPath the host context path
* @param snapContextPath the snap context path
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapFactory.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapFactory.java
index 03de854..4572303 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapFactory.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapFactory.java
@@ -16,9 +16,13 @@
public interface SnapFactory {
- static final String FACTORY_NAME_PROPERTY = "snap.factory.host.name";
+ String FACTORY_NAME_PROPERTY = "snap.factory.host.name";
- static final String FACTORY_RANGE_PROPERTY = "snap.factory.host.range";
+ String FACTORY_RANGE_PROPERTY = "snap.factory.host.range";
Snap createSnap(Host host);
+
+ boolean hasSnap();
+
+ Snap getSnap();
}
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapLifecycleListener.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapLifecycleListener.java
index 1fb702d..ef186d6 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapLifecycleListener.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapLifecycleListener.java
@@ -13,28 +13,29 @@
import java.io.IOException;
import java.util.Dictionary;
+import java.util.HashSet;
import java.util.Hashtable;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import org.eclipse.gemini.web.tomcat.spi.WebBundleClassLoaderFactory;
+import org.eclipse.virgo.kernel.install.artifact.BundleInstallArtifact;
+import org.eclipse.virgo.kernel.install.artifact.InstallArtifact;
+import org.eclipse.virgo.kernel.install.artifact.InstallArtifactLifecycleListenerSupport;
+import org.eclipse.virgo.medic.eventlog.EventLogger;
+import org.eclipse.virgo.nano.deployer.api.core.DeploymentException;
+import org.eclipse.virgo.nano.shim.scope.Scope;
import org.eclipse.virgo.snaps.core.internal.SnapHostDefinition;
import org.eclipse.virgo.snaps.core.internal.SnapUtils;
import org.eclipse.virgo.snaps.core.internal.webapp.WebAppSnapFactory;
+import org.eclipse.virgo.util.osgi.ServiceRegistrationTracker;
+import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.eclipse.virgo.nano.deployer.api.core.DeploymentException;
-import org.eclipse.virgo.kernel.install.artifact.BundleInstallArtifact;
-import org.eclipse.virgo.kernel.install.artifact.InstallArtifact;
-import org.eclipse.virgo.kernel.install.artifact.InstallArtifactLifecycleListenerSupport;
-import org.eclipse.virgo.nano.shim.scope.Scope;
-import org.eclipse.virgo.medic.eventlog.EventLogger;
-import org.eclipse.gemini.web.tomcat.spi.WebBundleClassLoaderFactory;
-import org.eclipse.virgo.util.osgi.ServiceRegistrationTracker;
-import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
-
/**
* <strong>Concurrent Semantics</strong><br />
* Thread-safe.
@@ -64,28 +65,36 @@
Bundle bundle = ((BundleInstallArtifact) installArtifact).getBundle();
BundleManifest bundleManifest = getBundleManifest((BundleInstallArtifact) installArtifact);
- ServiceRegistration<SnapFactory> registration = createAndRegisterSnapFactoryService(bundle, bundleManifest);
+ Set<ServiceRegistration<SnapFactory>> registrations = createAndRegisterSnapFactoryService(bundle, bundleManifest);
- ServiceRegistrationTracker registrationTracker = new ServiceRegistrationTracker();
- registrationTracker.track(registration);
+ for (ServiceRegistration<SnapFactory> registration:registrations) {
+ ServiceRegistrationTracker registrationTracker = new ServiceRegistrationTracker();
+ registrationTracker.track(registration);
- this.registrationTrackers.put(installArtifact, registrationTracker);
+ this.registrationTrackers.put(installArtifact, registrationTracker);
+ }
}
}
- ServiceRegistration<SnapFactory> createAndRegisterSnapFactoryService(Bundle bundle, BundleManifest bundleManifest) {
+ Set<ServiceRegistration<SnapFactory>> createAndRegisterSnapFactoryService(Bundle bundle, BundleManifest bundleManifest) {
logger.info("Creating a SnapFactory for bundle '{}'", bundle);
SnapFactory snapFactory = new WebAppSnapFactory(bundle, this.classLoaderFactory, this.eventLogger);
- SnapHostDefinition hostDefinition = SnapUtils.getSnapHostHeader(bundleManifest);
+ Set<SnapHostDefinition> hostDefinitions = SnapUtils.getSnapHostHeader(bundleManifest);
- Dictionary<String, String> serviceProperties= new Hashtable<String, String>();
- serviceProperties.put(Scope.PROPERTY_SERVICE_SCOPE, Scope.SCOPE_ID_GLOBAL); // expose service outside any containing scope
- serviceProperties.put(SnapFactory.FACTORY_NAME_PROPERTY, hostDefinition.getSymbolicName());
- serviceProperties.put(SnapFactory.FACTORY_RANGE_PROPERTY, hostDefinition.getVersionRange().toParseString());
+ Set<ServiceRegistration<SnapFactory>> registrations = new HashSet<ServiceRegistration<SnapFactory>>();
+
+ for (SnapHostDefinition hostDefinition : hostDefinitions) {
+ Dictionary<String, String> serviceProperties= new Hashtable<String, String>();
+ serviceProperties.put(Scope.PROPERTY_SERVICE_SCOPE, Scope.SCOPE_ID_GLOBAL); // expose service outside any containing scope
+ serviceProperties.put(SnapFactory.FACTORY_NAME_PROPERTY, hostDefinition.getSymbolicName());
+ serviceProperties.put(SnapFactory.FACTORY_RANGE_PROPERTY, hostDefinition.getVersionRange().toParseString());
- ServiceRegistration<SnapFactory> registration = bundle.getBundleContext().registerService(SnapFactory.class, snapFactory, serviceProperties);
- return registration;
+ ServiceRegistration<SnapFactory> registration = bundle.getBundleContext().registerService(SnapFactory.class, snapFactory, serviceProperties);
+ registrations.add(registration);
+ }
+
+ return registrations;
}
static BundleManifest getBundleManifest(BundleInstallArtifact bundleInstallArtifact) throws DeploymentException {
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/WebAppSnap.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/WebAppSnap.java
index 173720b..e63f3af 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/WebAppSnap.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/WebAppSnap.java
@@ -85,7 +85,7 @@
*
* @throws ServletException
*/
- public final void init() throws ServletException {
+ public synchronized final void init() throws ServletException {
logger.info("Initializing snap '{}'", this.contextPath);
WebXml webXml = BundleWebXmlLoader.loadWebXml(this.snapBundle);
SnapServletContext servletContext = new SnapServletContext(this.host.getServletContext(), this.snapBundle, this.contextPath);
@@ -179,4 +179,15 @@
}
return properties;
}
+
+ @Override
+ public synchronized void addHost(Host host) {
+ logger.info("Adding host '{}' to snap '{}'", host.getBundle(), this.contextPath);
+ SnapServletContext servletContext = new SnapServletContext(host.getServletContext(), this.snapBundle, this.contextPath);
+ servletContext.setAttribute(WebContainer.ATTRIBUTE_BUNDLE_CONTEXT, this.snapBundle.getBundleContext());
+
+ this.virtualContainer.addHost(servletContext);
+
+ this.eventLogger.log(SnapsLogEvents.SNAP_BOUND, SnapUtils.boundContextPath(host.getServletContext().getContextPath(), this.contextPath));
+ }
}
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/WebAppSnapFactory.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/WebAppSnapFactory.java
index dfde7c8..d8bb9ef 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/WebAppSnapFactory.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/WebAppSnapFactory.java
@@ -31,6 +31,8 @@
private final EventLogger eventLogger;
+ private WebAppSnap webAppSnap;
+
public WebAppSnapFactory(Bundle snapBundle, WebBundleClassLoaderFactory webBundleClassLoaderFactory, EventLogger eventLogger) {
this.snapBundle = snapBundle;
this.classLoaderFactory = webBundleClassLoaderFactory;
@@ -39,7 +41,18 @@
public Snap createSnap(Host host) {
logger.info("Creating new snap that binds snap bundle '{}' to host bundle '{}'", this.snapBundle, host.getBundle());
- return new WebAppSnap(host, this.snapBundle, this.classLoaderFactory, this.eventLogger);
+ webAppSnap = new WebAppSnap(host, this.snapBundle, this.classLoaderFactory, this.eventLogger);
+ return webAppSnap;
}
+
+ @Override
+ public boolean hasSnap() {
+ return this.webAppSnap != null;
+ }
+
+ @Override
+ public Snap getSnap() {
+ return webAppSnap;
+ }
}
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/FilterManager.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/FilterManager.java
index bb16747..edbbfc8 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/FilterManager.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/FilterManager.java
@@ -37,8 +37,8 @@
class FilterManager {
- private final SnapServletContext snapServletContext;
-
+ private final List<SnapServletContext> snapServletContexts = new ArrayList<>();
+
private final ClassLoader classLoader;
private final List<FilterHolder> filters = Collections.synchronizedList(new ArrayList<FilterHolder>());
@@ -47,22 +47,28 @@
private final List<ServletNameFilterMapping> servletNameFilterMappings = Collections.synchronizedList(new ArrayList<ServletNameFilterMapping>());
+ private WebXml webXml;
+
+ private Map<String, FilterHolder> filtersMap;
+
public FilterManager(WebXml webXml, SnapServletContext snapServletContext, ClassLoader classLoader) {
- this.snapServletContext = snapServletContext;
+ this.webXml = webXml;
+ this.snapServletContexts.add(snapServletContext);
this.classLoader = classLoader;
- reifyWebXml(webXml);
+ this.filtersMap = processFilters();
+ reifyWebXml(snapServletContext);
}
- private void reifyWebXml(WebXml webXml) {
- Map<String, FilterHolder> filters = processFilters(webXml);
- processFilterMappings(webXml, filters);
- }
+ private void reifyWebXml(SnapServletContext snapServletContext) {
+ processUrlPatternFilterMappings(snapServletContext);
+ processServletNameFilterMappings();
+ }
- private Map<String, FilterHolder> processFilters(WebXml webXml) throws SnapException {
+ private Map<String, FilterHolder> processFilters() throws SnapException {
Map<String, FilterHolder> filtersMap = new HashMap<String, FilterHolder>();
- for (FilterDefinition filterDefinition : webXml.getFilterDefinitions()) {
+ for (FilterDefinition filterDefinition : this.webXml.getFilterDefinitions()) {
try {
Class<?> filterClass = ManagerUtils.loadComponentClass(filterDefinition.getFilterClassName(), this.classLoader);
if (Filter.class.isAssignableFrom(filterClass)) {
@@ -86,24 +92,26 @@
return filtersMap;
}
- private void processFilterMappings(WebXml webXml, Map<String, FilterHolder> filters) throws SnapException {
- for (UrlPatternFilterMappingDefinition definition : webXml.getUrlPatternFilterMappingDefinitions()) {
- Filter filter = filters.get(definition.getFilterName()).getInstance();
- this.urlPatternFilterMappings.add(new UrlPatternFilterMapping(filter, ManagerUtils.expandMapping(definition.getUrlPattern(), this.snapServletContext), definition.getFilterDispatcherTypes()));
- }
-
- for (ServletNameFilterMappingDefinition definition : webXml.getServletNameFilterMappingDefinitions()) {
- Filter filter = filters.get(definition.getFilterName()).getInstance();
- this.servletNameFilterMappings.add(new ServletNameFilterMapping(filter, definition.getServletName(), definition.getFilterDispatcherTypes()));
+ private void processUrlPatternFilterMappings(SnapServletContext snapServletContext) throws SnapException {
+ for (UrlPatternFilterMappingDefinition definition : this.webXml.getUrlPatternFilterMappingDefinitions()) {
+ Filter filter = this.filtersMap.get(definition.getFilterName()).getInstance();
+ this.urlPatternFilterMappings.add(new UrlPatternFilterMapping(filter, ManagerUtils.expandMapping(definition.getUrlPattern(), snapServletContext), definition.getFilterDispatcherTypes()));
}
}
+
+ private void processServletNameFilterMappings() {
+ for (ServletNameFilterMappingDefinition definition : this.webXml.getServletNameFilterMappingDefinitions()) {
+ Filter filter = this.filtersMap.get(definition.getFilterName()).getInstance();
+ this.servletNameFilterMappings.add(new ServletNameFilterMapping(filter, definition.getServletName(), definition.getFilterDispatcherTypes()));
+ }
+ }
void init() throws ServletException {
try {
ManagerUtils.doWithThreadContextClassLoader(this.classLoader, new ClassLoaderCallback<Void>() {
public Void doWithClassLoader() throws ServletException {
for (FilterHolder filterHolder : filters) {
- FilterConfig config = new ImmutableFilterConfig(filterHolder.getDefinition(), snapServletContext);
+ FilterConfig config = new ImmutableFilterConfig(filterHolder.getDefinition(), snapServletContexts.get(0));
try {
filterHolder.getInstance().init(config);
} catch (ServletException se) {
@@ -187,4 +195,9 @@
return this.dispatcherTypes.contains(dispatcherType) && this.servletName.equals(servletName);
}
}
+
+ public void addSnapServletContext(SnapServletContext snapServletContext) {
+ this.snapServletContexts.add(snapServletContext);
+ processUrlPatternFilterMappings(snapServletContext);
+ }
}
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/ServletManager.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/ServletManager.java
index 9f49f74..c168168 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/ServletManager.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/ServletManager.java
@@ -12,6 +12,8 @@
package org.eclipse.virgo.snaps.core.internal.webapp.container;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -45,19 +47,22 @@
private final Logger logger = LoggerFactory.getLogger(this.getClass());
- private final SnapServletContext snapServletContext;
+ private final List<SnapServletContext> snapServletContexts = new ArrayList<>();
private final ClassLoader classLoader;
private final UrlPatternMatcher patternMatcher = new UrlPatternMatcher();
private final Map<String, ServletHolder> servlets = new ConcurrentHashMap<String, ServletHolder>();
+
+ private WebXml webXml;
ServletManager(WebXml webXml, SnapServletContext snapServletContext, ClassLoader classLoader) {
- this.snapServletContext = snapServletContext;
+ this.webXml = webXml;
+ this.snapServletContexts.add(snapServletContext);
this.classLoader = classLoader;
- reifyWebXml(webXml);
+ reifyWebXml(snapServletContext);
}
void init() throws ServletException {
@@ -67,7 +72,7 @@
public Void doWithClassLoader() throws ServletException {
for (Map.Entry<String, ServletHolder> entry : servlets.entrySet()) {
ServletHolder holder = entry.getValue();
- ServletConfig config = new ImmutableServletConfig(holder.getDefinition(), snapServletContext);
+ ServletConfig config = new ImmutableServletConfig(holder.getDefinition(), snapServletContexts.get(0));
holder.getInstance().init(config);
// TODO Log which servlet failed, and re-throw
}
@@ -98,13 +103,13 @@
}
}
- private void reifyWebXml(WebXml webXml) {
- processServlets(webXml);
- processServletMappingDefinitions(webXml);
+ private void reifyWebXml(SnapServletContext snapServletContext) {
+ processServlets();
+ processServletMappingDefinitions(snapServletContext);
}
- private void processServlets(WebXml webXml) throws SnapException {
- for (ServletDefinition servletDefinition : webXml.getServletDefinitions()) {
+ private void processServlets( ) throws SnapException {
+ for (ServletDefinition servletDefinition : this.webXml.getServletDefinitions()) {
try {
Class<?> servletClass = ManagerUtils.loadComponentClass(servletDefinition.getServletClassName(), this.classLoader);
Servlet servlet = (Servlet) servletClass.newInstance();
@@ -126,10 +131,10 @@
}
}
- private void processServletMappingDefinitions(WebXml webXml) {
- for (ServletMappingDefinition mappingDefinition : webXml.getServletMappingDefinitions()) {
+ private void processServletMappingDefinitions(SnapServletContext snapServletContext) {
+ for (ServletMappingDefinition mappingDefinition : this.webXml.getServletMappingDefinitions()) {
this.patternMatcher.addMapping(mappingDefinition.getServletName(), ManagerUtils.expandMapping(mappingDefinition.getUrlPattern(),
- this.snapServletContext));
+ snapServletContext));
// TODO Validate, probably in WebXml, the referenced servlets exist, etc.
}
}
@@ -159,4 +164,9 @@
return mapping;
}
}
+
+ public void addSnapServletContext(SnapServletContext snapServletContext) {
+ this.snapServletContexts.add(snapServletContext);
+ processServletMappingDefinitions(snapServletContext);
+ }
}
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/SnapHttpSession.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/SnapHttpSession.java
index fde835d..05b2c6e 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/SnapHttpSession.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/SnapHttpSession.java
@@ -23,6 +23,9 @@
public final class SnapHttpSession extends HttpSessionWrapper {
private static final String QUALIFIED_NAME_MARKER = "##";
+
+ // This constant should have the same value as within org.springframework.aop.scope.ScopedProxyUtils
+ private static final String TARGET_NAME_PREFIX = "scopedTarget.";
private final SnapServletContext snapServletContext;
@@ -48,11 +51,17 @@
@Override
public void removeAttribute(String name) {
super.removeAttribute(qualifyName(name));
+ if (name.startsWith(TARGET_NAME_PREFIX)) {
+ super.removeAttribute(name);
+ }
}
@Override
public void setAttribute(String name, Object value) {
super.setAttribute(qualifyName(name), value);
+ if (name.startsWith(TARGET_NAME_PREFIX)) {
+ super.setAttribute(name, value);
+ }
}
@Override
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/StandardVirtualContainer.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/StandardVirtualContainer.java
index e9bdbae..15d4205 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/StandardVirtualContainer.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/StandardVirtualContainer.java
@@ -93,4 +93,10 @@
public SnapServletContext getSnapServletContext() {
return this.snapServletContext;
}
+
+ @Override
+ public void addHost(SnapServletContext servletContext) {
+ this.servletManager.addSnapServletContext(servletContext);
+ this.filterManager.addSnapServletContext(servletContext);
+ }
}
diff --git a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/VirtualContainer.java b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/VirtualContainer.java
index ba0e4ee..a15c433 100644
--- a/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/VirtualContainer.java
+++ b/org.eclipse.virgo.snaps.core/src/main/java/org/eclipse/virgo/snaps/core/internal/webapp/container/VirtualContainer.java
@@ -36,4 +36,6 @@
VirtualContainerRequestDispatcher createDispatcher();
SnapServletContext getSnapServletContext();
+
+ void addHost(SnapServletContext servletContext);
}
diff --git a/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapFactoryMonitorTests.java b/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapFactoryMonitorTests.java
index 627c4d3..218244d 100644
--- a/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapFactoryMonitorTests.java
+++ b/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapFactoryMonitorTests.java
@@ -69,13 +69,13 @@
SnapFactory factory = createMock(SnapFactory.class);
expect(factory.createSnap(isA(Host.class))).andReturn(snap);
+ expect(factory.hasSnap()).andReturn(Boolean.FALSE);
replay(factory, snap);
publishFactory(factory, "travel", "[1.0, 2.0)");
assertSnapPublished("/hotels", host);
verify(factory, snap);
-
}
@Test
@@ -90,6 +90,7 @@
SnapFactory factory = createMock(SnapFactory.class);
expect(factory.createSnap(isA(Host.class))).andReturn(snap);
+ expect(factory.hasSnap()).andReturn(Boolean.FALSE);
publishFactory(factory, "travel", "[1.0, 2.0)");
replay(factory, snap);
@@ -129,6 +130,7 @@
SnapFactory factory = createMock(SnapFactory.class);
expect(factory.createSnap(isA(Host.class))).andReturn(snap);
+ expect(factory.hasSnap()).andReturn(Boolean.FALSE);
replay(factory, snap);
publishFactory(factory, "travel", "[1.0, 3.0)");
@@ -149,6 +151,7 @@
SnapFactory factory = createMock(SnapFactory.class);
expect(factory.createSnap(isA(Host.class))).andReturn(snap);
+ expect(factory.hasSnap()).andReturn(Boolean.FALSE);
publishFactory(factory, "travel", "[1.0, 2.0)");
replay(factory, snap);
@@ -222,6 +225,7 @@
final SnapFactory factory = createMock(SnapFactory.class);
expect(factory.createSnap(isA(Host.class))).andReturn(slice);
+ expect(factory.hasSnap()).andReturn(Boolean.FALSE);
replay(factory, slice);
// public snap factory bound to "clinic" host
diff --git a/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapHostDefinitionTests.java b/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapHostDefinitionTests.java
index 5dea8c0..15ac663 100644
--- a/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapHostDefinitionTests.java
+++ b/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapHostDefinitionTests.java
@@ -11,32 +11,52 @@
package org.eclipse.virgo.snaps.core.internal;
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.*;
-import org.eclipse.virgo.snaps.core.internal.SnapHostDefinition;
-import org.junit.Test;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
import org.eclipse.virgo.util.osgi.manifest.VersionRange;
+import org.junit.Test;
public class SnapHostDefinitionTests {
@Test
public void testStandard() {
- SnapHostDefinition def = SnapHostDefinition.parse("travel;version=\"[1.2, 1.3)\"");
- assertEquals("travel", def.getSymbolicName());
- assertEquals(new VersionRange("[1.2, 1.3)"), def.getVersionRange());
+ Set<SnapHostDefinition> definitions = SnapHostDefinition.parse("travel;version=\"[1.2, 1.3)\"");
+ assertEquals(1, definitions.size());
+
+ SnapHostDefinition definition = definitions.iterator().next();
+ assertEquals("travel", definition.getSymbolicName());
+ assertEquals(new VersionRange("[1.2, 1.3)"), definition.getVersionRange());
}
- @Test
- public void testWithoutRange() {
- SnapHostDefinition def = SnapHostDefinition.parse("travel");
- assertEquals("travel", def.getSymbolicName());
- assertEquals(VersionRange.NATURAL_NUMBER_RANGE, def.getVersionRange());
- }
+ @Test
+ public void testWithoutRange() {
+ Set<SnapHostDefinition> definitions = SnapHostDefinition.parse("travel");
+ assertEquals(1, definitions.size());
+
+ SnapHostDefinition definition = definitions.iterator().next();
+ assertEquals("travel", definition.getSymbolicName());
+ assertEquals(VersionRange.NATURAL_NUMBER_RANGE, definition.getVersionRange());
+ }
- @Test(expected=IllegalArgumentException.class)
- public void testInvalid() {
- SnapHostDefinition.parse("travel,hotels");
- }
+ @Test
+ public void testMultiple() throws Exception {
+ Set<SnapHostDefinition> definitions = SnapHostDefinition.parse("travel,ski;version=\"[1.4, 2)\"");
+
+ Map<String, VersionRange> expected = new HashMap<>();
+ expected.put("travel", VersionRange.NATURAL_NUMBER_RANGE);
+ expected.put("ski", new VersionRange("[1.4, 2)"));
+ assertEquals(expected.size(), definitions.size());
+
+ for (SnapHostDefinition host : definitions) {
+ VersionRange expectedRange = expected.get(host.getSymbolicName());
+
+ assertNotNull("Could not find a header for " + host.getSymbolicName(), expectedRange);
+ assertEquals(expectedRange, host.getVersionRange());
+ }
+ }
}
diff --git a/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapUtilsTests.java b/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapUtilsTests.java
index b83c413..fe40385 100644
--- a/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapUtilsTests.java
+++ b/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/SnapUtilsTests.java
@@ -23,15 +23,13 @@
import java.util.Dictionary;
import java.util.Hashtable;
+import java.util.Set;
-import org.eclipse.virgo.snaps.core.internal.SnapHostDefinition;
-import org.eclipse.virgo.snaps.core.internal.SnapUtils;
+import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
import org.junit.Test;
import org.osgi.framework.Bundle;
import org.springframework.mock.web.MockHttpServletRequest;
-import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
-
public class SnapUtilsTests {
@Test
@@ -84,9 +82,11 @@
expect(manifest.getHeader(SnapUtils.HEADER_SNAP_HOST)).andReturn("travel;version=\"[1.2, 1.3)\"");
replay(manifest);
- SnapHostDefinition header = SnapUtils.getSnapHostHeader(manifest);
+ Set<SnapHostDefinition> header = SnapUtils.getSnapHostHeader(manifest);
+ assertEquals(1, header.size());
+
assertNotNull(header);
- assertEquals("travel", header.getSymbolicName());
+ assertEquals("travel", header.iterator().next().getSymbolicName());
verify(manifest);
}
@@ -96,7 +96,7 @@
expect(manifest.getHeader(SnapUtils.HEADER_SNAP_HOST)).andReturn(null);
replay(manifest);
- SnapHostDefinition header = SnapUtils.getSnapHostHeader(manifest);
+ Set<SnapHostDefinition> header = SnapUtils.getSnapHostHeader(manifest);
assertNull(header);
verify(manifest);
}
diff --git a/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapLifecycleListenerTests.java b/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapLifecycleListenerTests.java
index 2e6c7d8..876c469 100644
--- a/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapLifecycleListenerTests.java
+++ b/org.eclipse.virgo.snaps.core/src/test/java/org/eclipse/virgo/snaps/core/internal/deployer/SnapLifecycleListenerTests.java
@@ -18,20 +18,17 @@
import java.io.IOException;
-import org.eclipse.virgo.snaps.core.internal.deployer.SnapFactory;
-import org.eclipse.virgo.snaps.core.internal.deployer.SnapLifecycleListener;
-import org.junit.Test;
-import org.osgi.framework.Version;
-
-import org.eclipse.virgo.nano.deployer.api.core.DeploymentException;
+import org.eclipse.gemini.web.tomcat.spi.WebBundleClassLoaderFactory;
import org.eclipse.virgo.kernel.install.artifact.BundleInstallArtifact;
import org.eclipse.virgo.medic.test.eventlog.MockEventLogger;
+import org.eclipse.virgo.nano.deployer.api.core.DeploymentException;
import org.eclipse.virgo.test.stubs.framework.OSGiAssert;
import org.eclipse.virgo.test.stubs.framework.StubBundle;
import org.eclipse.virgo.test.stubs.framework.StubBundleContext;
-import org.eclipse.gemini.web.tomcat.spi.WebBundleClassLoaderFactory;
import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
import org.eclipse.virgo.util.osgi.manifest.internal.StandardBundleManifest;
+import org.junit.Test;
+import org.osgi.framework.Version;
public class SnapLifecycleListenerTests {
@@ -65,4 +62,5 @@
verify(installArtifact, classLoaderFactory);
}
+
}