Home » geronimo-2.2-source-release » org.apache.geronimo.console.servlet » [javadoc | source]

    1   /**
    2    *  Licensed to the Apache Software Foundation (ASF) under one or more
    3    *  contributor license agreements.  See the NOTICE file distributed with
    4    *  this work for additional information regarding copyright ownership.
    5    *  The ASF licenses this file to You under the Apache License, Version 2.0
    6    *  (the "License"); you may not use this file except in compliance with
    7    *  the License.  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    *  Unless required by applicable law or agreed to in writing, software
   12    *  distributed under the License is distributed on an "AS IS" BASIS,
   13    *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    *  See the License for the specific language governing permissions and
   15    *  limitations under the License.
   16    */
   17   package org.apache.geronimo.console.servlet;
   18   
   19   import org.slf4j.Logger;
   20   import org.slf4j.LoggerFactory;
   21   import org.apache.geronimo.console.gbean.ContextForward;
   22   import org.apache.geronimo.gbean.AbstractName;
   23   import org.apache.geronimo.gbean.AbstractNameQuery;
   24   import org.apache.geronimo.kernel.Kernel;
   25   import org.apache.geronimo.kernel.KernelRegistry;
   26   import org.apache.geronimo.kernel.lifecycle.LifecycleAdapter;
   27   import org.apache.geronimo.kernel.lifecycle.LifecycleListener;
   28   
   29   import javax.servlet.RequestDispatcher;
   30   import javax.servlet.ServletConfig;
   31   import javax.servlet.ServletContext;
   32   import javax.servlet.ServletException;
   33   import javax.servlet.http.HttpServlet;
   34   import javax.servlet.http.HttpServletRequest;
   35   import javax.servlet.http.HttpServletResponse;
   36   import java.io.IOException;
   37   import java.util.HashMap;
   38   import java.util.Iterator;
   39   import java.util.Map;
   40   import java.util.Set;
   41   
   42   /**
   43    * Servlet that forwards GET and POST requests to a servlet in an alternate
   44    * context. The servlet path and alternate context are defined in GBeans of
   45    * type ContextForward, and this one servlet handles the forwarding for all
   46    * those different paths.
   47    *
   48    * NOTE: This does not work for DWR, because it changes the request path info
   49    * while forwarding, and DWR requires the exact initial request info in order
   50    * to construct URLs in the data that it returns.  It should work to forward
   51    * to most typical servlets, JSPs, and static content.
   52    */
   53   public class GenericForwardServlet extends HttpServlet {
   54       private static final Logger log = LoggerFactory.getLogger(GenericForwardServlet.class);
   55       private Map forwards = new HashMap(); // Maps a prefix String to ForwardData
   56       private Kernel kernel;
   57       private LifecycleListener listener;
   58   
   59       public void init(ServletConfig config) throws ServletException {
   60           super.init(config);
   61   
   62           kernel = KernelRegistry.getSingleKernel();
   63           AbstractNameQuery query = new AbstractNameQuery(ContextForward.class.getName());
   64           Set set = kernel.listGBeans(query);
   65           for (Iterator it = set.iterator(); it.hasNext();) {
   66               AbstractName name = (AbstractName) it.next();
   67               addGBean(name);
   68           }
   69           kernel.getLifecycleMonitor().addLifecycleListener(listener = new LifecycleAdapter() {
   70               public void running(AbstractName abstractName) {
   71                   addGBean(abstractName);
   72               }
   73   
   74               public void stopping(AbstractName abstractName) {
   75                   removeGBean(abstractName);
   76               }
   77   
   78               public void stopped(AbstractName abstractName) {
   79                   removeGBean(abstractName);
   80               }
   81   
   82               public void failed(AbstractName abstractName) {
   83                   removeGBean(abstractName);
   84               }
   85   
   86               public void unloaded(AbstractName abstractName) {
   87                   removeGBean(abstractName);
   88               }
   89           }, query);
   90       }
   91   
   92       public void destroy() {
   93           if(listener != null) {
   94               kernel.getLifecycleMonitor().removeLifecycleListener(listener);
   95               listener = null;
   96           }
   97       }
   98   
   99       private void addGBean(AbstractName name) {
  100           ContextForward forward = (ContextForward) kernel.getProxyManager().createProxy(name, ContextForward.class);
  101           forwards.put(forward.getPortalPathPrefix(), new ForwardData(forward.getPortletContextPath(), 
  102                                                                       forward.getPortletServletPath(), 
  103                                                                       name));
  104       }
  105   
  106       private void removeGBean(AbstractName name) {
  107           for (Iterator it = forwards.entrySet().iterator(); it.hasNext();) {
  108               Map.Entry entry = (Map.Entry) it.next();
  109               ForwardData data = (ForwardData) entry.getValue();
  110               if(data.getGbean().equals(name)) {
  111                   it.remove();
  112                   break;
  113               }
  114           }
  115       }
  116   
  117       public void doGet(HttpServletRequest req, HttpServletResponse resp)
  118               throws ServletException, IOException {
  119           doPost(req, resp);
  120       }
  121   
  122       public void doPost(HttpServletRequest req, HttpServletResponse resp)
  123               throws ServletException, IOException {
  124           String path = req.getPathInfo();
  125           if(path == null) {
  126               log.error("Unable to forward request; no path information provided.  Path is used to identify where to forward to.");
  127               throw new ServletException("Unable to forward request");
  128           }
  129           ForwardData forward = null;
  130           for (Iterator it = forwards.keySet().iterator(); it.hasNext();) {
  131               String prefix = (String) it.next();
  132               if(path.startsWith(prefix)) {
  133                   forward = (ForwardData) forwards.get(prefix);
  134                   path = path.substring(prefix.length());
  135                   break;
  136               }
  137           }
  138           if(forward == null) {
  139               log.error("Unable to forward URL "+path+"; does not match any known ContextForward definitions.");
  140               throw new ServletException("Unable to forward request");
  141           }
  142           if(!path.equals("") && !path.startsWith("/")) path = "/"+path;
  143           String queryString = req.getQueryString();
  144           if (queryString != null) {
  145               path += "?" + queryString;
  146           }
  147           path = forward.getServletPath()+path;
  148           ServletContext ctx = forward.getForwardContext(getServletContext());
  149           if (ctx == null) {
  150               log.error("Unable to forward URL " + path + ". Context not found: " + forward.getContextPath());
  151               throw new ServletException("Unable to forward request");
  152           }
  153           RequestDispatcher dispatcher = ctx.getRequestDispatcher(path);
  154           dispatcher.forward(req, resp);
  155       }
  156   
  157       private static class ForwardData {
  158           private String contextPath;
  159           private String servletPath;
  160           private AbstractName gbean;
  161   
  162           public ForwardData(String contextPath, String servletPath, AbstractName gbean) {
  163               this.contextPath = contextPath;
  164               this.servletPath = servletPath;
  165               this.gbean = gbean;
  166           }
  167   
  168           public ServletContext getForwardContext(ServletContext ctx) {
  169               return ctx.getContext(contextPath);
  170           }
  171           
  172           public String getContextPath() {
  173               return contextPath;
  174           }
  175   
  176           public String getServletPath() {
  177               return servletPath;
  178           }
  179   
  180           public AbstractName getGbean() {
  181               return gbean;
  182           }
  183       }
  184   }

Home » geronimo-2.2-source-release » org.apache.geronimo.console.servlet » [javadoc | source]