001    package de.deepamehta.plugins.webactivator.provider;
002    
003    import de.deepamehta.plugins.webactivator.WebActivatorPlugin;
004    import de.deepamehta.core.util.JavaUtils;
005    
006    import com.sun.jersey.api.view.Viewable;
007    import com.sun.jersey.spi.template.ViewProcessor;
008    
009    import org.thymeleaf.TemplateEngine;
010    import org.thymeleaf.context.IContext;
011    
012    import javax.ws.rs.core.Context;
013    import javax.ws.rs.core.UriInfo;
014    import javax.ws.rs.ext.Provider;
015    
016    import java.io.BufferedWriter;
017    import java.io.IOException;
018    import java.io.OutputStream;
019    import java.io.OutputStreamWriter;
020    import java.io.Writer;
021    import java.util.List;
022    import java.util.logging.Logger;
023    
024    
025    
026    @Provider
027    public class ThymeleafViewProcessor implements ViewProcessor<String> {
028    
029        // ---------------------------------------------------------------------------------------------- Instance Variables
030    
031        @Context
032        private UriInfo uriInfo;
033    
034        private Logger logger = Logger.getLogger(getClass().getName());
035    
036        // -------------------------------------------------------------------------------------------------- Public Methods
037    
038        @Override
039        public String resolve(String templateName) {
040            // Note: By default the Viewable constructor resolves relative template names (as returned by the
041            // webapp's resource methods) against the package path of the request's matching resource object.
042            // JavaUtils.getFilename() strips that path.
043            return "/views/" + JavaUtils.getFilename(templateName) + ".html";
044        }
045    
046        @Override
047        public void writeTo(String templateName, Viewable viewable, OutputStream out) throws IOException {
048            WebActivatorPlugin plugin = matchedPlugin();
049            logger.info("Processing template \"" + templateName + "\" of " + plugin);
050            processTemplate(plugin.getTemplateEngine(), templateName, (IContext) viewable.getModel(), out);
051        }
052    
053        // -------------------------------------------------------------------------------------------------- Public Methods
054    
055        /**
056         * Returns the plugin that matches the current request.
057         */
058        private WebActivatorPlugin matchedPlugin() {
059            List<Object> resources = uriInfo.getMatchedResources();
060            //
061            // Note: sub-resource methods match 2 times. Both with the same resource object.
062            // ### TODO: support sub-resource locators
063            /* if (resources.size() != 1) {
064                throw new RuntimeException("Request path \"" + uriInfo.getPath() + "\" matches " + resources.size() +
065                    " resource objects " + resources);
066            } */
067            //
068            return (WebActivatorPlugin) resources.get(0);
069        }
070    
071        private void processTemplate(TemplateEngine templateEngine, String templateName, IContext context, OutputStream out)
072                                                                                                        throws IOException {
073            Writer writer = new BufferedWriter(new OutputStreamWriter(out , "UTF-8"));
074            templateEngine.process(templateName, context, writer);
075            writer.flush();
076        }
077    }