Browse Source

OSGi resource registration via SCR (#11166)

* Changed the way resources, themes, and widgetsets are registered to the HttpService by only using the VaadinResourceTrackerComponent
tags/8.6.0.alpha2
S.W 5 years ago
parent
commit
7e89b5e334

+ 6
- 23
client-compiled/src/main/java/com/vaadin/osgi/widgetset/DefaultWidgetsetContribution.java View File

@@ -15,33 +15,16 @@
*/
package com.vaadin.osgi.widgetset;

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.Reference;
import org.osgi.service.http.HttpService;

import com.vaadin.osgi.resources.OsgiVaadinResources;
import com.vaadin.osgi.resources.VaadinResourceService;

@Component(immediate = true)
public class DefaultWidgetsetContribution {
private HttpService httpService;
import com.vaadin.osgi.resources.OsgiVaadinWidgetset;

@Component
public class DefaultWidgetsetContribution implements OsgiVaadinWidgetset {
private static final String WIDGETSET_NAME = "com.vaadin.DefaultWidgetSet";

@Activate
void startup(ComponentContext context) throws Exception {
VaadinResourceService service = OsgiVaadinResources.getService();
service.publishWidgetset(WIDGETSET_NAME, httpService);
}

@Reference
void setHttpService(HttpService httpService) {
this.httpService = httpService;
}

void unsetHttpService(HttpService httpService) {
this.httpService = null;
@Override
public String getName() {
return WIDGETSET_NAME;
}
}

+ 6
- 23
compatibility-client-compiled/src/main/java/com/vaadin/osgi/compatibility/widgetset/CompatibilityWidgetsetContribution.java View File

@@ -15,33 +15,16 @@
*/
package com.vaadin.osgi.compatibility.widgetset;

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.Reference;
import org.osgi.service.http.HttpService;

import com.vaadin.osgi.resources.OsgiVaadinResources;
import com.vaadin.osgi.resources.VaadinResourceService;

@Component(immediate = true)
public class CompatibilityWidgetsetContribution {
private HttpService httpService;
import com.vaadin.osgi.resources.OsgiVaadinWidgetset;

@Component
public class CompatibilityWidgetsetContribution implements OsgiVaadinWidgetset {
private static final String WIDGETSET_NAME = "com.vaadin.v7.Vaadin7WidgetSet";

@Activate
void startup(ComponentContext context) throws Exception {
VaadinResourceService service = OsgiVaadinResources.getService();
service.publishWidgetset(WIDGETSET_NAME, httpService);
}

@Reference
void setHttpService(HttpService httpService) {
this.httpService = httpService;
}

void unsetHttpService(HttpService httpService) {
this.httpService = null;
@Override
public String getName() {
return WIDGETSET_NAME;
}
}

+ 15
- 23
compatibility-themes/src/main/java/com/vaadin/osgi/compatibility/themes/LegacyThemeContributions.java View File

@@ -15,35 +15,27 @@
*/
package com.vaadin.osgi.compatibility.themes;

import org.osgi.service.component.annotations.Activate;
import java.util.ArrayList;
import java.util.List;

import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.http.HttpService;

import com.vaadin.osgi.resources.OsgiVaadinResources;
import com.vaadin.osgi.resources.VaadinResourceService;
import com.vaadin.osgi.resources.OsgiVaadinContributor;
import com.vaadin.osgi.resources.OsgiVaadinResource;
import com.vaadin.osgi.resources.OsgiVaadinTheme;

@Component(immediate = true)
public class LegacyThemeContributions {
@Component
public class LegacyThemeContributions implements OsgiVaadinContributor {
private static final String[] LEGACY_THEMES = { "base", "chameleon",
"reindeer", "runo" };

private HttpService httpService;

@Activate
void startup() throws Exception {
VaadinResourceService service = OsgiVaadinResources.getService();
for (String themeName : LEGACY_THEMES) {
service.publishTheme(themeName, httpService);
@Override
public List<OsgiVaadinResource> getContributions() {
final List<OsgiVaadinResource> contributions = new ArrayList<>(
LEGACY_THEMES.length);
for (final String theme : LEGACY_THEMES) {
contributions.add(OsgiVaadinTheme.create(theme));
}
}

@Reference
void setHttpService(HttpService httpService) {
this.httpService = httpService;
}

void unsetHttpService(HttpService httpService) {
this.httpService = null;
return contributions;
}
}

+ 14
- 24
push/src/main/java/com/vaadin/osgi/push/PushResourcesContribution.java View File

@@ -15,37 +15,27 @@
*/
package com.vaadin.osgi.push;

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.Reference;
import org.osgi.service.http.HttpService;
import java.util.ArrayList;
import java.util.List;

import com.vaadin.osgi.resources.OsgiVaadinResources;
import com.vaadin.osgi.resources.VaadinResourceService;
import org.osgi.service.component.annotations.Component;

@Component(immediate = true)
public class PushResourcesContribution {
private HttpService httpService;
import com.vaadin.osgi.resources.OsgiVaadinContributor;
import com.vaadin.osgi.resources.OsgiVaadinResource;

@Component
public class PushResourcesContribution implements OsgiVaadinContributor {
private static final String[] RESOURCES = { "vaadinPush.js",
"vaadinPush.js.gz", "vaadinPush.debug.js",
"vaadinPush.debug.js.gz" };

@Activate
void startup(ComponentContext context) throws Exception {
VaadinResourceService service = OsgiVaadinResources.getService();
for (String resourceName : RESOURCES) {
service.publishResource(resourceName, httpService);
@Override
public List<OsgiVaadinResource> getContributions() {
final List<OsgiVaadinResource> contributions = new ArrayList<>(
RESOURCES.length);
for (final String theme : RESOURCES) {
contributions.add(OsgiVaadinResource.create(theme));
}
}

@Reference
void setHttpService(HttpService httpService) {
this.httpService = httpService;
}

void unsetHttpService(HttpService httpService) {
this.httpService = null;
return contributions;
}
}

+ 14
- 24
server/src/main/java/com/vaadin/server/osgi/BootstrapContribution.java View File

@@ -15,15 +15,13 @@
*/
package com.vaadin.server.osgi;

import org.osgi.service.component.annotations.Activate;
import java.util.ArrayList;
import java.util.List;

import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.http.HttpService;
import org.osgi.service.http.NamespaceException;

import com.vaadin.osgi.resources.OsgiVaadinResources;
import com.vaadin.osgi.resources.OsgiVaadinResources.ResourceBundleInactiveException;
import com.vaadin.osgi.resources.VaadinResourceService;
import com.vaadin.osgi.resources.OsgiVaadinContributor;
import com.vaadin.osgi.resources.OsgiVaadinResource;

/**
* OSGi service component registering bootstrap JS as published resources in
@@ -32,26 +30,18 @@ import com.vaadin.osgi.resources.VaadinResourceService;
* @author Vaadin Ltd
* @since 8.1
*/
@Component(immediate = true)
public class BootstrapContribution {
@Component
public class BootstrapContribution implements OsgiVaadinContributor {
private static final String[] RESOURCES = { "vaadinBootstrap.js",
"vaadinBootstrap.js.gz" };
private HttpService httpService;

@Activate
void startup() throws NamespaceException, ResourceBundleInactiveException {
VaadinResourceService service = OsgiVaadinResources.getService();
for (String resourceName : RESOURCES) {
service.publishResource(resourceName, httpService);
@Override
public List<OsgiVaadinResource> getContributions() {
final List<OsgiVaadinResource> contributions = new ArrayList<>(
RESOURCES.length);
for (final String theme : RESOURCES) {
contributions.add(OsgiVaadinResource.create(theme));
}
}

@Reference
void setHttpService(HttpService service) {
httpService = service;
}

void unsetHttpService(HttpService service) {
httpService = null;
return contributions;
}
}

+ 29
- 0
shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinContributor.java View File

@@ -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();
}

+ 47
- 0
shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinResource.java View File

@@ -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;
}
};
}
}

+ 11
- 1
shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinTheme.java View File

@@ -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;
}
};
}
}

+ 11
- 1
shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinWidgetset.java View File

@@ -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;
}
};
}
}

+ 179
- 43
shared/src/main/java/com/vaadin/osgi/resources/impl/VaadinResourceTrackerComponent.java View File

@@ -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);
}

}
}

+ 6
- 23
themes/src/main/java/com/vaadin/osgi/themes/ValoThemeContribution.java View File

@@ -15,31 +15,14 @@
*/
package com.vaadin.osgi.themes;

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.http.HttpService;

import com.vaadin.osgi.resources.OsgiVaadinResources;
import com.vaadin.osgi.resources.VaadinResourceService;
import com.vaadin.osgi.resources.OsgiVaadinTheme;

@Component(immediate = true)
public class ValoThemeContribution {

private HttpService httpService;

@Activate
void startup() throws Exception {
VaadinResourceService service = OsgiVaadinResources.getService();
service.publishTheme("valo", httpService);
}

@Reference
void setHttpService(HttpService httpService) {
this.httpService = httpService;
}

void unsetHttpService(HttpService httpService) {
this.httpService = null;
@Component
public class ValoThemeContribution implements OsgiVaadinTheme {
@Override
public String getName() {
return "valo";
}
}

Loading…
Cancel
Save