Package com.caucho.server.host

Source Code of com.caucho.server.host.Host

/*
* Copyright (c) 1998-2010 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source 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 2 of the License, or
* (at your option) any later version.
*
* Resin Open Source 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, or any warranty
* of NON-INFRINGEMENT.  See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
*
*   Free Software Foundation, Inc.
*   59 Temple Place, Suite 330
*   Boston, MA 02111-1307  USA
*
* @author Scott Ferguson
*/

package com.caucho.server.host;

import com.caucho.bam.*;
import com.caucho.config.ConfigException;
import com.caucho.config.SchemaBean;
import com.caucho.config.inject.InjectManager;
import com.caucho.config.inject.SingletonBean;
import com.caucho.hemp.broker.*;
import com.caucho.lifecycle.Lifecycle;
import com.caucho.loader.EnvironmentBean;
import com.caucho.loader.EnvironmentClassLoader;
import com.caucho.loader.EnvironmentLocal;
import com.caucho.make.AlwaysModified;
import com.caucho.management.server.HostMXBean;
import com.caucho.network.listen.SocketLinkListener;
import com.caucho.server.cluster.Cluster;
import com.caucho.server.cluster.Server;
import com.caucho.server.deploy.EnvironmentDeployInstance;
import com.caucho.server.dispatch.DispatchServer;
import com.caucho.server.dispatch.ExceptionFilterChain;
import com.caucho.server.dispatch.Invocation;
import com.caucho.server.resin.*;
import com.caucho.server.webapp.WebAppContainer;
import com.caucho.util.L10N;
import com.caucho.vfs.Dependency;
import com.caucho.vfs.Path;

import java.net.*;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.*;

