Coverage Report - no.sesat.search.view.velocity.URLVelocityTemplateLoader
 
Classes in this File Line Coverage Branch Coverage Complexity
URLVelocityTemplateLoader
0%
0/82
0%
0/26
0
URLVelocityTemplateLoader$1
0%
0/16
0%
0/8
0
 
 1  
 /* Copyright (20072008) Schibsted Søk AS
 2  
  * This file is part of SESAT.
 3  
  *
 4  
  *   SESAT is free software: you can redistribute it and/or modify
 5  
  *   it under the terms of the GNU Affero General Public License as published by
 6  
  *   the Free Software Foundation, either version 3 of the License, or
 7  
  *   (at your option) any later version.
 8  
  *
 9  
  *   SESAT is distributed in the hope that it will be useful,
 10  
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12  
  *   GNU Affero General Public License for more details.
 13  
  *
 14  
  *   You should have received a copy of the GNU Affero General Public License
 15  
  *   along with SESAT.  If not, see <http://www.gnu.org/licenses/>.
 16  
  */
 17  
 package no.sesat.search.view.velocity;
 18  
 
 19  
 import java.io.*;
 20  
 
 21  
 import javax.xml.parsers.DocumentBuilderFactory;
 22  
 import javax.xml.parsers.ParserConfigurationException;
 23  
 import javax.xml.transform.OutputKeys;
 24  
 import javax.xml.transform.Transformer;
 25  
 import javax.xml.transform.TransformerConfigurationException;
 26  
 import javax.xml.transform.TransformerException;
 27  
 import javax.xml.transform.TransformerFactory;
 28  
 import javax.xml.transform.dom.DOMSource;
 29  
 import javax.xml.transform.stream.StreamResult;
 30  
 
 31  
 import no.sesat.Interpreter;
 32  
 
 33  
 import org.apache.log4j.Logger;
 34  
 
 35  
 import org.apache.velocity.exception.ResourceNotFoundException;
 36  
 import org.w3c.dom.Document;
 37  
 import org.w3c.dom.Element;
 38  
 
 39  
 /**
 40  
  *
 41  
  * Load templates and adds debuginformation if VELOCITY_DEBUG is set to true.
 42  
  *
 43  
  * @see URLResourceLoader
 44  
  *
 45  
  *
 46  
  *
 47  
  *
 48  
  */
 49  0
 public class URLVelocityTemplateLoader extends URLResourceLoader {
 50  
 
 51  0
     private static final Logger LOG = Logger.getLogger(URLVelocityTemplateLoader.class);
 52  
 
 53  
     private static final String DIV_TAG = "div";
 54  
     private static final String STYLE_ATTRIB = "style";
 55  
     private static final String STYLE_BORDER = "margin:3px;border:1px solid #C0C0C0";
 56  
     private static final String STYLE_HEADING="text-decoration:underline;font-size:10px";
 57  
     private static final String ONMOUSEOVER = "this.style.border='1px solid #C0C0C0';this.style.margin='4px'";
 58  
     private static final String ONMOUSEOUT = "this.style.border='none'";
 59  
 
 60  
     private static final String VELOCITY_DEBUG = "VELOCITY_DEBUG";
 61  
     private static final String VELOCITY_DEBUG_ON = "VELOCITY_DEBUG_ON";
 62  
     private static final String VELOCITY_DEBUG_STYLE = "VELOCITY_DEBUG_STYLE";
 63  
     private static final String VELOCITY_DEVELOP_BASEDIR = "VELOCITY_DEVELOP_BASEDIR";
 64  
 
 65  
     /**
 66  
      * getResourceStream() loads resource from url. Then add border around the
 67  
      * template so its easy to see wich templates are loaded.
 68  
      * @throws org.apache.velocity.exception.ResourceNotFoundException
 69  
      */
 70  
     @Override
 71  
     public InputStream getResourceStream(final String url) throws ResourceNotFoundException {
 72  
 
 73  
         // Enable/disable velocity debug
 74  0
         final boolean velocityDebug = Boolean.getBoolean(VELOCITY_DEBUG);
 75  
         // Activate debug (Show borders/debuginfo)
 76  0
         final boolean velocityDebugOn = Boolean.getBoolean(VELOCITY_DEBUG_ON);
 77  
         // Onmouseover style
 78  0
         final boolean styleOnmouseover ="onmouseover".equals(System.getProperty(VELOCITY_DEBUG_STYLE));
 79  
         // Silent style
 80  0
         final boolean styleSilent ="silent".equals(System.getProperty(VELOCITY_DEBUG_STYLE));
 81  
         // Indicates if we found file local.(Can be edited)
 82  0
         boolean foundLocal = false;
 83  
 
 84  0
         if(velocityDebug) {
 85  
 
 86  0
             final String templatesDir = System.getProperty(VELOCITY_DEVELOP_BASEDIR);
 87  
 
 88  
             // Get the file equivalece of the URL by removing the host as well as the web application context path.
 89  0
             final String filePath = url.replaceAll("http://(.*?)/[^/]+/", "/").replace("localhost/", "");
 90  0
             final File file = getFile(templatesDir, filePath);
 91  
 
 92  0
             foundLocal = file.exists();
 93  
 
 94  0
             final InputStream stream = file.exists() ? getStream(file) : super.getResourceStream(url);
 95  
 
 96  0
             if(velocityDebugOn && -1 == url.indexOf("rss")){
 97  0
                 StringBuilder  content = this.readTemplateFrom(stream);
 98  
 
 99  
                 // Create html
 100  0
                 final StringBuilder template= new  StringBuilder();
 101  0
                 template.append("\n");
 102  0
                 template.append(content);
 103  0
                 template.append("\n");
 104  
 
 105  0
                 final StringWriter writer = new StringWriter();
 106  0
                 final Document doc = createDocument();
 107  
 
 108  0
                 final Element div = doc.createElement(DIV_TAG);
 109  
 
 110  0
                 if(styleOnmouseover) {
 111  
 
 112  0
                     div.setAttribute("onmouseover", ONMOUSEOVER);
 113  0
                     div.setAttribute("onmouseout", ONMOUSEOUT);
 114  
 
 115  0
                 }else if(styleSilent){
 116  
 
 117  
                         // Just print title as popup.
 118  
                 }else {
 119  
 
 120  0
                     final Element divHeader = doc.createElement(DIV_TAG);
 121  0
                     divHeader.setAttribute(STYLE_ATTRIB, STYLE_HEADING);
 122  0
                     divHeader.appendChild(doc.createTextNode(filePath));
 123  0
                     div.appendChild(divHeader);
 124  0
                     div.setAttribute("style", STYLE_BORDER);
 125  
                 }
 126  
 
 127  0
                 div.setAttribute("title", file.getName() + (foundLocal ? "(Editable)" : "(Not editable)"));
 128  0
                 div.appendChild(doc.createCDATASection(template.toString()));
 129  0
                 doc.appendChild(div);
 130  
 
 131  0
                 internalWriteDocument(doc, writer);
 132  
 
 133  0
                 final String result = writer.getBuffer().toString()
 134  
                         .replace("<![CDATA[", "")
 135  
                         .replace("]]>", "");
 136  
 
 137  0
                 return new ByteArrayInputStream(result.getBytes());
 138  
 
 139  
             }else{
 140  
                 // If debug is not currently activated OR If rss, means the output is xml.
 141  0
                 return stream;
 142  
             }
 143  
         }
 144  0
         return super.getResourceStream(url);
 145  
     }
 146  
 
 147  
     /**
 148  
      * Read template utf8.
 149  
      * @param is to read from
 150  
      * @return template as StringBuilder object
 151  
      */
 152  
     private StringBuilder readTemplateFrom(final InputStream is) {
 153  0
         StringBuilder builder = new StringBuilder();
 154  
 
 155  
         try {
 156  0
             InputStreamReader isr = new InputStreamReader(is, "UTF8");
 157  0
             Reader in = new BufferedReader(isr);
 158  
             int ch;
 159  0
             while ((ch = in.read()) > -1) {
 160  0
                 builder.append((char)ch);
 161  
             }
 162  0
             in.close();
 163  0
         } catch (IOException e) {
 164  0
             LOG.error(e);
 165  0
         }
 166  0
         return builder;
 167  
     }
 168  
 
 169  
     /**
 170  
      * Create file object
 171  
      */
 172  
     private File getFile(final String templatesDir, final String filePath) {
 173  
 
 174  0
         File result = null;
 175  
 
 176  0
         if(null == templatesDir) {
 177  0
             result = new File("null" + filePath);
 178  
 
 179  
         }else{
 180  0
             for(String p : templatesDir.split(",")) {
 181  
 
 182  0
                 final File file = new File(p + filePath);
 183  0
                 if(file.exists()) {
 184  0
                     result = file;
 185  0
                     break;
 186  
                 }
 187  
             }
 188  
         }
 189  
 
 190  0
         return null == result ? new File(filePath) : result;
 191  
     }
 192  
 
 193  
     /*
 194  
      * Get stream from file of or url.
 195  
      */
 196  
     private InputStream getStream(final File file) {
 197  
 
 198  0
         if (file.exists()) {
 199  
 
 200  
             try {
 201  0
                 FileInputStream fileStream = new FileInputStream(file);
 202  0
                 return fileStream;
 203  
 
 204  0
             } catch (FileNotFoundException ignore) {
 205  0
                 throw new IllegalStateException("File exist but filenotfoundexception thrown: " + ignore);
 206  
             }
 207  
 
 208  
         } else {
 209  0
             throw new IllegalArgumentException("File does not exist");
 210  
         }
 211  
     }
 212  
 
 213  
     // -- Write the document to the writer
 214  
     private void internalWriteDocument(final Document d, final Writer w) {
 215  
 
 216  0
         final DOMSource source = new DOMSource(d);
 217  0
         final StreamResult result = new StreamResult(w);
 218  
 
 219  0
         final TransformerFactory factory = TransformerFactory.newInstance();
 220  
 
 221  
         try {
 222  0
             final Transformer transformer = factory.newTransformer();
 223  0
             transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
 224  0
             transformer.transform(source, result);
 225  
 
 226  0
         } catch (TransformerConfigurationException e) {
 227  0
             throw new RuntimeException("Xml Parser: " + e);
 228  
 
 229  0
         } catch (TransformerException ignore) {
 230  0
             LOG.debug("Ingoring the following ", ignore);
 231  0
         }
 232  0
     }
 233  
 
 234  
     // -- Create a DOM document
 235  
     private Document createDocument() {
 236  
 
 237  0
         final DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
 238  
 
 239  
         try {
 240  0
             return docFactory.newDocumentBuilder().newDocument();
 241  
 
 242  0
         } catch (ParserConfigurationException e) {
 243  0
             throw new RuntimeException(e);
 244  
         }
 245  
     }
 246  
 
 247  
     /**
 248  
      * Add some debug function to the interpreter.
 249  
      */
 250  
     static {
 251  0
         Interpreter.addFunction("velocity-debug", new Interpreter.Function() {
 252  
             public String execute(Interpreter.Context ctx) {
 253  0
                 if (ctx.length() == 1) {
 254  0
                     System.setProperty(VELOCITY_DEBUG_ON, ctx.getArgument(0));
 255  0
                     String style = ctx.getKeywordArgument("style");
 256  0
                     if (style != null) {
 257  0
                         if (style.toUpperCase().startsWith("ON")) {
 258  0
                             System.setProperty(VELOCITY_DEBUG_STYLE, "onmouseover");
 259  
                         }
 260  0
                         else if (style.toUpperCase().startsWith("SI")) {
 261  0
                             System.setProperty(VELOCITY_DEBUG_STYLE, "silent");
 262  
                         }
 263  
                         else {
 264  0
                             System.setProperty(VELOCITY_DEBUG_STYLE, "default");
 265  
                         }
 266  
                     }
 267  
                 }
 268  0
                 String res = VELOCITY_DEBUG + " = " + Boolean.parseBoolean(System.getProperty(VELOCITY_DEBUG)) + " (must be set before starting up)\n";
 269  0
                 res += VELOCITY_DEBUG_ON + " = " + Boolean.parseBoolean(System.getProperty(VELOCITY_DEBUG_ON)) + "\n";
 270  0
                 res += VELOCITY_DEBUG_STYLE + " = " + System.getProperty(VELOCITY_DEBUG_STYLE) + "\n";
 271  0
                 res += VELOCITY_DEVELOP_BASEDIR + " = " + System.getProperty(VELOCITY_DEVELOP_BASEDIR) + "\n";
 272  
 
 273  0
                 return res;
 274  
             }
 275  
 
 276  
             @Override
 277  
             protected String describe() {
 278  0
                 return "Change or view velocity debug options. 'velocity-debug [true|false] [style=silent|onmouseover|default]'";
 279  
             }
 280  
         });
 281  0
     }
 282  
 }