]> source.dussan.org Git - vaadin-framework.git/commitdiff
OSGi resource registration via SCR (#11166)
authorS.W <wimmesberger@gmail.com>
Fri, 21 Sep 2018 08:01:52 +0000 (10:01 +0200)
committerIlia Motornyi <elmot@vaadin.com>
Fri, 21 Sep 2018 08:01:52 +0000 (11:01 +0300)
* Changed the way resources, themes, and widgetsets are registered to the HttpService by only using the VaadinResourceTrackerComponent

client-compiled/src/main/java/com/vaadin/osgi/widgetset/DefaultWidgetsetContribution.java
compatibility-client-compiled/src/main/java/com/vaadin/osgi/compatibility/widgetset/CompatibilityWidgetsetContribution.java
compatibility-themes/src/main/java/com/vaadin/osgi/compatibility/themes/LegacyThemeContributions.java
push/src/main/java/com/vaadin/osgi/push/PushResourcesContribution.java
server/src/main/java/com/vaadin/server/osgi/BootstrapContribution.java
shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinContributor.java [new file with mode: 0644]
shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinResource.java [new file with mode: 0644]
shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinTheme.java
shared/src/main/java/com/vaadin/osgi/resources/OsgiVaadinWidgetset.java
shared/src/main/java/com/vaadin/osgi/resources/impl/VaadinResourceTrackerComponent.java
themes/src/main/java/com/vaadin/osgi/themes/ValoThemeContribution.java

index df25f5d537a677bde7c684efb0bb3a47d7124c47..783e4a0de1247114b2b3732a715713eb691b7903 100644 (file)
  */
 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;
     }
 }
index 155d7070b3be15ce778e9c077b147c971578c0be..b4b7d5c064a6141cf59baac5d1a287d8398843a0 100644 (file)
  */
 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;
     }
 }
index a773b7279a3575547d881c74ff7de29176699ad5..c0c7c962cff09508c65ab30fc6f61cb4a2f881c6 100644 (file)
  */
 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;
     }
 }
index 80b524be88c6008ce639dff6f252f9a67baad536..5857b7b3b28c5a7d4d323cf323ada77a641d5471 100644 (file)
  */
 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;
     }
 }
index 05966f4f2ba8d6b680cc3f640af2b8cabaf65262..17e2e711e6f85f451ce2441eb3862a6bc8b05923 100644 (file)
  */
 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;
     }
 }
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 (file)
index 0000000..44cd87b
--- /dev/null
@@ -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 (file)
index 0000000..ffe5e98
--- /dev/null
@@ -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;
+            }
+        };
+    }
+}
index b3d89ae35601f069857ad732563260bef490e4f5..d1afa22eb50f1120bba3577a59afd40c919ef555 100644 (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;
+            }
+        };
+    }
 }
index 2f443a00ab7854cd47eef5333a2c7ac5ed43729a..d5c927b98492f8c7f71563f0c9e52d7bbaed4efd 100644 (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;
+            }
+        };
+    }
 }
index fefe632ada421595d1fb1e8a449e01d185f302b3..4eb361fe61b84b3e3fed3f1a35ad179414dd58b8 100644 (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);
         }
-
     }
 }
index 4161c31e9e89dae93aeeed418ef367131d12bb75..29e7394e9c1da70b39b9d14fe6830ebbbaa54a5f 100644 (file)
  */
 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";
     }
 }