summaryrefslogtreecommitdiffstats
path: root/shared
diff options
context:
space:
mode:
authorS.W <wimmesberger@gmail.com>2018-09-21 10:01:52 +0200
committerIlia Motornyi <elmot@vaadin.com>2018-09-21 11:01:52 +0300
commit7e89b5e3348be487110bd8a5c60336ff363cf9d6 (patch)
tree4913034eb366e7173bc083abae4c6ba3b9a19402 /shared
parentc534fb8e609c38c7b4821b5f79ec697b384c0809 (diff)
downloadvaadin-framework-7e89b5e3348be487110bd8a5c60336ff363cf9d6.tar.gz
vaadin-framework-7e89b5e3348be487110bd8a5c60336ff363cf9d6.zip
OSGi resource registration via SCR (#11166)
* Changed the way resources, themes, and widgetsets are registered to the HttpService by only using the VaadinResourceTrackerComponent
Diffstat (limited to 'shared')
-rw-r--r--shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinContributor.java29
-rw-r--r--shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinResource.java47
-rw-r--r--shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinTheme.java12
-rw-r--r--shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinWidgetset.java12
-rw-r--r--shared/src/main/java/com/vaadin/osgi/resources/impl/VaadinResourceTrackerComponent.java222
5 files changed, 277 insertions, 45 deletions
diff --git a/shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinContributor.java b/shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinContributor.java
new file mode 100644
index 0000000000..44cd87b0d4
--- /dev/null
+++ b/shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinContributor.java
@@ -0,0 +1,29 @@
+/*
+ * 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;
+
+import java.util.List;
+
+/**
+ * Used to declare multiple OsgiVaadinResources with a single OSGi component.
+ * Each vaadin resource will be checked for the type (theme, widgetset,
+ * resource) and registered to the OSGi context with the appropriate type.
+ *
+ * @since
+ */
+public interface OsgiVaadinContributor {
+ List<OsgiVaadinResource> getContributions();
+}
diff --git a/shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinResource.java b/shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinResource.java
new file mode 100644
index 0000000000..ffe5e980ac
--- /dev/null
+++ b/shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinResource.java
@@ -0,0 +1,47 @@
+/*
+ * 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;
+
+/**
+ * Used to declare a Vaadin Resource for use in OSGi. The resource is expected
+ * to be in the same OSGi bundle as the class implementing this interface, under
+ * the path "/VAADIN/{resourceName}" where {resourceName} is what is returned by
+ * {@link OsgiVaadinResource#getName()}.
+ * <p>
+ * To publish a resource, an implementation of this interface needs to be
+ * registered as an OSGi service, which makes
+ * <code>VaadinResourceTrackerComponent</code> automatically publish the
+ * resource with the given name.
+ *
+ * @since
+ */
+public interface OsgiVaadinResource {
+ /**
+ * Return the theme name to publish for OSGi.
+ *
+ * @return theme name, not null
+ */
+ String getName();
+
+ public static OsgiVaadinResource create(final String name) {
+ return new OsgiVaadinResource() {
+ @Override
+ public String getName() {
+ return name;
+ }
+ };
+ }
+}
diff --git a/shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinTheme.java b/shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinTheme.java
index b3d89ae356..d1afa22eb5 100644
--- a/shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinTheme.java
+++ b/shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinTheme.java
@@ -30,11 +30,21 @@ package com.vaadin.osgi.resources;
*
* @since 8.1
*/
-public interface OsgiVaadinTheme {
+public interface OsgiVaadinTheme extends OsgiVaadinResource {
/**
* Return the theme name to publish for OSGi.
*
* @return theme name, not null
*/
+ @Override
public String getName();
+
+ public static OsgiVaadinTheme create(final String name) {
+ return new OsgiVaadinTheme() {
+ @Override
+ public String getName() {
+ return name;
+ }
+ };
+ }
}
diff --git a/shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinWidgetset.java b/shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinWidgetset.java
index 2f443a00ab..d5c927b984 100644
--- a/shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinWidgetset.java
+++ b/shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinWidgetset.java
@@ -30,11 +30,21 @@ package com.vaadin.osgi.resources;
*
* @since 8.1
*/
-public interface OsgiVaadinWidgetset {
+public interface OsgiVaadinWidgetset extends OsgiVaadinResource {
/**
* Return the widgetset name to publish for OSGi.
*
* @return widgetset name, not null
*/
+ @Override
public String getName();
+
+ public static OsgiVaadinWidgetset create(final String name) {
+ return new OsgiVaadinWidgetset() {
+ @Override
+ public String getName() {
+ return name;
+ }
+ };
+ }
}
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 fefe632ada..4eb361fe61 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
@@ -17,8 +17,10 @@ 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.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
@@ -28,7 +30,10 @@ import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
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.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
@@ -36,6 +41,8 @@ import org.osgi.service.http.HttpContext;
import org.osgi.service.http.HttpService;
import org.osgi.service.http.NamespaceException;
+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;
@@ -52,16 +59,15 @@ import com.vaadin.osgi.resources.VaadinResourceService;
*/
@Component(immediate = true)
public class VaadinResourceTrackerComponent {
- private HttpService httpService;
-
- private Map<Long, String> themeToAlias = Collections
+ private final Map<Long, Delegate> resourceToRegistration = Collections
.synchronizedMap(new LinkedHashMap<>());
- private Map<Long, String> widgetsetToAlias = Collections
+ 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 {
+ throws ResourceBundleInactiveException {
Bundle bundle = themeRef.getBundle();
BundleContext context = bundle.getBundleContext();
@@ -73,19 +79,9 @@ public class VaadinResourceTrackerComponent {
VaadinResourceService resourceService = OsgiVaadinResources
.getService();
-
+ Long serviceId = (Long) themeRef.getProperty(Constants.SERVICE_ID);
try {
- String pathPrefix = resourceService.getResourcePathPrefix();
- Long serviceId = (Long) themeRef.getProperty(Constants.SERVICE_ID);
-
- String alias = PathFormatHelper.getThemeAlias(theme.getName(),
- pathPrefix);
- String path = PathFormatHelper.getThemePath(theme.getName());
-
- httpService.registerResources(alias, path,
- new Delegate(httpService, bundle));
-
- themeToAlias.put(serviceId, alias);
+ registerTheme(resourceService, bundle, serviceId, theme);
} finally {
context.ungetService(themeRef);
}
@@ -93,15 +89,12 @@ public class VaadinResourceTrackerComponent {
void unbindTheme(ServiceReference<OsgiVaadinTheme> themeRef) {
Long serviceId = (Long) themeRef.getProperty(Constants.SERVICE_ID);
- String themeAlias = themeToAlias.remove(serviceId);
- if (themeAlias != null && httpService != null) {
- httpService.unregister(themeAlias);
- }
+ unregisterResource(serviceId);
}
@Reference(cardinality = ReferenceCardinality.MULTIPLE, service = OsgiVaadinWidgetset.class, policy = ReferencePolicy.DYNAMIC)
void bindWidgetset(ServiceReference<OsgiVaadinWidgetset> widgetsetRef)
- throws ResourceBundleInactiveException, NamespaceException {
+ throws ResourceBundleInactiveException {
Bundle bundle = widgetsetRef.getBundle();
BundleContext context = bundle.getBundleContext();
@@ -111,20 +104,9 @@ public class VaadinResourceTrackerComponent {
}
VaadinResourceService service = OsgiVaadinResources.getService();
+ Long serviceId = (Long) widgetsetRef.getProperty(Constants.SERVICE_ID);
try {
- String pathPrefix = service.getResourcePathPrefix();
-
- Long serviceId = (Long) widgetsetRef
- .getProperty(Constants.SERVICE_ID);
-
- String alias = PathFormatHelper
- .getWidgetsetAlias(widgetset.getName(), pathPrefix);
- String path = PathFormatHelper
- .getWidgetsetPath(widgetset.getName());
-
- httpService.registerResources(alias, path,
- new Delegate(httpService, bundle));
- widgetsetToAlias.put(serviceId, alias);
+ registerWidget(service, bundle, serviceId, widgetset);
} finally {
context.ungetService(widgetsetRef);
}
@@ -133,9 +115,76 @@ public class VaadinResourceTrackerComponent {
void unbindWidgetset(ServiceReference<OsgiVaadinWidgetset> widgetsetRef) {
Long serviceId = (Long) widgetsetRef.getProperty(Constants.SERVICE_ID);
- String widgetsetAlias = widgetsetToAlias.remove(serviceId);
- if (widgetsetAlias != null && httpService != null) {
- httpService.unregister(widgetsetAlias);
+ unregisterResource(serviceId);
+ }
+
+ @Reference(cardinality = ReferenceCardinality.MULTIPLE, service = OsgiVaadinResource.class, policy = ReferencePolicy.DYNAMIC)
+ void bindResource(ServiceReference<OsgiVaadinResource> resourceRef)
+ throws ResourceBundleInactiveException {
+ 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 unbindResource(ServiceReference<OsgiVaadinResource> resourceRef) {
+ Long serviceId = (Long) resourceRef.getProperty(Constants.SERVICE_ID);
+ unregisterResource(serviceId);
+ }
+
+ @Reference(cardinality = ReferenceCardinality.MULTIPLE, service = OsgiVaadinContributor.class, policy = ReferencePolicy.DYNAMIC)
+ void bindContributor(ServiceReference<OsgiVaadinContributor> contributorRef)
+ throws ResourceBundleInactiveException {
+ Bundle bundle = contributorRef.getBundle();
+ BundleContext context = bundle.getBundleContext();
+
+ OsgiVaadinContributor contributor = context.getService(contributorRef);
+ if (contributor == null) {
+ return;
+ }
+ Long serviceId = (Long) contributorRef
+ .getProperty(Constants.SERVICE_ID);
+ List<OsgiVaadinResource> contributions = contributor.getContributions();
+ List<ServiceRegistration<? extends OsgiVaadinResource>> registrations = new ArrayList<>(
+ contributions.size());
+ for (final OsgiVaadinResource r : contributions) {
+ ServiceRegistration<? extends OsgiVaadinResource> reg;
+ if (r instanceof OsgiVaadinTheme) {
+ reg = context.registerService(OsgiVaadinTheme.class,
+ (OsgiVaadinTheme) r, null);
+ } else if (r instanceof OsgiVaadinWidgetset) {
+ reg = context.registerService(OsgiVaadinWidgetset.class,
+ (OsgiVaadinWidgetset) r, null);
+ } else {
+ reg = context.registerService(OsgiVaadinResource.class, r,
+ null);
+ }
+ registrations.add(reg);
+ }
+ contributorToRegistrations.put(serviceId, registrations);
+ }
+
+ void unbindContributor(
+ ServiceReference<OsgiVaadinContributor> contributorRef) {
+ Long serviceId = (Long) contributorRef
+ .getProperty(Constants.SERVICE_ID);
+ List<ServiceRegistration<? extends OsgiVaadinResource>> registrations = contributorToRegistrations
+ .get(serviceId);
+ if (registrations != null) {
+ for (ServiceRegistration<? extends OsgiVaadinResource> reg : registrations) {
+ reg.unregister();
+ }
}
}
@@ -148,15 +197,103 @@ public class VaadinResourceTrackerComponent {
this.httpService = null;
}
+ /**
+ *
+ * @throws NamespaceException
+ * @since
+ */
+ @Activate
+ protected void activate() throws NamespaceException {
+ for(Delegate registration : resourceToRegistration.values()) {
+ registration.init(httpService);
+ httpService.registerResources(registration.alias, registration.path, registration);
+ }
+ }
+
+ /**
+ * @since
+ */
+ @Deactivate
+ protected void deactivate() {
+ for(final Delegate registration : resourceToRegistration.values()) {
+ unregisterResource(registration);
+ }
+ for(List<ServiceRegistration<? extends OsgiVaadinResource>> registrations : contributorToRegistrations.values()) {
+ for (ServiceRegistration<? extends OsgiVaadinResource> reg : registrations) {
+ reg.unregister();
+ }
+ }
+ resourceToRegistration.clear();
+ contributorToRegistrations.clear();
+ httpService = null;
+ }
+
+ private void registerTheme(VaadinResourceService resourceService,
+ Bundle bundle, Long serviceId, OsgiVaadinTheme theme) {
+ 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) {
+ String pathPrefix = resourceService.getResourcePathPrefix();
+
+ String alias = PathFormatHelper.getWidgetsetAlias(widgetset.getName(),
+ pathPrefix);
+ String path = PathFormatHelper.getWidgetsetPath(widgetset.getName());
+
+ registerResource(alias, path, bundle, serviceId);
+ }
+
+ private void registerResource(VaadinResourceService resourceService,
+ Bundle bundle, Long serviceId, OsgiVaadinResource resource) {
+ 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) {
+ resourceToRegistration.put(serviceId, new Delegate(alias, path, bundle));
+ }
+
+ private void unregisterResource(Long serviceId) {
+ Delegate registration = resourceToRegistration.remove(serviceId);
+ unregisterResource(registration);
+ }
+
+ private void unregisterResource(Delegate registration) {
+ if (registration != null && httpService != null) {
+ httpService.unregister(registration.alias);
+ }
+ }
+
static final class Delegate implements HttpContext {
- private HttpContext context;
- private Bundle bundle;
+ private final String alias;
+ private final String path;
+ private final Bundle bundle;
- public Delegate(HttpService service, Bundle bundle) {
- this.context = service.createDefaultHttpContext();
+ 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();
+ }
+
@Override
public boolean handleSecurity(HttpServletRequest request,
HttpServletResponse response) throws IOException {
@@ -172,6 +309,5 @@ public class VaadinResourceTrackerComponent {
public String getMimeType(String name) {
return context.getMimeType(name);
}
-
}
}