Package de.odysseus.calyxo.control.impl

Source Code of de.odysseus.calyxo.control.impl.DefaultDispatcher

/*
* Copyright 2004, 2005, 2006 Odysseus Software GmbH
*
* 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 de.odysseus.calyxo.control.impl;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Iterator;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import de.odysseus.calyxo.base.ModuleContext;
import de.odysseus.calyxo.base.ModuleSupport;

import de.odysseus.calyxo.control.Dispatcher;
import de.odysseus.calyxo.control.conf.DispatchConfig;
import de.odysseus.calyxo.control.conf.ParamConfig;
import de.odysseus.calyxo.control.conf.ParamsConfig;

/**
* Dispatcher class.
* The dispatcher is responsible to perform a forward, include or redirect
* according to a dispatch config. Each module has its own dispatcher and
* dispatches to actions in its module or to resource paths.
* <p/>
* This class may be subclassed to modify dispatching behaviour.
*
* @author Christoph Beck
*/
public class DefaultDispatcher implements Dispatcher {
  protected static final Log log = LogFactory.getLog(DefaultDispatcher.class);

  private ModuleContext context;
  private ModuleSupport support;

  public DefaultDispatcher(ModuleContext context) {
    this.context = context;
    this.support = ModuleSupport.getInstance(context.getServletContext());
  }
 
  /**
   * Dispatch request.
   * </p>
   * If the dispatch element specifies an action, dispatch to that action.
   * Otherwise, the dispatch element must specify a path. If that path starts
   * with a "/", treat it as a context-relative path and dispatch accordingly.
   * If the path doesn't start with a "/" leave it unchanged.
   * </p>
   * If the redirection flag is set, dispatch by redirection.
   * Otherwise, dispatch by forward or include, depending on if the
   * response has already been committed.
   *
   * @param request the request we process
   * @param response the response we process
   * @param dispatch the dispatch target
   * @throws IOException passed through
   * @throws ServletException passed through
   */
  public void dispatch(
    HttpServletRequest request,
    HttpServletResponse response,
    DispatchConfig dispatch
  ) throws IOException, ServletException {
    String path = null;
    if (dispatch.getAction() != null) {
      ModuleContext module = context;
      if (dispatch.getModule() != null) { // switch module
        module = support.getModuleContext(dispatch.getModule());
        if (module == null) {
          throw new ServletException("Unknown module in '" + dispatch.toInlineString() + "'");
        }
      }
      path = module.getPath(dispatch.getAction());
    } else /* if (dispatch.getPath() != null) */ {
      path = dispatch.getPath();
    }
    path = addParams(path, dispatch, "UTF-8");
    dispatch(request, response, path, dispatch.isRedirect());
  }

  /**
   * Append the dispatch parameters as URL parameters to the
   * specified path.
   * @param path uri
   * @param config parameters
   * @param encoding encoding to be used, e.g. <code>"UTF-8"</code>
   * @return uri with query string according to the dispatch parameters.
   * @throws UnsupportedEncodingException
   */
  protected String addParams(String path, ParamsConfig config, String encoding)
    throws UnsupportedEncodingException {
    // append query parameters
    Iterator params = config.getParamConfigs();
    if (params.hasNext()) {
      StringBuffer buf = new StringBuffer(path);
      // save anchor (if any)
      String anchor = null;
      int hash = path.indexOf('#');
      if (hash > 0) {
        anchor = path.substring(hash);
        buf.setLength(hash);
      }
      buf.append(path.indexOf('?') > 0 ? '&' : '?');
      do {
        ParamConfig param = (ParamConfig)params.next();
        buf.append(URLEncoder.encode(param.getName(), encoding));
        buf.append('=');
        buf.append(URLEncoder.encode(param.getValue(), encoding));
        if (params.hasNext()) {
          buf.append('&');
        } else {
          break;
        }
      } while (true);
      // restore anchor (if any)
      if (anchor != null) {
        buf.append(anchor);
      }
      return buf.toString();
    }
    return path;
  }

  /**
   * Dispatch to specified uri.
   * If the redirection flag is set, send a redirect to the specified uri.
   * Otherwise, use a request dispatcher to dispatch to specified uri:
   * Use include, if the response is already committed, forward else.
   * In case of redirection, the path is prepended with the request context
   * path, if it starts with a slash (<code>'/'</code>).
   * @param request the request we process
   * @param response the response we process
   * @param uri context-relative path (may be an absolute URL if redirection
   * is used).
   * @param redirect use redirection flag
   * @throws IOException passed through
   * @throws ServletException passed through
   */
  protected void dispatch(HttpServletRequest request, HttpServletResponse response, String uri, boolean redirect) throws IOException, ServletException {
    if (redirect) {
      if (uri.startsWith("/")) {
        uri = request.getContextPath() + uri;
      }
      response.sendRedirect(response.encodeRedirectURL(uri));
    } else {
      RequestDispatcher dispatcher = request.getRequestDispatcher(uri);
      if (response.isCommitted()) {
        if (log.isDebugEnabled())
          log.debug("include " + uri);
        dispatcher.include(request, response);
      } else {
        if (log.isDebugEnabled())
          log.debug("forward " + uri);
        dispatcher.forward(request, response);   
      }
    }
  }
}
TOP

Related Classes of de.odysseus.calyxo.control.impl.DefaultDispatcher

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.