Package org.emrys.webosgi.launcher.internal

Source Code of org.emrys.webosgi.launcher.internal.DefaultBridgeHttpServlet$ExtensionMappingRequest

package org.emrys.webosgi.launcher.internal;

import java.io.IOException;
import java.lang.reflect.Method;
import java.rmi.ServerException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.emrys.webosgi.launcher.internal.adapter.HttpServletRequestAdapter;
import org.emrys.webosgi.launcher.internal.adapter.HttpServletResponseAdapter;
import org.emrys.webosgi.launcher.internal.adapter.ServletContextAdapter;


/**
* Default implementation of Bridget Http Servlet for OSGi Java EE Framework.
*
* @author LeoChang
*
*/
public abstract class DefaultBridgeHttpServlet extends HttpServlet {

  private static final long serialVersionUID = 1697892540453511903L;

  private Object fwkDelegateServlet;
  private ServletConfig config;
  private int delegateReferenceCount;
  private boolean isFwkLaunchedByOther;
  protected FwkExternalAgent fwkAgent;

  private static boolean isJeeContainerInitialized;

  private static boolean isJeeContainerInitializing;

  @Override
  public void init(ServletConfig config) throws ServletException {
    super.init(config);

    fwkAgent = FwkExternalAgent.getInstance();

    // Check if the fwk has been launched by another launcher to skip.
    ServletContextAdapter fwkServletCtxAdapter = fwkAgent
        .getFwkServletContext(FwkExternalAgent.SERVLET_TYPE_HTTP);
    if (fwkServletCtxAdapter != null) {
      isFwkLaunchedByOther = true;
      return;
    }

    this.config = config;
    ServletContext fwkServletCtx = config.getServletContext();
    ServletContextAdapter servletCtxAdapter = new ServletContextAdapter(
        fwkServletCtx);
    fwkAgent.setFwkServletContext(FwkExternalAgent.SERVLET_TYPE_HTTP,
        servletCtxAdapter);

    try {
      IFwkLauncher fwkLauncher = getFwkLauncher();
      fwkLauncher.init(getServletConfig());
      fwkLauncher.deploy();
      fwkLauncher.start();
    } catch (Exception e) {
      throw new ServletException("Framework start failed.", e);
    }
  }

  public abstract IFwkLauncher getFwkLauncher();

  public boolean isFwkLaunchedByOther() {
    return isFwkLaunchedByOther;
  }

  @Override
  public void destroy() {
    // Is OK to ignore uncompleted requests(the delegate servlet reference
    // count > 0)?
    getFwkLauncher().stop();
    getFwkLauncher().destroy();
    super.destroy();
  }

  @Override
  public ServletConfig getServletConfig() {
    // More customized configuration here...
    return config;
  }

  @Override
  public String getServletInfo() {
    return super.getServletInfo()
        + "/Bridge Servlet for OSGi JavaEE Container 1.0.0";
  }

  /**
   * service is called by the Servlet Container and will first determine if
   * the request is a framework control and will otherwise try to delegate to
   * the registered servlet delegate
   *
   */
  @Override
  protected void service(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    // If framework has been launched by another launcher, return
    // NOT_FOUND http status.
    if (isFwkLaunchedByOther()) {
      resp.sendError(HttpServletResponse.SC_NOT_FOUND);
      return;
    }

    // To support both servlet 2.4/2.5 server(here domino8/servlet2.5),
    // adapt all servlet resources on the entrance of framework.
    HttpServletRequestAdapter newReq = new ExtensionMappingRequest(req);
    HttpServletResponseAdapter newResp = new HttpServletResponseAdapter(
        resp);

    Object servletReference = acquireDelegateReference();
    if (servletReference == null) {
      resp
          .sendError(
              HttpServletResponse.SC_NOT_FOUND,
              "Framework Servlet Delegate not found for: " + newReq.getRequestURI()); //$NON-NLS-1$
      return;
    }

    // Buffer the original thread context class loader and ready to invoke
    // framework objecct. For framework may change this.
    ClassLoader original = Thread.currentThread().getContextClassLoader();
    try {
      if (!isJeeContainerInitialized) {
        // If the delegate servlet is initializing, wait.
        while (isJeeContainerInitializing) {
          Thread.sleep(20);
        }
        // If the JavaEE Container not initilaized yet, do it at first.
        Method method = servletReference.getClass().getMethod(
            "isInitialized");
        isJeeContainerInitialized = (Boolean) method
            .invoke(servletReference);
        if (!isJeeContainerInitialized) {
          isJeeContainerInitializing = true;
          try {
            // Set several attributes which can only be retrieved
            // when
            // the
            // first request comes.
            // Servlet Context path(for in JavaEE 2.4,
            // ServletContext.getContextPath() not available).
            String fwkServletCtxPath = getSpecifiedContextPath();
            if (fwkServletCtxPath == null)
              fwkServletCtxPath = req.getContextPath();

            fwkAgent.setFwkEvnAttribute(
                FwkExternalAgent.ATTR_FWK_SERVLET_CTX_PATH,
                fwkServletCtxPath);
            fwkAgent.getFwkServletContext(
                FwkExternalAgent.SERVLET_TYPE_HTTP)
                .setContextPath(fwkServletCtxPath);
            // Set Server host and port
            fwkAgent.setFwkEvnAttribute(
                FwkExternalAgent.ATTR_WEB_APP_HOST, req
                    .getServerName());
            fwkAgent.setFwkEvnAttribute(
                FwkExternalAgent.ATTR_WEB_APP_PORT, req
                    .getServerPort());

            method = servletReference.getClass().getMethod("init");
            method.invoke(servletReference);
          } finally {
            isJeeContainerInitializing = false;
          }
        }
      }

      // Dispatch the request to JavaEE Containe inside framework.
      Method serviceMethod = servletReference.getClass().getMethod(
          "service", HttpServletRequestAdapter.class,
          HttpServletResponseAdapter.class);
      serviceMethod.invoke(servletReference, newReq, newResp);
    } catch (Exception e) {
      e.printStackTrace();
      throw new ServerException(
          "Invoke serivce method from Delegate Servlet failed.", e);
    } finally {
      releaseDelegateReference();
      Thread.currentThread().setContextClassLoader(original);
    }
  }

  protected String getSpecifiedContextPath() {
    return null;
  }

  private void releaseDelegateReference() {
    --delegateReferenceCount;
  }

  private Object acquireDelegateReference() {
    if (fwkDelegateServlet == null)
      fwkDelegateServlet = fwkAgent
          .getFwkDelegateServlet(FwkExternalAgent.SERVLET_TYPE_HTTP);
    if (fwkDelegateServlet != null)
      ++delegateReferenceCount;
    return fwkDelegateServlet;
  }

  static class ExtensionMappingRequest extends HttpServletRequestAdapter {

    public ExtensionMappingRequest(HttpServletRequest req) {
      super(req);
    }

    @Override
    public String getPathInfo() {
      // Let the pathInfo be empty string. Tomcat6's hehavior is to set it
      // null.
      return null;//$NON-NLS-1$
    }

    @Override
    public String getServletPath() {
      // At the entrance of JEE OSGi Container, use the pathInfo as
      // servlet path.
      return super.getPathInfo();
    }
  }
}
TOP

Related Classes of org.emrys.webosgi.launcher.internal.DefaultBridgeHttpServlet$ExtensionMappingRequest

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.