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.apache.log4j.Logger;
16
17 import javax.ws.rs.core.Context;
18 import javax.servlet.http.HttpServletRequest;
19 import javax.servlet.http.HttpServletResponse;
20
21
22
23
24 @SuppressWarnings({"UnusedDeclaration"})
25 public class VelocityTemplateProcessor implements TemplateProcessor
26 {
27 private static final Logger log = Logger.getLogger(VelocityTemplateProcessor.class);
28 private static final String VM = ".vm";
29
30 private final ServiceTracker templateRendererServiceTracker;
31 private @Context HttpContext httpContext;
32 private @Context HttpServletRequest httpServletRequest;
33 private @Context HttpServletResponse httpServletResponse;
34
35 VelocityTemplateProcessor(ServiceTracker templateRendererServiceTracker)
36 {
37 this.templateRendererServiceTracker = Preconditions.checkNotNull(templateRendererServiceTracker);
38 }
39
40 public String resolve(final String path)
41 {
42 return executeOnTemplateRenderer(new TemplateRendererCommand<String>()
43 {
44 public String execute(TemplateRenderer renderer)
45 {
46 String resolvedPath = path + VM;
47 if (renderer.resolve(resolvedPath))
48 {
49 return resolvedPath;
50 }
51 else
52 {
53 return null;
54 }
55 }
56 });
57 }
58
59 public void writeTo(final String resolvedPath, final Object model, final OutputStream out) throws IOException
60 {
61 try
62 {
63 executeOnTemplateRenderer(new TemplateRendererCommand<Object>()
64 {
65 public Object execute(TemplateRenderer renderer)
66 {
67 final OutputStreamWriter writer = new OutputStreamWriter(out);
68 final Map<String, Object> context = Maps.newHashMap();
69 context.put("renderer", new RendererImpl(renderer, writer, httpContext,
70 httpServletRequest, httpServletResponse));
71 context.put("it", model);
72 context.put("httpContext", httpContext);
73 context.put("request", httpServletRequest);
74 context.put("response", httpServletResponse);
75 try
76 {
77 renderer.render(resolvedPath, context, writer);
78 }
79 catch (IOException ioe)
80 {
81 throw new RuntimeException(ioe);
82 }
83 return null;
84 }
85 });
86 }
87 catch (RuntimeException re)
88 {
89 if (re.getCause() instanceof IOException)
90 {
91 throw (IOException) re.getCause();
92 }
93 else
94 {
95 throw re;
96 }
97 }
98 }
99
100
101
102
103 public void closeTemplateRendererServiceTracker()
104 {
105 templateRendererServiceTracker.close();
106 }
107
108
109
110
111
112 private interface TemplateRendererCommand<T>
113 {
114 T execute(TemplateRenderer renderer);
115 }
116
117 private <T> T executeOnTemplateRenderer(TemplateRendererCommand<T> templateRendererCommand)
118 {
119 TemplateRenderer renderer = (TemplateRenderer) templateRendererServiceTracker.getService();
120 if (renderer != null)
121 {
122 return templateRendererCommand.execute(renderer);
123 }
124 else
125 {
126 log.warn("No template renderer service available, not executing command");
127 return null;
128 }
129
130 }
131 }