diff options
Diffstat (limited to 'shared/src')
5 files changed, 313 insertions, 189 deletions
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; + } + } +} |