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 java.io.FileNotFoundException;
23 import java.io.IOException;
24 import java.net.URL;
25 import java.util.Map;
26
27 import org.apache.felix.scr.annotations.Activate;
28 import org.apache.felix.scr.annotations.Component;
29 import org.apache.felix.scr.annotations.Service;
30 import org.osgi.framework.Bundle;
31 import org.osgi.service.component.ComponentContext;
32
33 import com.github.jknack.handlebars.Handlebars;
34 import com.github.jknack.handlebars.Template;
35 import com.github.jknack.handlebars.io.AbstractTemplateLoader;
36 import com.github.jknack.handlebars.io.TemplateSource;
37 import com.github.jknack.handlebars.io.URLTemplateSource;
38 import com.google.common.collect.ImmutableMap;
39
40 import io.wcm.caravan.hal.docs.impl.model.LinkRelation;
41
42
43
44
45 @Component(immediate = true)
46 @Service(TemplateRenderer.class)
47 public class TemplateRenderer {
48
49 private static final String CLASSPATH_TEMPLATES = "HALDOCS-TEMPLATE-INF/templates";
50
51 private Handlebars handlebars;
52 private Template serviceTemplate;
53 private Template linkRelationTemplate;
54
55 @Activate
56 void activate(ComponentContext componentContext) throws IOException {
57 Bundle bundle = componentContext.getBundleContext().getBundle();
58 this.handlebars = new Handlebars(new BundleTemplateLoader(bundle));
59 this.serviceTemplate = handlebars.compile("service.html.hbs");
60 this.linkRelationTemplate = handlebars.compile("linkRelation.html.hbs");
61 }
62
63
64
65
66
67
68
69 public String renderServiceHtml(io.wcm.caravan.hal.docs.impl.model.Service service) throws IOException {
70 Map<String, Object> model = ImmutableMap.<String, Object>builder()
71 .put("service", service)
72 .build();
73 return render(service, model, serviceTemplate);
74 }
75
76
77
78
79
80
81
82
83 public String renderLinkRelationHtml(io.wcm.caravan.hal.docs.impl.model.Service service, LinkRelation linkRelation)
84 throws IOException {
85 Map<String, Object> model = ImmutableMap.<String, Object>builder()
86 .put("service", service)
87 .put("linkRelation", linkRelation)
88 .build();
89 return render(service, model, linkRelationTemplate);
90 }
91
92
93
94
95
96
97
98 private String render(io.wcm.caravan.hal.docs.impl.model.Service service, Map<String, Object> model,
99 Template template) throws IOException {
100 Map<String, Object> mergedModel = ImmutableMap.<String, Object>builder()
101 .putAll(model)
102 .put("docsContext", ImmutableMap.<String, Object>builder()
103 .put("baseUrl", DocsPath.get(service.getServiceId()) + "/")
104 .put("resourcesPath", HalDocsBundleTracker.DOCS_RESOURCES_URI_PREFIX)
105 .build())
106 .build();
107 return template.apply(mergedModel);
108 }
109
110
111
112
113 private static class BundleTemplateLoader extends AbstractTemplateLoader {
114
115 private final Bundle bundle;
116
117 BundleTemplateLoader(Bundle bundle) {
118 this.bundle = bundle;
119 }
120
121 @Override
122 public TemplateSource sourceAt(String location) throws IOException {
123 URL resource = bundle.getResource(CLASSPATH_TEMPLATES + "/" + location);
124 if (resource == null) {
125 throw new FileNotFoundException(location);
126 }
127 return new URLTemplateSource(location, resource);
128 }
129
130 }
131
132 }