Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2014 Attila Szegedi, Daniel Dekany, Jonathan Revusky
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   * http://www.apache.org/licenses/LICENSE-2.0
   * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package freemarker.ext.servlet;
 
 import java.io.Writer;
 import java.util.Map;
 
 import  javax.servlet.ServletException;
 import  javax.servlet.http.HttpServletRequest;
 import  javax.servlet.http.HttpServletRequestWrapper;
 import  javax.servlet.http.HttpServletResponse;
 import  javax.servlet.http.HttpServletResponseWrapper;
 
A model that when invoked with a 'path' parameter will perform a servlet include. It also support an optional hash named 'params' which specifies request parameters for the include - its keys are strings, its values should be either strings or sequences of strings (for multiple valued parameters). A third optional parameter 'inherit_params' should be a boolean when specified, and it defaults to true when not specified. A value of true means that the include inherits the request parameters from the current request. In this case values in 'params' will get prepended to the existing values of parameters.
 
 public class IncludePage implements TemplateDirectiveModel
 {
     private final HttpServletRequest request;
     private final HttpServletResponse response;
     
     public IncludePage(HttpServletRequest request, HttpServletResponse response) {
         this. = request;
         this. = response;
     }
     
     public void execute(final Environment envMap params
             TemplateModel[] loopVarsTemplateDirectiveBody body)
     throws TemplateExceptionIOException
     {
         // Determine the path
         final TemplateModel path = (TemplateModel)params.get("path");
         if(path == null) {
             throw new _MiscTemplateException(env"Missing required parameter \"path\"");
         }
         if(!(path instanceof TemplateScalarModel)) {
             throw new _MiscTemplateException(envnew Object[] {
                     "Expected a scalar model. \"path\" is instead ",
                     new _DelayedFTLTypeDescription(path) });
         }
         final String strPath = ((TemplateScalarModel)path).getAsString();
         if(strPath == null) {
             throw new _MiscTemplateException(env"String value of \"path\" parameter is null");
         }
         
         // See whether we need to use a custom response (if we're inside a TTM
         // or TDM or macro nested body, we'll need to as then the current 
         // FM environment writer is not identical to HTTP servlet response 
         // writer. 
         final Writer envOut = env.getOut(); 
         final HttpServletResponse wrappedResponse;
         if(envOut == .getWriter()) {
             // Don't bother wrapping if environment's writer is same as 
             // response writer
             wrappedResponse = ;
         }
         else {
            final PrintWriter printWriter = (envOut instanceof PrintWriter) ?
                (PrintWriter)envOut :
                new PrintWriter(envOut); 
            // Otherwise, create a response wrapper that will pass the
            // env writer, potentially first wrapping it in a print
            // writer when it ain't one already.
            wrappedResponse = new HttpServletResponseWrapper() {
                public PrintWriter getWriter() {
                    return printWriter;
                }
            };
        }
        // Determine inherit_params value
        final boolean inheritParams;
        final TemplateModel inheritParamsModel = (TemplateModel)params.get("inherit_params");
        if(inheritParamsModel == null) {
            // defaults to true when not specified
            inheritParams = true
        }
        else {
            if(!(inheritParamsModel instanceof TemplateBooleanModel)) {
                throw new _MiscTemplateException(envnew Object[] {
                        "\"inherit_params\" should be a boolean but it's a(n) ",
                        inheritParamsModel.getClass().getName(), " instead" });
            }
            inheritParams = ((TemplateBooleanModel)inheritParamsModel).getAsBoolean();
        }
        
        // Get explicit params, if any
        final TemplateModel paramsModel = (TemplateModel)params.get("params");
        
        // Determine whether we need to wrap the request
        final HttpServletRequest wrappedRequest;
        if(paramsModel == null && inheritParams) {
            // Inherit original request params & no params explicitly 
            // specified, so use the original request
            wrappedRequest = ;
        }
        else {
            // In any other case, use a custom request wrapper
            final Map paramsMap;
            if(paramsModel != null) {
                // Convert params to a Map
                final Object unwrapped = DeepUnwrap.unwrap(paramsModel);
                if(!(unwrapped instanceof Map)) {
                    throw new _MiscTemplateException(envnew Object[] {
                            "Expected \"params\" to unwrap into a java.util.Map. It unwrapped into ",
                            unwrapped.getClass().getName(), " instead." });
                }
                paramsMap = (Map)unwrapped;
            }
            else {
                paramsMap = .;
            }
            wrappedRequest = new CustomParamsRequest(paramsMap
                    inheritParams);
        }
        
        // Finally, do the include
        try {
            .getRequestDispatcher(strPath).include(wrappedRequest
                    wrappedResponse);
        }
        catch (ServletException e) {
            throw new _MiscTemplateException(eenv);
        }
    }
    private static final class CustomParamsRequest extends HttpServletRequestWrapper
    {
        private final HashMap paramsMap;
        private CustomParamsRequest(HttpServletRequest requestMap paramMap
                boolean inheritParams) {
            super(request);
             = inheritParams ? new HashMap(request.getParameterMap()) : new HashMap();
            for (Iterator it = paramMap.entrySet().iterator(); it.hasNext();) {
                Map.Entry entry = (Map.Entry)it.next();
                String name = String.valueOf(entry.getKey());
                Object value = entry.getValue();
                final String[] valueArray;
                if(value == null) {
                    // Null values are explicitly added (so, among other 
                    // things, we can hide inherited param values).
                    valueArray = new String[] { null };
                }
                else if(value instanceof String[]) {
                    // String[] arrays are just passed through
                    valueArray = (String[])value;
                }
                else if(value instanceof Collection) {
                    // Collections are converted to String[], with 
                    // String.valueOf() used on elements
                    Collection col = (Collection)value;
                    valueArray = new String[col.size()];
                    int i = 0;
                    for (Iterator it2 = col.iterator(); it2.hasNext();) {
                        valueArray[i++] = String.valueOf(it2.next());
                    }
                }
                else if(value.getClass().isArray()) {
                    // Other array types are too converted to String[], with 
                    // String.valueOf() used on elements
                    int len = Array.getLength(value);
                    valueArray = new String[len];
                    for(int i = 0; i < len; ++i) {
                        valueArray[i] = String.valueOf(Array.get(valuei));
                    }
                }
                else {
                    // All other values (including strings) are converted to a
                    // single-element String[], with String.valueOf applied to
                    // the value.
                    valueArray = new String[] { String.valueOf(value) };
                }
                String[] existingParams = (String[]).get(name);
                int el = existingParams == null ? 0 : existingParams.length;
                if(el == 0)
                {
                    // No original params, just put our array
                    .put(namevalueArray);
                }
                else
                {
                    int vl = valueArray.length;
                    if(vl > 0)
                    {
                        // Both original params and new params, prepend our
                        // params to original params
                        String[] newValueArray = new String[el + vl];
                        System.arraycopy(valueArray, 0, newValueArray, 0, vl);
                        System.arraycopy(existingParams, 0, newValueArrayvlel);
                        .put(namenewValueArray);
                    }
                }
            }
        }
        public String[] getParameterValues(String name) {
            String[] value = ((String[]).get(name));
            return value != null ? (String[])value.clone() : null;
        }
        public String getParameter(String name) {
            String[] values = (String[]).get(name);
            return values != null && values.length > 0 ? values[0] : null;
        }
        public Enumeration getParameterNames() {
            return Collections.enumeration(.keySet());
        }
        public Map getParameterMap() {
            HashMap clone = (HashMap).clone();
            for (Iterator it = clone.entrySet().iterator(); it.hasNext();) {
                Map.Entry entry = (Map.Entry)it.next();
                entry.setValue(((String[])entry.getValue()).clone());
            }
            return Collections.unmodifiableMap(clone);
        }
    }
New to GrepCode? Check out our FAQ X