summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorS.W <wimmesberger@gmail.com>2019-06-27 09:58:37 +0200
committerZhe Sun <31067185+ZheSun88@users.noreply.github.com>2019-06-27 10:58:36 +0300
commit583920f327c338a020d4e09e420548f44127cb7f (patch)
tree4319908dd2887bd780fb89a64d79c7690721c252
parent4c4d0375c1efdf5d943ee2112bdd2160e0045af7 (diff)
downloadvaadin-framework-583920f327c338a020d4e09e420548f44127cb7f.tar.gz
vaadin-framework-583920f327c338a020d4e09e420548f44127cb7f.zip
OSGi: Removed static VaadinResourceService access in liferay-integration, osgi-integration (#11335)
* Made VaadinResourceService a OSGi component, removed static access of OsgiVaadinResources
-rw-r--r--liferay-integration/src/main/java/com/vaadin/osgi/liferay/VaadinPortletProvider.java25
-rw-r--r--osgi-integration/src/main/java/com/vaadin/osgi/servlet/VaadinServletRegistration.java115
-rw-r--r--pom.xml2
-rw-r--r--server/src/main/java/com/vaadin/server/osgi/BootstrapContribution.java4
-rw-r--r--shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinResources.java41
-rw-r--r--shared/src/main/java/com/vaadin/osgi/resources/VaadinResourceService.java15
-rw-r--r--shared/src/main/java/com/vaadin/osgi/resources/impl/VaadinResourceServiceImpl.java72
-rw-r--r--shared/src/main/java/com/vaadin/osgi/resources/impl/VaadinResourceTrackerComponent.java313
-rw-r--r--shared/src/main/java/com/vaadin/osgi/resources/impl/VaadinServletContextFactory.java61
9 files changed, 418 insertions, 230 deletions
diff --git a/liferay-integration/src/main/java/com/vaadin/osgi/liferay/VaadinPortletProvider.java b/liferay-integration/src/main/java/com/vaadin/osgi/liferay/VaadinPortletProvider.java
index cb5f6cfa1b..0bdab7b480 100644
--- a/liferay-integration/src/main/java/com/vaadin/osgi/liferay/VaadinPortletProvider.java
+++ b/liferay-integration/src/main/java/com/vaadin/osgi/liferay/VaadinPortletProvider.java
@@ -17,7 +17,6 @@ package com.vaadin.osgi.liferay;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceObjects;
-import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
@@ -26,7 +25,6 @@ import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.log.LogService;
import org.osgi.util.tracker.ServiceTracker;
-import com.vaadin.osgi.resources.OsgiVaadinResources;
import com.vaadin.osgi.resources.VaadinResourceService;
import com.vaadin.ui.UI;
@@ -45,19 +43,28 @@ public class VaadinPortletProvider {
private ServiceTracker<UI, ServiceObjects<UI>> serviceTracker;
private PortletUIServiceTrackerCustomizer portletUIServiceTrackerCustomizer;
+ private VaadinResourceService vaadinService;
private LogService logService;
@Activate
- void activate(ComponentContext componentContext) throws Exception {
- BundleContext bundleContext = componentContext.getBundleContext();
- VaadinResourceService service = OsgiVaadinResources.getService();
-
+ void activate(BundleContext bundleContext) throws Exception {
portletUIServiceTrackerCustomizer = new PortletUIServiceTrackerCustomizer(
- service, logService);
+ vaadinService, logService);
serviceTracker = new ServiceTracker<UI, ServiceObjects<UI>>(
bundleContext, UI.class, portletUIServiceTrackerCustomizer);
serviceTracker.open();
}
+
+ @Reference
+ void setVaadinResourceService(VaadinResourceService vaadinService) {
+ this.vaadinService = vaadinService;
+ }
+
+ void unsetVaadinResourceService(VaadinResourceService vaadinService) {
+ if(this.vaadinService == vaadinService) {
+ this.vaadinService = null;
+ }
+ }
@Reference(cardinality = ReferenceCardinality.OPTIONAL)
void setLogService(LogService logService) {
@@ -65,7 +72,9 @@ public class VaadinPortletProvider {
}
void unsetLogService(LogService logService) {
- this.logService = null;
+ if(this.logService == logService) {
+ this.logService = null;
+ }
}
@Deactivate
diff --git a/osgi-integration/src/main/java/com/vaadin/osgi/servlet/VaadinServletRegistration.java b/osgi-integration/src/main/java/com/vaadin/osgi/servlet/VaadinServletRegistration.java
index d331edf7bb..013ec65f05 100644
--- a/osgi-integration/src/main/java/com/vaadin/osgi/servlet/VaadinServletRegistration.java
+++ b/osgi-integration/src/main/java/com/vaadin/osgi/servlet/VaadinServletRegistration.java
@@ -19,6 +19,7 @@ import java.util.Collections;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.Map;
+import java.util.Objects;
import javax.servlet.Servlet;
import javax.servlet.annotation.WebServlet;
@@ -26,6 +27,7 @@ import javax.servlet.annotation.WebServlet;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
@@ -33,8 +35,6 @@ import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
import org.osgi.service.log.LogService;
-import com.vaadin.osgi.resources.OsgiVaadinResources;
-import com.vaadin.osgi.resources.OsgiVaadinResources.ResourceBundleInactiveException;
import com.vaadin.osgi.resources.VaadinResourceService;
import com.vaadin.server.Constants;
import com.vaadin.server.VaadinServlet;
@@ -50,9 +50,6 @@ import com.vaadin.server.VaadinServlet;
*/
@Component
public class VaadinServletRegistration {
- private final Map<ServiceReference<VaadinServlet>, ServiceRegistration<Servlet>> registeredServlets = Collections
- .synchronizedMap(new LinkedHashMap<>());
-
private static final String MISSING_ANNOTATION_MESSAGE_FORMAT = "The property '%s' must be set in a '%s' without the '%s' annotation!";
private static final String URL_PATTERNS_NOT_SET_MESSAGE_FORMAT = "The property '%s' must be set when the 'urlPatterns' attribute is not set!";
@@ -61,11 +58,22 @@ public class VaadinServletRegistration {
private static final String VAADIN_RESOURCES_PARAM = HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX
+ Constants.PARAMETER_VAADIN_RESOURCES;
+ private final Map<ServiceReference<VaadinServlet>, ServletRegistration> registeredServlets = Collections
+ .synchronizedMap(new LinkedHashMap<>());
+ private VaadinResourceService vaadinService;
private LogService logService;
+ @Activate
+ void activate(BundleContext bundleContext) throws Exception {
+ // see if we have registrations already which are not initialized
+ for(ServletRegistration registration : registeredServlets.values()) {
+ registration.register(vaadinService);
+ }
+ }
+
@Reference(cardinality = ReferenceCardinality.MULTIPLE, service = VaadinServlet.class, policy = ReferencePolicy.DYNAMIC)
- void bindVaadinServlet(VaadinServlet servlet, ServiceReference<VaadinServlet> reference)
- throws ResourceBundleInactiveException {
+ void bindVaadinServlet(VaadinServlet servlet,
+ ServiceReference<VaadinServlet> reference) {
log(LogService.LOG_INFO, "VaadinServlet Registration");
Hashtable<String, Object> properties = getProperties(reference);
@@ -77,20 +85,17 @@ public class VaadinServletRegistration {
return;
}
- properties.put(VAADIN_RESOURCES_PARAM, getResourcePath());
if (annotation != null) {
properties.put(
HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ASYNC_SUPPORTED,
Boolean.toString(annotation.asyncSupported()));
}
- // We register the Http Whiteboard servlet using the context of
- // the bundle which registered the Vaadin Servlet, not our own
- BundleContext bundleContext = reference.getBundle().getBundleContext();
- ServiceRegistration<Servlet> servletRegistration = bundleContext
- .registerService(Servlet.class, servlet, properties);
-
- registeredServlets.put(reference, servletRegistration);
+ ServletRegistration registration = new ServletRegistration(servlet,
+ reference, properties);
+ registeredServlets.put(reference, registration);
+ // try to register with the vaadin service - the service could be null at this point but we handle that in the register method
+ registration.register(this.vaadinService);
}
private boolean validateSettings(WebServlet annotation,
@@ -112,11 +117,6 @@ public class VaadinServletRegistration {
return true;
}
- private String getResourcePath() throws ResourceBundleInactiveException {
- VaadinResourceService service = OsgiVaadinResources.getService();
- return String.format("/%s", service.getResourcePathPrefix());
- }
-
private void log(int level, String message) {
if (logService != null) {
logService.log(level, message);
@@ -124,17 +124,21 @@ public class VaadinServletRegistration {
}
void unbindVaadinServlet(ServiceReference<VaadinServlet> reference) {
- ServiceRegistration<?> servletRegistration = registeredServlets
+ ServletRegistration servletRegistration = registeredServlets
.remove(reference);
if (servletRegistration != null) {
- try {
- servletRegistration.unregister();
- } catch (IllegalStateException ise) {
- // This service may have already been unregistered
- // automatically by the OSGi framework if the
- // application bundle is being stopped. This is
- // obviously not a problem for us.
- }
+ servletRegistration.unregister();
+ }
+ }
+
+ @Reference
+ void setVaadinResourceService(VaadinResourceService vaadinService) {
+ this.vaadinService = vaadinService;
+ }
+
+ void unsetVaadinResourceService(VaadinResourceService vaadinService) {
+ if (this.vaadinService == vaadinService) {
+ this.vaadinService = null;
}
}
@@ -144,7 +148,9 @@ public class VaadinServletRegistration {
}
void unsetLogService(LogService logService) {
- this.logService = null;
+ if (this.logService == logService) {
+ this.logService = null;
+ }
}
private Hashtable<String, Object> getProperties(
@@ -155,4 +161,53 @@ public class VaadinServletRegistration {
}
return properties;
}
+
+ private static class ServletRegistration {
+ private final VaadinServlet servlet;
+ private final ServiceReference<VaadinServlet> servletRef;
+ private final Hashtable<String, Object> properties;
+
+ private volatile ServiceRegistration<Servlet> registration;
+
+ public ServletRegistration(VaadinServlet servlet,
+ ServiceReference<VaadinServlet> servletRef,
+ Hashtable<String, Object> properties) {
+ this.servlet = Objects.requireNonNull(servlet);
+ this.servletRef = Objects.requireNonNull(servletRef);
+ this.properties = properties;
+ }
+
+ public void register(VaadinResourceService vaadinService) {
+ // we are already registered
+ if (this.registration != null)
+ return;
+ // only register if the vaadin service is not null
+ if(vaadinService == null)
+ return;
+
+ final String resourcePath = String.format("/%s", vaadinService.getResourcePathPrefix());
+ this.properties.put(VAADIN_RESOURCES_PARAM, resourcePath);
+ // We register the Http Whiteboard servlet using the context of
+ // the bundle which registered the Vaadin Servlet, not our own
+ BundleContext bundleContext = this.servletRef.getBundle()
+ .getBundleContext();
+ this.registration = bundleContext.registerService(Servlet.class,
+ servlet, properties);
+ }
+
+ public void unregister() {
+ //we are already deregistered
+ if (this.registration == null)
+ return;
+ try {
+ this.registration.unregister();
+ } catch (IllegalStateException ise) {
+ // This service may have already been unregistered
+ // automatically by the OSGi framework if the
+ // application bundle is being stopped. This is
+ // obviously not a problem for us.
+ }
+ this.registration = null;
+ }
+ }
}
diff --git a/pom.xml b/pom.xml
index 555b9b8a2f..a9c0a9b761 100644
--- a/pom.xml
+++ b/pom.xml
@@ -43,7 +43,7 @@
<osgi.version>6.0.0</osgi.version>
<osgi.annotation.version>6.0.1</osgi.annotation.version>
- <bnd.version>3.3.0</bnd.version>
+ <bnd.version>3.5.0</bnd.version>
<!-- Dependency unpack directory -->
<dependency.unpack.directory>${project.build.directory}/dependency-unpack</dependency.unpack.directory>
diff --git a/server/src/main/java/com/vaadin/server/osgi/BootstrapContribution.java b/server/src/main/java/com/vaadin/server/osgi/BootstrapContribution.java
index 17e2e711e6..62b6d55967 100644
--- a/server/src/main/java/com/vaadin/server/osgi/BootstrapContribution.java
+++ b/server/src/main/java/com/vaadin/server/osgi/BootstrapContribution.java
@@ -39,8 +39,8 @@ public class BootstrapContribution implements OsgiVaadinContributor {
public List<OsgiVaadinResource> getContributions() {
final List<OsgiVaadinResource> contributions = new ArrayList<>(
RESOURCES.length);
- for (final String theme : RESOURCES) {
- contributions.add(OsgiVaadinResource.create(theme));
+ for (final String resource : RESOURCES) {
+ contributions.add(OsgiVaadinResource.create(resource));
}
return contributions;
}
diff --git a/shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinResources.java b/shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinResources.java
index 6f2842d47e..675c33db3f 100644
--- a/shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinResources.java
+++ b/shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinResources.java
@@ -17,9 +17,8 @@ package com.vaadin.osgi.resources;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.Version;
-
-import com.vaadin.osgi.resources.impl.VaadinResourceServiceImpl;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
/**
* {@link BundleActivator} used to provide access to the
@@ -29,6 +28,8 @@ import com.vaadin.osgi.resources.impl.VaadinResourceServiceImpl;
* @author Vaadin Ltd.
*
* @since 8.1
+ * @deprecated use OSGi DS services to bind a instance of
+ * {@link VaadinResourceService}
*/
public class OsgiVaadinResources implements BundleActivator {
@@ -48,8 +49,8 @@ public class OsgiVaadinResources implements BundleActivator {
private static OsgiVaadinResources instance;
- private VaadinResourceServiceImpl service;
- private Version version;
+ private ServiceTracker<VaadinResourceService, VaadinResourceService> vaadinResourceTracker;
+ private VaadinResourceService service;
/**
* Returns the {@link VaadinResourceService} instance. Always returns
@@ -71,16 +72,38 @@ public class OsgiVaadinResources implements BundleActivator {
@Override
public void start(BundleContext context) throws Exception {
- version = context.getBundle().getVersion();
- service = new VaadinResourceServiceImpl();
- service.setBundleVersion(version.toString());
+ vaadinResourceTracker = new ServiceTracker<VaadinResourceService, VaadinResourceService>(
+ context, VaadinResourceService.class, null) {
+ @Override
+ public VaadinResourceService addingService(
+ ServiceReference<VaadinResourceService> reference) {
+ VaadinResourceService vaadinService = super.addingService(
+ reference);
+ service = vaadinService;
+ return vaadinService;
+ }
+
+ @Override
+ public void removedService(
+ ServiceReference<VaadinResourceService> reference,
+ VaadinResourceService service) {
+ super.removedService(reference, service);
+ if (OsgiVaadinResources.this.service == service) {
+ OsgiVaadinResources.this.service = null;
+ }
+ }
+ };
+ vaadinResourceTracker.open();
instance = this;
}
@Override
public void stop(BundleContext context) throws Exception {
+ if (vaadinResourceTracker != null) {
+ vaadinResourceTracker.close();
+ }
+ vaadinResourceTracker = null;
instance = null;
service = null;
- version = null;
}
}
diff --git a/shared/src/main/java/com/vaadin/osgi/resources/VaadinResourceService.java b/shared/src/main/java/com/vaadin/osgi/resources/VaadinResourceService.java
index ee4ff294e0..1568edf563 100644
--- a/shared/src/main/java/com/vaadin/osgi/resources/VaadinResourceService.java
+++ b/shared/src/main/java/com/vaadin/osgi/resources/VaadinResourceService.java
@@ -27,7 +27,6 @@ import org.osgi.service.http.NamespaceException;
* @since 8.1
*/
public interface VaadinResourceService {
-
/**
* Register the theme with the given name under the
* {@link VaadinResourceService} versioned namespace. The theme folder is
@@ -38,6 +37,7 @@ public interface VaadinResourceService {
* "/vaadin-x.x.x/VAADIN/themes/themeName" where x.x.x is the version of the
* Vaadin Shared bundle
*
+ * @deprecated use OSGi DS services and register a {@link OsgiVaadinTheme}
* @param themeName
* the name of the theme
* @param httpService
@@ -45,6 +45,7 @@ public interface VaadinResourceService {
* @throws NamespaceException
* if there is a clash during the theme registration
*/
+ @Deprecated
void publishTheme(String themeName, HttpService httpService)
throws NamespaceException;
@@ -56,6 +57,8 @@ public interface VaadinResourceService {
* The resource will become accessible under the url "/vaadin-x.x.x/VAADIN/"
* where x.x.x is the version of the Vaadin Shared bundle
*
+ * @deprecated use OSGi DS services and register a
+ * {@link OsgiVaadinResource}
* @param resourceName
* the name of the resource
* @param httpService
@@ -63,6 +66,7 @@ public interface VaadinResourceService {
* @throws NamespaceException
* if there is a clash during the theme registration
*/
+ @Deprecated
void publishResource(String resourceName, HttpService httpService)
throws NamespaceException;
@@ -75,6 +79,8 @@ public interface VaadinResourceService {
* "/vaadin-x.x.x/VAADIN/widgetsets" where x.x.x is the version of the
* Vaadin Shared bundle
*
+ * @deprecated use OSGi DS services and register a
+ * {@link OsgiVaadinWidgetset}
* @param widgetsetName
* the name of the resource
* @param httpService
@@ -82,6 +88,7 @@ public interface VaadinResourceService {
* @throws NamespaceException
* if there is a clash during the theme registration
*/
+ @Deprecated
void publishWidgetset(String widgetsetName, HttpService httpService)
throws NamespaceException;
@@ -94,4 +101,10 @@ public interface VaadinResourceService {
*/
String getResourcePathPrefix();
+ /**
+ * Returns the http servlet context name of Vaadin
+ *
+ * @return the context name
+ */
+ String getContextName();
}
diff --git a/shared/src/main/java/com/vaadin/osgi/resources/impl/VaadinResourceServiceImpl.java b/shared/src/main/java/com/vaadin/osgi/resources/impl/VaadinResourceServiceImpl.java
index 6ada30f7b3..6bda191681 100644
--- a/shared/src/main/java/com/vaadin/osgi/resources/impl/VaadinResourceServiceImpl.java
+++ b/shared/src/main/java/com/vaadin/osgi/resources/impl/VaadinResourceServiceImpl.java
@@ -15,8 +15,19 @@
*/
package com.vaadin.osgi.resources.impl;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.Version;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.http.HttpService;
import org.osgi.service.http.NamespaceException;
+import org.osgi.service.http.context.ServletContextHelper;
+import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
import com.vaadin.osgi.resources.VaadinResourceService;
@@ -28,26 +39,36 @@ import com.vaadin.osgi.resources.VaadinResourceService;
*
* @since 8.1
*/
+@Component
public class VaadinResourceServiceImpl implements VaadinResourceService {
private static final String NAMESPACE_PREFIX = "vaadin-%s";
-
- private String bundleVersion;
+ // it's best practice to select a own context "namespace"
+ private static final String CONTEXT_NAME = "com.vaadin";
private String pathPrefix;
+ private ServiceRegistration<ServletContextHelper> servletContextReg;
- /**
- * Sets the version of the bundle managing this service.
- *
- * <p>
- * This needs to be called before any other method after the service is
- * created.
- *
- * @param bundleVersion
- * the version of the bundle managing this service
- */
- public void setBundleVersion(String bundleVersion) {
- this.bundleVersion = bundleVersion;
- pathPrefix = String.format(NAMESPACE_PREFIX, bundleVersion);
+ @Activate
+ public void start(BundleContext context) throws Exception {
+ Version version = context.getBundle().getVersion();
+ this.setBundleVersion(version.toString());
+
+ // register the vaadin servlet context helper
+ Dictionary<String, String> contextProps = new Hashtable<>();
+ contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME,
+ this.getContextName());
+ contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH,
+ "/" + this.getResourcePathPrefix());
+ servletContextReg = context.registerService(ServletContextHelper.class,
+ new VaadinServletContextFactory(), contextProps);
+ }
+
+ @Deactivate
+ public void stop() {
+ if (servletContextReg != null) {
+ servletContextReg.unregister();
+ servletContextReg = null;
+ }
}
@Override
@@ -79,6 +100,25 @@ public class VaadinResourceServiceImpl implements VaadinResourceService {
@Override
public String getResourcePathPrefix() {
- return String.format(NAMESPACE_PREFIX, bundleVersion);
+ return this.pathPrefix;
+ }
+
+ @Override
+ public String getContextName() {
+ return CONTEXT_NAME;
+ }
+
+ /**
+ * Sets the version of the bundle managing this service.
+ *
+ * <p>
+ * This needs to be called before any other method after the service is
+ * created.
+ *
+ * @param bundleVersion
+ * the version of the bundle managing this service
+ */
+ private void setBundleVersion(String bundleVersion) {
+ this.pathPrefix = String.format(NAMESPACE_PREFIX, bundleVersion);
}
}
diff --git a/shared/src/main/java/com/vaadin/osgi/resources/impl/VaadinResourceTrackerComponent.java b/shared/src/main/java/com/vaadin/osgi/resources/impl/VaadinResourceTrackerComponent.java
index 031b1d1432..26b2a15d4f 100644
--- a/shared/src/main/java/com/vaadin/osgi/resources/impl/VaadinResourceTrackerComponent.java
+++ b/shared/src/main/java/com/vaadin/osgi/resources/impl/VaadinResourceTrackerComponent.java
@@ -15,16 +15,14 @@
*/
package com.vaadin.osgi.resources.impl;
-import java.io.IOException;
-import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import java.util.Objects;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
@@ -37,14 +35,11 @@ import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
-import org.osgi.service.http.HttpContext;
import org.osgi.service.http.HttpService;
-import org.osgi.service.http.NamespaceException;
+import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
import com.vaadin.osgi.resources.OsgiVaadinContributor;
import com.vaadin.osgi.resources.OsgiVaadinResource;
-import com.vaadin.osgi.resources.OsgiVaadinResources;
-import com.vaadin.osgi.resources.OsgiVaadinResources.ResourceBundleInactiveException;
import com.vaadin.osgi.resources.OsgiVaadinTheme;
import com.vaadin.osgi.resources.OsgiVaadinWidgetset;
import com.vaadin.osgi.resources.VaadinResourceService;
@@ -59,93 +54,44 @@ import com.vaadin.osgi.resources.VaadinResourceService;
*/
@Component(immediate = true)
public class VaadinResourceTrackerComponent {
- private final Map<Long, Delegate> resourceToRegistration = Collections
+ private final Map<Long, Delegate<?>> resourceToRegistration = Collections
.synchronizedMap(new LinkedHashMap<>());
private final Map<Long, List<ServiceRegistration<? extends OsgiVaadinResource>>> contributorToRegistrations = Collections
.synchronizedMap(new LinkedHashMap<>());
- private HttpService httpService;
-
- @Reference(cardinality = ReferenceCardinality.MULTIPLE, service = OsgiVaadinTheme.class, policy = ReferencePolicy.DYNAMIC)
- void bindTheme(ServiceReference<OsgiVaadinTheme> themeRef)
- throws ResourceBundleInactiveException, NamespaceException {
-
- Bundle bundle = themeRef.getBundle();
- BundleContext context = bundle.getBundleContext();
- OsgiVaadinTheme theme = context.getService(themeRef);
- if (theme == null) {
- return;
- }
+ private BundleContext vaadinSharedContext;
+ private VaadinResourceService vaadinService;
- VaadinResourceService resourceService = OsgiVaadinResources
- .getService();
- Long serviceId = (Long) themeRef.getProperty(Constants.SERVICE_ID);
- try {
- registerTheme(resourceService, bundle, serviceId, theme);
- } finally {
- context.ungetService(themeRef);
- }
+ @Reference(cardinality = ReferenceCardinality.MULTIPLE, service = OsgiVaadinTheme.class, policy = ReferencePolicy.DYNAMIC)
+ void bindTheme(ServiceReference<OsgiVaadinTheme> themeRef) {
+ registerResource(themeRef);
}
void unbindTheme(ServiceReference<OsgiVaadinTheme> themeRef) {
- Long serviceId = (Long) themeRef.getProperty(Constants.SERVICE_ID);
- unregisterResource(serviceId);
+ unregisterResource(themeRef);
}
@Reference(cardinality = ReferenceCardinality.MULTIPLE, service = OsgiVaadinWidgetset.class, policy = ReferencePolicy.DYNAMIC)
- void bindWidgetset(ServiceReference<OsgiVaadinWidgetset> widgetsetRef)
- throws ResourceBundleInactiveException, NamespaceException {
- Bundle bundle = widgetsetRef.getBundle();
- BundleContext context = bundle.getBundleContext();
-
- OsgiVaadinWidgetset widgetset = context.getService(widgetsetRef);
- if (widgetset == null) {
- return;
- }
-
- VaadinResourceService service = OsgiVaadinResources.getService();
- Long serviceId = (Long) widgetsetRef.getProperty(Constants.SERVICE_ID);
- try {
- registerWidget(service, bundle, serviceId, widgetset);
- } finally {
- context.ungetService(widgetsetRef);
- }
-
+ void bindWidgetset(ServiceReference<OsgiVaadinWidgetset> widgetsetRef) {
+ registerResource(widgetsetRef);
}
void unbindWidgetset(ServiceReference<OsgiVaadinWidgetset> widgetsetRef) {
- Long serviceId = (Long) widgetsetRef.getProperty(Constants.SERVICE_ID);
- unregisterResource(serviceId);
+ unregisterResource(widgetsetRef);
}
@Reference(cardinality = ReferenceCardinality.MULTIPLE, service = OsgiVaadinResource.class, policy = ReferencePolicy.DYNAMIC)
- void bindResource(ServiceReference<OsgiVaadinResource> resourceRef)
- throws ResourceBundleInactiveException, NamespaceException {
- Bundle bundle = resourceRef.getBundle();
- BundleContext context = bundle.getBundleContext();
-
- OsgiVaadinResource resource = context.getService(resourceRef);
- if (resource == null) {
- return;
- }
-
- VaadinResourceService service = OsgiVaadinResources.getService();
- Long serviceId = (Long) resourceRef.getProperty(Constants.SERVICE_ID);
- try {
- registerResource(service, bundle, serviceId, resource);
- } finally {
- context.ungetService(resourceRef);
- }
+ void bindResource(ServiceReference<OsgiVaadinResource> resourceRef) {
+ registerResource(resourceRef);
}
void unbindResource(ServiceReference<OsgiVaadinResource> resourceRef) {
- Long serviceId = (Long) resourceRef.getProperty(Constants.SERVICE_ID);
- unregisterResource(serviceId);
+ unregisterResource(resourceRef);
}
@Reference(cardinality = ReferenceCardinality.MULTIPLE, service = OsgiVaadinContributor.class, policy = ReferencePolicy.DYNAMIC)
- void bindContributor(ServiceReference<OsgiVaadinContributor> contributorRef)
- throws ResourceBundleInactiveException {
+ void bindContributor(
+ ServiceReference<OsgiVaadinContributor> contributorRef) {
Bundle bundle = contributorRef.getBundle();
BundleContext context = bundle.getBundleContext();
@@ -189,23 +135,25 @@ public class VaadinResourceTrackerComponent {
}
@Reference
- void setHttpService(HttpService service) {
- this.httpService = service;
+ void bindVaadinResourceService(VaadinResourceService vaadinService) {
+ this.vaadinService = vaadinService;
}
- void unsetHttpService(HttpService service) {
- this.httpService = null;
+ void unbindVaadinResourceService(VaadinResourceService vaadinService) {
+ if (this.vaadinService == vaadinService) {
+ this.vaadinService = null;
+ }
}
/**
*
- * @throws NamespaceException
* @since 8.6.0
*/
@Activate
- protected void activate() throws NamespaceException {
- for (Delegate registration : resourceToRegistration.values()) {
- registerResource(registration);
+ protected void activate(BundleContext context) {
+ vaadinSharedContext = context;
+ for (Delegate<?> registration : resourceToRegistration.values()) {
+ registration.register(vaadinSharedContext, vaadinService);
}
}
@@ -214,7 +162,7 @@ public class VaadinResourceTrackerComponent {
*/
@Deactivate
protected void deactivate() {
- for (final Delegate registration : resourceToRegistration.values()) {
+ for (final Delegate<?> registration : resourceToRegistration.values()) {
unregisterResource(registration);
}
for (List<ServiceRegistration<? extends OsgiVaadinResource>> registrations : contributorToRegistrations
@@ -225,107 +173,146 @@ public class VaadinResourceTrackerComponent {
}
resourceToRegistration.clear();
contributorToRegistrations.clear();
- httpService = null;
- }
-
- private void registerTheme(VaadinResourceService resourceService,
- Bundle bundle, Long serviceId, OsgiVaadinTheme theme)
- throws NamespaceException {
- String pathPrefix = resourceService.getResourcePathPrefix();
-
- String alias = PathFormatHelper.getThemeAlias(theme.getName(),
- pathPrefix);
- String path = PathFormatHelper.getThemePath(theme.getName());
-
- registerResource(alias, path, bundle, serviceId);
- }
-
- private void registerWidget(VaadinResourceService resourceService,
- Bundle bundle, Long serviceId, OsgiVaadinWidgetset widgetset)
- throws NamespaceException {
- String pathPrefix = resourceService.getResourcePathPrefix();
-
- String alias = PathFormatHelper.getWidgetsetAlias(widgetset.getName(),
- pathPrefix);
- String path = PathFormatHelper.getWidgetsetPath(widgetset.getName());
-
- registerResource(alias, path, bundle, serviceId);
+ vaadinSharedContext = null;
+ vaadinService = null;
}
- private void registerResource(VaadinResourceService resourceService,
- Bundle bundle, Long serviceId, OsgiVaadinResource resource)
- throws NamespaceException {
- String pathPrefix = resourceService.getResourcePathPrefix();
-
- String alias = PathFormatHelper.getRootResourceAlias(resource.getName(),
- pathPrefix);
- String path = PathFormatHelper.getRootResourcePath(resource.getName());
-
- registerResource(alias, path, bundle, serviceId);
- }
-
- private void registerResource(String alias, String path, Bundle bundle,
- Long serviceId) throws NamespaceException {
- Delegate registration = new Delegate(alias, path, bundle);
+ private <T extends OsgiVaadinResource> void registerResource(
+ ServiceReference<T> resourceRef) {
+ String pattern = (String) resourceRef.getProperty(
+ HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PATTERN);
+ // if this resource contains a http whiteboard property we are done here
+ // because we are registering the same service with whiteboard
+ // properties we have to filter them here
+ if (pattern != null)
+ return;
+ BundleContext context = resourceRef.getBundle().getBundleContext();
+ Long serviceId = (Long) resourceRef.getProperty(Constants.SERVICE_ID);
+ Delegate<T> registration = new Delegate<>(resourceRef, context);
resourceToRegistration.put(serviceId, registration);
- registerResource(registration);
+ registration.register(vaadinSharedContext, vaadinService);
}
- private void registerResource(Delegate registration)
- throws NamespaceException {
- if (this.httpService != null && !registration.isInitialized()) {
- registration.init(httpService);
- httpService.registerResources(registration.alias, registration.path,
- registration);
- }
+ private void unregisterResource(
+ ServiceReference<? extends OsgiVaadinResource> resourceRef) {
+ Long serviceId = (Long) resourceRef.getProperty(Constants.SERVICE_ID);
+ unregisterResource(serviceId);
}
private void unregisterResource(Long serviceId) {
- Delegate registration = resourceToRegistration.remove(serviceId);
+ if (serviceId == null)
+ return;
+ Delegate<?> registration = resourceToRegistration.remove(serviceId);
unregisterResource(registration);
}
- private void unregisterResource(Delegate registration) {
- if (registration != null && httpService != null) {
- httpService.unregister(registration.alias);
+ private void unregisterResource(Delegate<?> registration) {
+ if (registration != null) {
+ registration.unregister();
}
}
- static final class Delegate implements HttpContext {
- private final String alias;
- private final String path;
- private final Bundle bundle;
-
- private volatile HttpContext context;
-
- public Delegate(String alias, String path, Bundle bundle) {
- this.alias = alias;
- this.path = path;
- this.bundle = bundle;
- }
-
- public void init(HttpService service) {
- context = service.createDefaultHttpContext();
- }
-
- public boolean isInitialized() {
- return context != null;
+ static final class Delegate<T extends OsgiVaadinResource> {
+ private final ServiceReference<T> resourceRef;
+ // the bundle context who contributed the resource - we reuse that so we
+ // can register the http whiteboard resource in the name of the
+ // contributing bundle
+ private final BundleContext bundleContext;
+
+ private volatile BundleContext vaadinSharedContext;
+ private volatile VaadinResourceService vaadinService;
+ private volatile ServiceRegistration<? super T> resourceRegistration;
+
+ public Delegate(ServiceReference<T> resourceRef,
+ BundleContext bundleContext) {
+ this.resourceRef = Objects.requireNonNull(resourceRef);
+ this.bundleContext = Objects.requireNonNull(bundleContext);
}
- @Override
- public boolean handleSecurity(HttpServletRequest request,
- HttpServletResponse response) throws IOException {
- return context.handleSecurity(request, response);
+ public void register(BundleContext vaadinSharedContext,
+ VaadinResourceService vaadinService) {
+ if (vaadinService != null) {
+ this.vaadinService = vaadinService;
+ }
+ if (vaadinSharedContext != null) {
+ this.vaadinSharedContext = vaadinSharedContext;
+ }
+ // if all dependencies are satisfied we can finally register the
+ // http resource
+ if (this.vaadinService != null
+ && this.vaadinSharedContext != null) {
+ this.registerImpl();
+ }
}
- @Override
- public URL getResource(String name) {
- return bundle.getResource(name);
+ public void unregister() {
+ if (resourceRegistration != null) {
+ resourceRegistration.unregister();
+ }
+ if (vaadinSharedContext != null) {
+ // unget the service reference
+ vaadinSharedContext.ungetService(resourceRef);
+ }
+ vaadinService = null;
+ vaadinSharedContext = null;
+ resourceRegistration = null;
}
- @Override
- public String getMimeType(String name) {
- return context.getMimeType(name);
+ @SuppressWarnings("unchecked")
+ private void registerImpl() {
+ // we have already registered if resourceRegistration is set
+ if (resourceRegistration != null)
+ return;
+
+ T resource = vaadinSharedContext.getService(this.resourceRef);
+ // we don't need a path prefix because we register at the vaadin
+ // context which handles the prefixing
+ String pathPrefix = "";
+ Class<? super T> interfaceType;
+ String alias;
+ String path;
+ if (resource instanceof OsgiVaadinWidgetset) {
+ alias = PathFormatHelper.getWidgetsetAlias(resource.getName(),
+ pathPrefix);
+ // OsgiVaadinWidgetset provides folders so we have to add a
+ // wildcard
+ alias = alias + "/*";
+ path = PathFormatHelper.getWidgetsetPath(resource.getName());
+ // save cast because OsgiVaadinWidgetset is a super class of T
+ interfaceType = (Class<? super T>) OsgiVaadinWidgetset.class;
+ } else if (resource instanceof OsgiVaadinTheme) {
+ alias = PathFormatHelper.getThemeAlias(resource.getName(),
+ pathPrefix);
+ // OsgiVaadinTheme provides folders so we have to add a wildcard
+ alias = alias + "/*";
+ path = PathFormatHelper.getThemePath(resource.getName());
+ // save cast because OsgiVaadinTheme is a super class of T
+ interfaceType = (Class<? super T>) OsgiVaadinTheme.class;
+ } else {
+ alias = PathFormatHelper
+ .getRootResourceAlias(resource.getName(), pathPrefix);
+ path = PathFormatHelper.getRootResourcePath(resource.getName());
+ interfaceType = OsgiVaadinResource.class;
+ }
+ // remove the empty prefixed slash
+ alias = alias.substring(1);
+
+ final String contextFilter = "("
+ + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "="
+ + vaadinService.getContextName() + ")";
+ // register a OSGi http resource based on the whiteboard pattern
+ final Dictionary<String, String> properties = new Hashtable<>();
+ properties.put(
+ HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PATTERN,
+ alias);
+ properties.put(
+ HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PREFIX,
+ path);
+ properties.put(
+ HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT,
+ contextFilter);
+ resourceRegistration = bundleContext.registerService(interfaceType,
+ resource, properties);
}
}
}
diff --git a/shared/src/main/java/com/vaadin/osgi/resources/impl/VaadinServletContextFactory.java b/shared/src/main/java/com/vaadin/osgi/resources/impl/VaadinServletContextFactory.java
new file mode 100644
index 0000000000..035f6fca47
--- /dev/null
+++ b/shared/src/main/java/com/vaadin/osgi/resources/impl/VaadinServletContextFactory.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2000-2018 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.osgi.resources.impl;
+
+import java.net.URL;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.http.context.ServletContextHelper;
+
+public class VaadinServletContextFactory
+ implements ServiceFactory<ServletContextHelper> {
+ @Override
+ public ServletContextHelper getService(final Bundle bundle,
+ final ServiceRegistration<ServletContextHelper> registration) {
+ return new VaadinServletContext(bundle);
+ }
+
+ @Override
+ public void ungetService(final Bundle bundle,
+ final ServiceRegistration<ServletContextHelper> registration,
+ final ServletContextHelper service) {
+ // nothing to do
+ }
+
+ private static class VaadinServletContext extends ServletContextHelper {
+ private final Bundle bundle;
+
+ public VaadinServletContext(Bundle bundle) {
+ super(bundle);
+ this.bundle = bundle;
+ }
+
+ // we want to load the resources from the classpath
+ @Override
+ public URL getResource(String name) {
+ if ((name != null) && (bundle != null)) {
+ if (name.startsWith("/")) {
+ name = name.substring(1);
+ }
+
+ return this.bundle.getResource(name);
+ }
+ return null;
+ }
+ }
+}