View Javadoc

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   * Template processor that uses velocity and locates template within the bundle that uses it.
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       * Close the template renderer service tracker.  This should be called when the service is unimported.
89       */
90      public void closeTemplateRendererServiceTracker() {
91          templateRendererServiceTracker.close();
92      }
93  
94      /**
95       * Command so calls to the template renderer don't need to check if the template renderer service is available
96       * first
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 }