Package de.innovationgate.wgpublisher

Source Code of de.innovationgate.wgpublisher.WGAFilter$GETRequestWrapper

/*******************************************************************************
* Copyright 2009, 2010 Innovation Gate GmbH. All Rights Reserved.
*
* This file is part of the OpenWGA server platform.
*
* OpenWGA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, a special exception is granted by the copyright holders
* of OpenWGA called "OpenWGA plugin exception". You should have received
* a copy of this exception along with OpenWGA in file COPYING.
* If not, see <http://www.openwga.com/gpl-plugin-exception>.
*
* OpenWGA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenWGA in file COPYING.
* If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package de.innovationgate.wgpublisher;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.WeakHashMap;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

import org.apache.commons.lang.ArrayUtils;

import de.innovationgate.utils.WGUtils;
import de.innovationgate.webgate.api.WGFactory;
import de.innovationgate.wgpublisher.WGPDispatcher.RequestInformation;
import de.innovationgate.wgpublisher.log.WGALoggerWrapper;
import de.innovationgate.wgpublisher.log.WGARequestInformation;
import de.innovationgate.wgpublisher.lucene.LuceneManager;

public class WGAFilter implements Filter {
 
  private WGACore _core;
  private WGAFilterChain _wgaFilterChain;
    private ServletContext _servletContext;
    private Map<ServletRequest, WGARequestInformation> _currentRequests = new WeakHashMap<ServletRequest, WGARequestInformation>();
   
   

   
    /**
     * wrapper for HttpServletResponse
     * - ignores all calls to setCharacterEncoding
     * - replace parameter charset=<XY> during setContentType with <wrappedResponse>.getCharacterEncoding()
     * Therefore the output encoding can be final set on the original response.
     *
     */
    private class FinalCharacterEncodingResponseWrapper extends HttpServletResponseWrapper {

      public static final String SYSPROP_ENCODING_ON_CONTENTTYPE = "de.innovationgate.wga.encoding.oncontenttype";

      private boolean _encodingOnContentType = false;

    private int _statusCode = HttpServletResponse.SC_OK;

    private String _statusMessage;
     
        public FinalCharacterEncodingResponseWrapper(HttpServletResponse arg0) {
            super(arg0);
            _encodingOnContentType = Boolean.getBoolean(SYSPROP_ENCODING_ON_CONTENTTYPE);
        }
       
        public void setCharacterEncoding(String arg0) {
            // ignore
        }
       
        public void setContentType(String arg0) {
            String contentType = arg0;
            if (contentType != null) {
                if (contentType.indexOf(";") != -1) {
                    List parameters = WGUtils.deserializeCollection(contentType, ";");
                    boolean charsetParamSet = false;
                    for (int i=1; i < parameters.size(); i++) {
                        String parameter = (String) parameters.get(i);
                        parameter = parameter.trim();
                        if (parameter.toLowerCase().startsWith("charset")) {
                            parameters.set(i, "charset=" + getResponse().getCharacterEncoding());
                            charsetParamSet = true;
                        }
                    }
                   
                   
                    if (_encodingOnContentType && !charsetParamSet && contentType.toLowerCase().trim().startsWith("text/")) {
                      // this is for a websphere bug
                      // if character encoding is set before content type and content type
                      // is given without charset websphere resets the charset to platform default
                      // therefore we ensure here that all of our content types have the correct
                      // charset parameter
                      parameters.add("charset=" + getResponse().getCharacterEncoding());
                    }
                    contentType = WGUtils.serializeCollection(parameters, ";");
                 } else if (_encodingOnContentType && contentType.toLowerCase().trim().startsWith("text/")) {                  
                   // see above about websphere bug
                  contentType += ";charset=" + getResponse().getCharacterEncoding();
                 }                
           }
           getResponse().setContentType(contentType);
        }

    @Override
    public void sendError(int sc, String msg) throws IOException {
      super.sendError(sc, msg);
      _statusCode = sc;
      _statusMessage = msg;
    }

    @Override
    public void sendError(int sc) throws IOException {
      super.sendError(sc);
      _statusCode = sc;
      _statusMessage = null;
    }

    @Override
    public void setStatus(int sc, String sm) {
      super.setStatus(sc, sm);
      _statusCode = sc;
      _statusMessage = sm;
    }

    @Override
    public void setStatus(int sc) {
      super.setStatus(sc);
      _statusCode = sc;
      _statusMessage = null;
    }

    public int getStatusCode() {
      return _statusCode;
    }

    public String getStatusMessage() {
      return _statusMessage;
    }

    @Override
    public void sendRedirect(String location) throws IOException {
      super.sendRedirect(location);
      setStatus(SC_MOVED_TEMPORARILY);
    }
       
    }
   
    /**
     * a wrapper for WGA GET requests
     * - supports decoding of url parameters (parameters of the querystring) in the correct encoding
     * - supports setting defaults for url parameters if they are empty (not submitted)
     *
     */
    public class GETRequestWrapper extends HttpServletRequestWrapper {

    private Map _parameters = new HashMap();
   
    private ServletRequest _wrappedRequest;

    public GETRequestWrapper(HttpServletRequest request, String encoding) {     
      super(request);
      _wrappedRequest = request;
      if (encoding != null) {           
        String queryString = request.getQueryString();
        // decode query string parameters with wga character encoding
        if (queryString != null) {
          StringTokenizer keyValuePairs = new StringTokenizer(queryString, "&");
          while (keyValuePairs.hasMoreTokens()) {
            String keyValuePair = keyValuePairs.nextToken();
           
            String key = null;
            String value = null;
            int pos = keyValuePair.indexOf("=");
            if (pos != -1) {
              key = keyValuePair.substring(0, pos);
              if (pos  < keyValuePair.length() - 1) {
                value = keyValuePair.substring(pos + 1);
              } else {
                value = "";
              }
             
              try {
                String keyDecoded = URLDecoder.decode(key, encoding);
                String valueDecoded = URLDecoder.decode(value, encoding);
                String values[] = (String[]) _parameters.get(keyDecoded);
                values = (String[])ArrayUtils.add(values, valueDecoded);
                _parameters.put(keyDecoded, values);
              } catch (UnsupportedEncodingException e) {
                WGFactory.getLogger().warn("Unable to decode request parameter '" + key + "'.", e);
              }
            }
                       
          }
        }        
      } else {
        // no encoding given - rely on default container encoding and request parsing
        _parameters = request.getParameterMap();
      }     
    }
     
     
    public String getParameter(String name) {
      copyNoneExistingParams(_wrappedRequest.getParameterMap());
      String values[] = (String[]) _parameters.get(name);
      if (values == null || values.length == 0) {
        return null;
      } else {
        return values[0];
      }
    }

    public Map getParameterMap() {
      copyNoneExistingParams(_wrappedRequest.getParameterMap());
      return new HashMap(_parameters);
    }

    public String[] getParameterValues(String name) {
      copyNoneExistingParams(_wrappedRequest.getParameterMap());
      return (String[]) _parameters.get(name);
    }

      public Enumeration getParameterNames() {
        copyNoneExistingParams(_wrappedRequest.getParameterMap());
        return Collections.enumeration(_parameters.keySet());
    }
     
      public void setParameterIfEmpty(String name, String value) {
        String[] values = getParameterValues(name);
        if (values == null || values.length == 0 || (values.length == 1 && values[0].equals(""))) {       
          String valueArr[] = new String[1];
          valueArr[0] = value;
          _parameters.put(name, valueArr);
        }
      }
     
      public void setParameterIfEmpty(String name, String[] values) {
        String[] existingValues = getParameterValues(name);
        if (existingValues == null || existingValues.length == 0 || (existingValues.length == 1 && existingValues[0].equals(""))) {  
          _parameters.put(name, values);
        }
      }


    public void setRequest(ServletRequest request) {
      super.setRequest(request);
      _wrappedRequest = request;
    }
     
    private void copyNoneExistingParams(Map from) {
      // add all parameters from the request to local map, which where not already parsed from querystring or added via setParameterIfEmpty
      // necessary for jsp-param parsing
      HashMap temp = new HashMap(from);
      Iterator localParams = _parameters.keySet().iterator();
      while (localParams.hasNext()) {
        String localParam = (String) localParams.next();
        temp.remove(localParam)
      }
      _parameters.putAll(temp);
    }
    }

  /* (Kein Javadoc)
   * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
   */
  public void init(FilterConfig arg0) throws ServletException {
      _servletContext = arg0.getServletContext();
    _core = WGACore.retrieve(_servletContext);
    if (_core != null) {
        _core.setFilter(this);
    }
    initFilterChain();
  }

    public void initFilterChain() {
        _core.getLog().info("Initializing filter chain");
        _wgaFilterChain = new WGAFilterChain(_core, _servletContext);
    }

  /* (Kein Javadoc)
   * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
   */
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    WGARequestInformation info = new WGARequestInformation();
    try {
      info.setStartTime(System.currentTimeMillis());
      request.setAttribute(WGARequestInformation.REQUEST_ATTRIBUTENAME, info);
     
      _wgaFilterChain.init(request, chain);                 
     
      _currentRequests.put(request, info);
     
          // F000037B2
          if (_core.getCharacterEncoding() != null) {
              request.setCharacterEncoding(_core.getCharacterEncoding());
              // B000041DA
              response.setCharacterEncoding(_core.getCharacterEncoding());           
          }
                 
         
         HttpServletResponse wrappedResponse =  new FinalCharacterEncodingResponseWrapper((HttpServletResponse)response);     
        
         if (((HttpServletRequest)request).getMethod().equalsIgnoreCase("GET")) {
            HttpServletRequest wrappedRequest = new GETRequestWrapper((HttpServletRequest)request, _core.getCharacterEncoding());
            _wgaFilterChain.doFilter(wrappedRequest, wrappedResponse);
         } else {
            _wgaFilterChain.doFilter(request, wrappedResponse);
         }
       
         info.setStatusCode(((FinalCharacterEncodingResponseWrapper)wrappedResponse).getStatusCode());
         info.setStatusMessage(((FinalCharacterEncodingResponseWrapper)wrappedResponse).getStatusMessage());        
    }
    catch (ServletException e) {
      info.setStatusCode(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        info.setStatusMessage(e.getMessage());
        throw e;
    }
    finally {
      info.setEndTime(System.currentTimeMillis())
         try {
        WGALoggerWrapper logger = _core.getAccessLogger();
           if (logger != null) {
             logger.logRequest(request);
           }
      } catch (Exception e) {
        _core.getLog().error("Unable to log request.", e);
      }
     
         WGFactory.getInstance().closeSessions();
        
         // close opened lucene-resultsets
         LuceneManager luceneManager = _core.getLuceneManager();
         if (luceneManager != null) {
             luceneManager.closeOpenedResultSets();
         }
        
         _currentRequests.remove(request);
       }
  }

  /* (Kein Javadoc)
   * @see javax.servlet.Filter#destroy()
   */
  public void destroy() {}


}
TOP

Related Classes of de.innovationgate.wgpublisher.WGAFilter$GETRequestWrapper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.