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 org.apache.commons.lang3.StringUtils;
23 import org.apache.felix.scr.annotations.Activate;
24 import org.apache.felix.scr.annotations.Component;
25 import org.apache.felix.scr.annotations.Deactivate;
26 import org.apache.felix.scr.annotations.Reference;
27 import org.osgi.framework.Bundle;
28 import org.osgi.framework.BundleContext;
29 import org.osgi.framework.BundleEvent;
30 import org.osgi.service.component.ComponentContext;
31 import org.osgi.service.http.HttpService;
32 import org.osgi.service.http.NamespaceException;
33 import org.osgi.util.tracker.BundleTracker;
34 import org.osgi.util.tracker.BundleTrackerCustomizer;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38
39
40
41
42 @Component(immediate = true)
43 public class JsonSchemaBundleTracker implements BundleTrackerCustomizer<String> {
44
45
46
47
48 public static final String HEADER_DOMAIN_PATH = "Caravan-HalDocs-DomainPath";
49
50
51
52
53 public static final String SCHEMA_URI_PREFIX = "/docs/json-schema";
54
55
56
57
58 public static final String SCHEMA_CLASSPATH_PREFIX = "JSON-SCHEMA-INF";
59
60 private static final Logger log = LoggerFactory.getLogger(JsonSchemaBundleTracker.class);
61
62 private BundleContext bundleContext;
63 private BundleTracker bundleTracker;
64
65 @Reference
66 private HttpService httpService;
67
68 @Activate
69 void activate(ComponentContext componentContext) {
70 bundleContext = componentContext.getBundleContext();
71 this.bundleTracker = new BundleTracker<String>(bundleContext, Bundle.ACTIVE, this);
72 this.bundleTracker.open();
73 }
74
75 @Deactivate
76 void deactivate(ComponentContext componentContext) {
77 this.bundleTracker.close();
78 }
79
80 @Override
81 public String addingBundle(Bundle bundle, BundleEvent event) {
82 String domainPath = getHalDocsDomainPath(bundle);
83 if (StringUtils.isNotBlank(domainPath)) {
84 String schemaPath = getDocsPath(domainPath);
85
86 if (log.isInfoEnabled()) {
87 log.info("Mount JSON schema files for {} to {}", bundle.getSymbolicName(), schemaPath);
88 }
89
90 try {
91 httpService.registerResources(schemaPath, SCHEMA_CLASSPATH_PREFIX,
92 new HttpContextWrapper(httpService.createDefaultHttpContext(), bundle));
93 }
94 catch (NamespaceException ex) {
95 throw new RuntimeException("Unable to mount JSON schema files to " + schemaPath, ex);
96 }
97 return schemaPath;
98 }
99 return null;
100 }
101
102 @Override
103 public void modifiedBundle(Bundle bundle, BundleEvent event, String schemaPath) {
104
105 }
106
107 @Override
108 public void removedBundle(Bundle bundle, BundleEvent event, String schemaPath) {
109 if (schemaPath == null) {
110 return;
111 }
112 if (log.isInfoEnabled()) {
113 log.info("Unmount JSON schema files for {} from {}", bundle.getSymbolicName(), schemaPath);
114 }
115 httpService.unregister(schemaPath);
116 }
117
118 private String getHalDocsDomainPath(Bundle bundle) {
119 return bundle.getHeaders().get(HEADER_DOMAIN_PATH);
120 }
121
122 private String getDocsPath(String domainPath) {
123 return SCHEMA_URI_PREFIX + domainPath;
124 }
125
126 }