/**
* Resin's virtual host implementation.
*/
public class Host extends WebAppContainer
  implements EnvironmentBean, Dependency, SchemaBean,
             EnvironmentDeployInstance
{
  private static final Logger log = Logger.getLogger(Host.class.getName());
  private static final L10N L = new L10N(Host.class);

  private static EnvironmentLocal<Host> _hostLocal
    = new EnvironmentLocal<Host>("caucho.host");

  private HostContainer _parent;

  // The Host entry
  private HostController _controller;

  // The canonical host name.  The host name may include the port.
  private String _hostName = "";
  // The canonical URL
  private String _url;

  private String _serverName = "";
  private int _serverPort = 0;

  // The secure host
  private String _secureHostName;

  private boolean _isDefaultHost;

  // Alises
  private ArrayList<String> _aliasList = new ArrayList<String>();

  private HempBroker _bamBroker;

  private Throwable _configException;

  private boolean _isRootDirSet;
  private boolean _isDocDirSet;

  private String _configETag = null;

  /**
   * Creates the webApp with its environment loader.
   */
  public Host(HostContainer parent, HostController controller, String hostName)
  {
    super(EnvironmentClassLoader.create("host:" + controller.getName()),
          new Lifecycle(log, "Host[" + hostName + "]", Level.INFO));

    try {
      _controller = controller;

      setParent(parent);
      setHostName(hostName);

      _hostLocal.set(this, getClassLoader());
    } catch (Exception e) {
      _configException = e;
    }
  }

  /**
   * Returns the local host.
   */
  public static Host getLocal()
  {
    return _hostLocal.get();
  }

  /**
   * Sets the canonical host name.
   */
  private void setHostName(String name)
    throws ConfigException
  {
    _hostName = name;

    if (name.equals(""))
      _isDefaultHost = true;

    addHostAlias(name);

    // getEnvironmentClassLoader().setId("host:" + name);

    // _jmxContext.put("J2EEServer", name);

    int p = name.indexOf("://");

    if (p >= 0)
      name = name.substring(p + 3);

    _serverName = name;

    p = name.lastIndexOf(':');
    if (p > 0) {
      _serverName = name.substring(0, p);

      boolean isPort = true;
      int port = 0;
      for (p++; p < name.length(); p++) {
        char ch = name.charAt(p);

        if ('0' <= ch && ch <= '9')
          port = 10 * port + ch - '0';
        else
          isPort = false;
      }

      if (isPort)
        _serverPort = port;
    }
  }

  /**
   * Returns the entry name
   */
  public String getName()
  {
    return _controller.getName();
  }

  /**
   * Returns the canonical host name.  The canonical host name may include
   * the port.
   */
  public String getHostName()
  {
    return _hostName;
  }

  /**
   * Returns the host (as an webApp container)
   */
  public Host getHost()
  {
    return this;
  }

  /**
   * Returns the secure host name.  Used for redirects.
   */
  public String getSecureHostName()
  {
    return _secureHostName;
  }

  /**
   * Sets the secure host name.  Used for redirects.
   */
  public void setSecureHostName(String secureHostName)
  {
    _secureHostName = secureHostName;
  }

  /**
   * Returns the bam broker.
   */
  public Broker getBamBroker()
  {
    return _bamBroker;
  }

  /**
   * Returns the relax schema.
   */
  public String getSchema()
  {
    return "com/caucho/server/host/host.rnc";
  }

  /**
   * Returns the URL for the container.
   */
  public String getId()
  {
    if (_url != null && ! "".equals(_url))
      return _url;
    else if (_hostName == null
             || _hostName.equals("")) {
      return getURL();
    }
    else if (_hostName.startsWith("http:")
             || _hostName.startsWith("https:"))
      return _hostName;
    else if (_hostName.equals(""))
      return "http://default";
    else
      return "http://" + _hostName;
  }

  /**
   * Returns the URL for the container.
   */
  public String getURL()
  {
    if (_url != null && ! "".equals(_url))
      return _url;
    else if (_hostName == null
             || _hostName.equals("")
             || _hostName.equals("default")) {
      Server server = getServer();

      if (server == null)
        return "http://localhost";

      for (SocketLinkListener port : server.getPorts()) {
        if ("http".equals(port.getProtocolName())) {
          String address = port.getAddress();

          if (address == null || address.equals(""))
            address = "localhost";

          return "http://" + address + ":" + port.getPort();
        }
      }

      for (SocketLinkListener port : server.getPorts()) {
        if ("https".equals(port.getProtocolName())) {
          String address = port.getAddress();
          if (address == null || address.equals(""))
            address = "localhost";

          return "https://" + address + ":" + port.getPort();
        }
      }

      return "http://localhost";
    }
    else if (_hostName.startsWith("http:")
             || _hostName.startsWith("https:"))
      return _hostName;
    else if (_hostName.equals("") || _hostName.equals("default"))
      return "http://localhost";
    else
      return "http://" + _hostName;
  }

  /**
   * Adds an alias.
   */
  public void addHostAlias(String name)
  {
    name = name.toLowerCase();

    if (! _aliasList.contains(name))
      _aliasList.add(name);

    if (name.equals("") || name.equals("*"))
      _isDefaultHost = true;


    _controller.addExtHostAlias(name);
  }

  /**
   * Gets the alias list.
   */
  public ArrayList<String> getAliasList()
  {
    return _aliasList;
  }

  /**
   * Adds an alias.
   */
  public void addHostAliasRegexp(String name)
  {
    name = name.trim();

    Pattern pattern = Pattern.compile(name, Pattern.CASE_INSENSITIVE);

    _controller.addExtHostAliasRegexp(pattern);
  }

  /**
   * Returns true if matches the default host.
   */
  public boolean isDefaultHost()
  {
    return _isDefaultHost;
  }

  /**
   * Sets the parent container.
   */
  private void setParent(HostContainer parent)
  {
    _parent = parent;

    setDispatchServer(parent.getDispatchServer());

    if (! _isRootDirSet) {
      setRootDirectory(parent.getRootDirectory());
      _isRootDirSet = false;
    }
  }

  /**
   * Gets the environment class loader.
   */
  public EnvironmentClassLoader getEnvironmentClassLoader()
  {
    return (EnvironmentClassLoader) getClassLoader();
  }

  /**
   * Sets the root dir.
   */
  public void setRootDirectory(Path rootDir)
  {
    super.setRootDirectory(rootDir);
    _isRootDirSet = true;

    if (! _isDocDirSet) {
      setDocumentDirectory(rootDir);
      _isDocDirSet = false;
    }
  }

  /**
   * Sets the doc dir.
   */
  public void setDocumentDirectory(Path docDir)
  {
    super.setDocumentDirectory(docDir);
    _isDocDirSet = true;
  }

  /**
   * Sets the config exception.
   */
  public void setConfigException(Throwable e)
  {
    if (e != null) {
      _configException = e;
      getEnvironmentClassLoader().addDependency(AlwaysModified.create());

      if (log.isLoggable(Level.FINE))
        log.log(Level.FINE, e.toString(), e);
    }
  }

  /**
   * Gets the config exception.
   */
  public Throwable getConfigException()
  {
    return _configException;
  }

  /**
   * Returns the owning server.
   */
  public Server getServer()
  {
    if (_parent != null) {
      DispatchServer server = _parent.getDispatchServer();

      if (server instanceof Server)
        return (Server) server;
    }

    return null;
  }

  /**
   * Returns the current cluster.
   */
  public Cluster getCluster()
  {
    Server server = getServer();

    if (server != null)
      return server.getCluster();
    else
      return null;
  }

  /**
   * Returns the config etag.
   */
  public String getConfigETag()
  {
    return _configETag;
  }

  /**
   * Returns the config etag.
   */
  public void setConfigETag(String etag)
  {
    _configETag = etag;
  }

  /**
   * Returns the admin.
   */
  public HostMXBean getAdmin()
  {
    return _controller.getAdmin();
  }

  /**
   * Initialization before configuration
   */
  public void preConfigInit()
  {
  }

  /**
   * Starts the host.
   */
  protected void startImpl()
  {
    if (getURL().equals("") && _parent != null) {
      _url = _parent.getURL();
    }

    EnvironmentClassLoader loader;
    loader = getEnvironmentClassLoader();

    // server/1al2
    // loader.setId("host:" + getURL());

    Thread thread = Thread.currentThread();
    ClassLoader oldLoader = thread.getContextClassLoader();

    try {
      thread.setContextClassLoader(loader);

      initBam();

      // ioc/04010
      // loader needs to start first, so Host managed beans will be
      // initialized before the webappd
      loader.start();

      super.startImpl();

      if (_parent != null)
        _parent.clearCache();
    } finally {
      thread.setContextClassLoader(oldLoader);
    }
  }

  private void initBam()
  {
    if (Resin.getCurrent() == null)
      return;

    String hostName = _hostName;

    if ("".equals(hostName)) {
      try {
        hostName = InetAddress.getLocalHost().getCanonicalHostName();
      } catch (Exception e) {
        throw ConfigException.create(e);
      }
    }

    _bamBroker = new HempBroker(hostName);

    HempBrokerManager brokerManager = HempBrokerManager.getCurrent();

    if (brokerManager != null)
      brokerManager.addBroker(hostName, _bamBroker);

    for (String alias : _aliasList) {
      _bamBroker.addAlias(alias);

      if (brokerManager != null)
        brokerManager.addBroker(alias, _bamBroker);
    }

    InjectManager webBeans = InjectManager.getCurrent();

    webBeans.addBean(webBeans.createBeanFactory(Broker.class)
                     .name("bamBroker").singleton(_bamBroker));

    webBeans.addExtension(_bamBroker);

    // XXX: webBeans.addRegistrationListener(new BamRegisterListener());
  }

  /**
   * Clears the cache
   */
  public void clearCache()
  {
    super.clearCache();

    setConfigETag(null);
  }

  /**
   * Builds the invocation for the host.
   */
  public Invocation buildInvocation(Invocation invocation)
    throws ConfigException
  {
    invocation.setHostName(_serverName);
    invocation.setPort(_serverPort);

    Thread thread = Thread.currentThread();
    ClassLoader oldLoader = thread.getContextClassLoader();

    try {
      thread.setContextClassLoader(getClassLoader());

      if (_configException == null)
        return super.buildInvocation(invocation);
      else {
        invocation.setFilterChain(new ExceptionFilterChain(_configException));
        invocation.setDependency(AlwaysModified.create());

        return invocation;
      }
    } finally {
      thread.setContextClassLoader(oldLoader);
    }
  }

  /**
   * Returns true if the host is modified.
   */
  public boolean isModified()
  {
    return (isDestroyed() || getEnvironmentClassLoader().isModified());
  }

  /**
   * Returns true if the host is modified.
   */
  public boolean isModifiedNow()
  {
    return (isDestroyed() || getEnvironmentClassLoader().isModifiedNow());
  }

  /**
   * Log the reason for modification.
   */
  public boolean logModified(Logger log)
  {
    if (isDestroyed())
      return true;
    else
      return getEnvironmentClassLoader().logModified(log);
  }

  /**
   * Returns true if the host deploy was an error
   */
  public boolean isDeployError()
  {
    return _configException != null;
  }

  /**
   * Returns true if the host is idle
   */
  public boolean isDeployIdle()
  {
    return false;
  }

  /**
   * Stops the host.
   */
  public boolean stop()
  {
    Thread thread = Thread.currentThread();
    ClassLoader oldLoader = thread.getContextClassLoader();

    try {
      EnvironmentClassLoader envLoader = getEnvironmentClassLoader();
      thread.setContextClassLoader(envLoader);

      if (! _lifecycle.toStopping())
        return false;

      super.stop();

      if (_bamBroker != null)
        _bamBroker.close();

      envLoader.stop();

      return true;
    } finally {
      _lifecycle.toStop();

      thread.setContextClassLoader(oldLoader);
    }
  }

  /**
   * Closes the host.
   */
  public void destroy()
  {
    stop();

    if (isDestroyed())
      return;

    Thread thread = Thread.currentThread();
    ClassLoader oldLoader = thread.getContextClassLoader();
    EnvironmentClassLoader classLoader = getEnvironmentClassLoader();

    thread.setContextClassLoader(classLoader);

    try {
      super.destroy();
    } finally {
      thread.setContextClassLoader(oldLoader);

      classLoader.destroy();
    }
  }

  public String toString()
  {
    return getClass().getSimpleName() + "[" + getHostName() + "]";
  }
}
TOP

Related Classes of com.caucho.server.host.Host

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.