1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package io.wcm.caravan.hal.docs.impl;
21
22 import io.wcm.caravan.jaxrs.publisher.ApplicationPath;
23
24 import java.util.Dictionary;
25 import java.util.Hashtable;
26
27 import org.apache.felix.scr.annotations.Activate;
28 import org.apache.felix.scr.annotations.Component;
29 import org.apache.felix.scr.annotations.Deactivate;
30 import org.apache.felix.scr.annotations.Reference;
31 import org.osgi.framework.Bundle;
32 import org.osgi.framework.BundleContext;
33 import org.osgi.framework.BundleEvent;
34 import org.osgi.service.component.ComponentConstants;
35 import org.osgi.service.component.ComponentContext;
36 import org.osgi.service.component.ComponentFactory;
37 import org.osgi.service.component.ComponentInstance;
38 import org.osgi.service.http.HttpService;
39 import org.osgi.service.http.NamespaceException;
40 import org.osgi.util.tracker.BundleTracker;
41 import org.osgi.util.tracker.BundleTrackerCustomizer;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45
46
47
48
49 @Component(immediate = true)
50 public class HalDocsBundleTracker implements BundleTrackerCustomizer<ComponentInstance> {
51
52 static final String DOCS_RESOURCES_URI_PREFIX = "/docs/resources";
53 static final String CLASSPATH_FRONTEND = "HALDOCS-TEMPLATE-INF/frontend";
54
55 private static final Logger log = LoggerFactory.getLogger(HalDocsBundleTracker.class);
56
57 private BundleContext bundleContext;
58 private BundleTracker bundleTracker;
59
60 @Reference(target = "(" + ComponentConstants.COMPONENT_FACTORY + "=" + HalDocsServlet.FACTORY + ")")
61 private ComponentFactory servletFactory;
62
63 @Reference
64 private HttpService httpService;
65
66 @Activate
67 void activate(ComponentContext componentContext) throws NamespaceException {
68 bundleContext = componentContext.getBundleContext();
69 this.bundleTracker = new BundleTracker<ComponentInstance>(bundleContext, Bundle.ACTIVE, this);
70 this.bundleTracker.open();
71
72
73 httpService.registerResources(DOCS_RESOURCES_URI_PREFIX, CLASSPATH_FRONTEND, null);
74 }
75
76 @Deactivate
77 void deactivate(ComponentContext componentContext) {
78 this.bundleTracker.close();
79 httpService.unregister(DOCS_RESOURCES_URI_PREFIX);
80 }
81
82 @Override
83 public ComponentInstance addingBundle(Bundle bundle, BundleEvent event) {
84 String docsPath = DocsPath.get(bundle);
85 if (docsPath != null) {
86
87 if (log.isInfoEnabled()) {
88 log.info("Mount HAL docs for {} to {}", bundle.getSymbolicName(), docsPath);
89 }
90
91
92 Dictionary<String, Object> serviceConfig = new Hashtable<>();
93 serviceConfig.put("alias", docsPath);
94 serviceConfig.put(HalDocsServlet.PROPERTY_BUNDLE, bundle);
95 return servletFactory.newInstance(serviceConfig);
96 }
97 return null;
98 }
99
100 @Override
101 public void modifiedBundle(Bundle bundle, BundleEvent event, ComponentInstance componentInstance) {
102
103 }
104
105 @Override
106 public void removedBundle(Bundle bundle, BundleEvent event, ComponentInstance componentInstance) {
107 if (componentInstance == null) {
108 return;
109 }
110 if (log.isInfoEnabled()) {
111 String applicationPath = ApplicationPath.get(bundle);
112 String docsPath = DocsPath.get(applicationPath);
113 log.info("Unmount HAL docs for {} from {}", bundle.getSymbolicName(), docsPath);
114 }
115 componentInstance.dispose();
116 }
117
118 }