Coverage Report - org.apache.tiles.request.freemarker.servlet.SharedVariableLoaderFreemarkerServlet
 
Classes in this File Line Coverage Branch Coverage Complexity
SharedVariableLoaderFreemarkerServlet
52%
11/21
20%
2/10
1.846
SharedVariableLoaderFreemarkerServlet$ExcludingParameterServletConfig
77%
7/9
50%
1/2
1.846
SharedVariableLoaderFreemarkerServlet$SkippingEnumeration
94%
18/19
87%
7/8
1.846
 
 1  
 /*
 2  
  * $Id: SharedVariableLoaderFreemarkerServlet.java 1306435 2012-03-28 15:39:11Z nlebas $
 3  
  *
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  * http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 package org.apache.tiles.request.freemarker.servlet;
 23  
 
 24  
 import java.util.Enumeration;
 25  
 import java.util.LinkedHashMap;
 26  
 import java.util.Map;
 27  
 
 28  
 import javax.servlet.ServletConfig;
 29  
 import javax.servlet.ServletContext;
 30  
 import javax.servlet.ServletException;
 31  
 
 32  
 import org.apache.tiles.request.reflect.ClassUtil;
 33  
 
 34  
 import freemarker.cache.TemplateLoader;
 35  
 import freemarker.ext.servlet.FreemarkerServlet;
 36  
 import freemarker.template.Configuration;
 37  
 
 38  
 /**
 39  
  * Extends FreemarkerServlet to load Tiles directives as a shared variable.
 40  
  *
 41  
  * @version $Rev: 1306435 $ $Date: 2012-03-29 02:39:11 +1100 (Thu, 29 Mar 2012) $
 42  
  */
 43  5
 public class SharedVariableLoaderFreemarkerServlet extends FreemarkerServlet {
 44  
 
 45  
     /**
 46  
      * The serial UID.
 47  
      */
 48  
     private static final long serialVersionUID = 4301098067909854507L;
 49  
 
 50  
     /**
 51  
      * The init parameter under which the factories will be put. The value of the parameter
 52  
      * must be a semicolon (;) separated list of couples, each member of the couple must
 53  
      * be separated by commas (,).
 54  
      */
 55  
     public static final String CUSTOM_SHARED_VARIABLE_FACTORIES_INIT_PARAM =
 56  
         "org.apache.tiles.request.freemarker.CUSTOM_SHARED_VARIABLE_FACTORIES";
 57  
 
 58  
     /**
 59  
      * Maps a name of a shared variable to its factory.
 60  
      */
 61  5
     private Map<String, SharedVariableFactory> name2variableFactory =
 62  
         new LinkedHashMap<String, SharedVariableFactory>();
 63  
 
 64  
     @Override
 65  
     public void init(ServletConfig config) throws ServletException {
 66  5
         String param = config.getInitParameter(CUSTOM_SHARED_VARIABLE_FACTORIES_INIT_PARAM);
 67  5
         if (param != null) {
 68  0
             String[] couples = param.split("\\s*;\\s*");
 69  0
             for (int i = 0; i < couples.length; i++) {
 70  0
                 String[] couple = couples[i].split("\\s*,\\s*");
 71  0
                 if (couple == null || couple.length != 2) {
 72  0
                     throw new ServletException(
 73  
                             "Cannot parse custom shared variable partial init param: '"
 74  
                                     + couples[i] + "'");
 75  
                 }
 76  0
                 name2variableFactory.put(couple[0],
 77  
                         (SharedVariableFactory) ClassUtil.instantiate(couple[1]));
 78  
             }
 79  
         }
 80  5
         super.init(new ExcludingParameterServletConfig(config));
 81  5
     }
 82  
 
 83  
     /**
 84  
      * Adds anew shared variable factory in a manual way.
 85  
      *
 86  
      * @param variableName The name of the shared variable.
 87  
      * @param factory The shared variable factory.
 88  
      */
 89  
     public void addSharedVariableFactory(String variableName, SharedVariableFactory factory) {
 90  0
         name2variableFactory.put(variableName, factory);
 91  0
     }
 92  
 
 93  
     /** {@inheritDoc} */
 94  
     @Override
 95  
     protected Configuration createConfiguration() {
 96  5
         Configuration configuration = super.createConfiguration();
 97  
 
 98  5
         for (Map.Entry<String, SharedVariableFactory> entry : name2variableFactory.entrySet()) {
 99  0
             configuration.setSharedVariable(entry.getKey(), entry.getValue().create());
 100  0
         }
 101  5
         return configuration;
 102  
     }
 103  
 
 104  
     /** {@inheritDoc} */
 105  
 
 106  
     @Override
 107  
     protected TemplateLoader createTemplateLoader(String templatePath) {
 108  5
         return new WebappClassTemplateLoader(getServletContext());
 109  
     }
 110  
 
 111  
     /**
 112  
      * Servlet configuration that excludes some parameters. It is useful to adapt to
 113  
      * FreemarkerServlet behaviour, because it gets angry if it sees some extra
 114  
      * parameters that it does not recognize.
 115  
      */
 116  
     private class ExcludingParameterServletConfig implements ServletConfig {
 117  
 
 118  
         /**
 119  
          * The servlet configuration.
 120  
          */
 121  
         private ServletConfig config;
 122  
 
 123  
         /**
 124  
          * Constructor.
 125  
          *
 126  
          * @param config The servlet configuration.
 127  
          */
 128  5
         public ExcludingParameterServletConfig(ServletConfig config) {
 129  5
             this.config = config;
 130  5
         }
 131  
 
 132  
         @Override
 133  
         public String getServletName() {
 134  0
             return config.getServletName();
 135  
         }
 136  
 
 137  
         @Override
 138  
         public ServletContext getServletContext() {
 139  6
             return config.getServletContext();
 140  
         }
 141  
 
 142  
         @Override
 143  
         public String getInitParameter(String name) {
 144  45
             if (CUSTOM_SHARED_VARIABLE_FACTORIES_INIT_PARAM.equals(name)) {
 145  0
                 return null;
 146  
             }
 147  45
             return config.getInitParameter(name);
 148  
         }
 149  
 
 150  
         @SuppressWarnings({ "rawtypes", "unchecked" })
 151  
         @Override
 152  
         public Enumeration getInitParameterNames() {
 153  5
             return new SkippingEnumeration(config.getInitParameterNames());
 154  
         }
 155  
 
 156  
     }
 157  
 
 158  
     /**
 159  
      * An enumeration that skip just
 160  
      * {@link SharedVariableLoaderFreemarkerServlet#CUSTOM_SHARED_VARIABLE_FACTORIES_INIT_PARAM},
 161  
      * again not to let the FreemarkerServlet be angry about it.
 162  
      */
 163  30
     private static class SkippingEnumeration implements Enumeration<String> {
 164  
 
 165  
         /**
 166  
          * The original enumeration.
 167  
          */
 168  
         private Enumeration<String> enumeration;
 169  
 
 170  
         /**
 171  
          * The next element.
 172  
          */
 173  5
         private String next = null;
 174  
 
 175  
         /**
 176  
          * Constructor.
 177  
          *
 178  
          * @param enumeration The original enumeration.
 179  
          */
 180  5
         public SkippingEnumeration(Enumeration<String> enumeration) {
 181  5
             this.enumeration = enumeration;
 182  5
             updateNextElement();
 183  5
         }
 184  
 
 185  
         @Override
 186  
         public boolean hasMoreElements() {
 187  35
             return next != null;
 188  
         }
 189  
 
 190  
         @Override
 191  
         public String nextElement() {
 192  30
             String retValue = next;
 193  30
             updateNextElement();
 194  30
             return retValue;
 195  
         }
 196  
 
 197  
         /**
 198  
          * Updates the next element that will be passed.
 199  
          */
 200  
         private void updateNextElement() {
 201  35
             String value = null;
 202  35
             boolean done = false;
 203  65
             while (this.enumeration.hasMoreElements() && !done) {
 204  30
                 value = this.enumeration.nextElement();
 205  30
                 if (value.equals(CUSTOM_SHARED_VARIABLE_FACTORIES_INIT_PARAM)) {
 206  0
                     value = null;
 207  
                 } else {
 208  30
                     done = true;
 209  
                 }
 210  
             }
 211  35
             next = value;
 212  35
         }
 213  
 
 214  
     }
 215  
 }