1 package com.atlassian.plugins.rest.module.template;
2
3 import com.atlassian.templaterenderer.TemplateRenderer;
4 import com.google.common.base.Preconditions;
5 import com.google.common.collect.Maps;
6 import com.sun.jersey.spi.template.TemplateProcessor;
7 import com.sun.jersey.api.core.HttpContext;
8
9 import java.io.IOException;
10 import java.io.OutputStream;
11 import java.io.OutputStreamWriter;
12 import java.util.Map;
13
14 import org.osgi.util.tracker.ServiceTracker;
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
17
18 import javax.ws.rs.core.Context;
19 import javax.servlet.http.HttpServletRequest;
20 import javax.servlet.http.HttpServletResponse;
21
22
23
24
25 @SuppressWarnings({"UnusedDeclaration"})
26 public class VelocityTemplateProcessor implements TemplateProcessor {
27 private static final Logger log = LoggerFactory.getLogger(VelocityTemplateProcessor.class);
28 private static final String VM = ".vm";
29
30 private final ServiceTracker templateRendererServiceTracker;
31 private
32 @Context
33 HttpContext httpContext;
34 private
35 @Context
36 HttpServletRequest httpServletRequest;
37 private
38 @Context
39 HttpServletResponse httpServletResponse;
40
41 VelocityTemplateProcessor(ServiceTracker templateRendererServiceTracker) {
42 this.templateRendererServiceTracker = Preconditions.checkNotNull(templateRendererServiceTracker);
43 }
44
45 public String resolve(final String path) {
46 return executeOnTemplateRenderer(new TemplateRendererCommand<String>() {
47 public String execute(TemplateRenderer renderer) {
48 String resolvedPath = path + VM;
49 if (renderer.resolve(resolvedPath)) {
50 return resolvedPath;
51 } else {
52 return null;
53 }
54 }
55 });
56 }
57
58 public void writeTo(final String resolvedPath, final Object model, final OutputStream out) throws IOException {
59 try {
60 executeOnTemplateRenderer(new TemplateRendererCommand<Object>() {
61 public Object execute(TemplateRenderer renderer) {
62 final OutputStreamWriter writer = new OutputStreamWriter(out);
63 final Map<String, Object> context = Maps.newHashMap();
64 context.put("renderer", new RendererImpl(renderer, writer, httpContext,
65 httpServletRequest, httpServletResponse));
66 context.put("it", model);
67 context.put("httpContext", httpContext);
68 context.put("request", httpServletRequest);
69 context.put("response", httpServletResponse);
70 try {
71 renderer.render(resolvedPath, context, writer);
72 } catch (IOException ioe) {
73 throw new RuntimeException(ioe);
74 }
75 return null;
76 }
77 });
78 } catch (RuntimeException re) {
79 if (re.getCause() instanceof IOException) {
80 throw (IOException) re.getCause();
81 } else {
82 throw re;
83 }
84 }
85 }
86
87
88
89
90 public void closeTemplateRendererServiceTracker() {
91 templateRendererServiceTracker.close();
92 }
93
94
95
96
97
98 private interface TemplateRendererCommand<T> {
99 T execute(TemplateRenderer renderer);
100 }
101
102 private <T> T executeOnTemplateRenderer(TemplateRendererCommand<T> templateRendererCommand) {
103 TemplateRenderer renderer = (TemplateRenderer) templateRendererServiceTracker.getService();
104 if (renderer != null) {
105 return templateRendererCommand.execute(renderer);
106 } else {
107 log.warn("No template renderer service available, not executing command");
108 return null;
109 }
110
111 }
112 }