001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.apache.hadoop.lib.servlet;
020
021import org.apache.hadoop.conf.Configuration;
022import org.apache.hadoop.lib.server.Server;
023import org.apache.hadoop.lib.server.ServerException;
024
025import javax.servlet.ServletContextEvent;
026import javax.servlet.ServletContextListener;
027import java.text.MessageFormat;
028
029/**
030 * {@link Server} subclass that implements <code>ServletContextListener</code>
031 * and uses its lifecycle to start and stop the server.
032 */
033public abstract class ServerWebApp extends Server implements ServletContextListener {
034
035  private static final String HOME_DIR = ".home.dir";
036  private static final String CONFIG_DIR = ".config.dir";
037  private static final String LOG_DIR = ".log.dir";
038  private static final String TEMP_DIR = ".temp.dir";
039
040  private static ThreadLocal<String> HOME_DIR_TL = new ThreadLocal<String>();
041
042  /**
043   * Method for testing purposes.
044   */
045  public static void setHomeDirForCurrentThread(String homeDir) {
046    HOME_DIR_TL.set(homeDir);
047  }
048
049  /**
050   * Constructor for testing purposes.
051   */
052  protected ServerWebApp(String name, String homeDir, String configDir, String logDir, String tempDir,
053                         Configuration config) {
054    super(name, homeDir, configDir, logDir, tempDir, config);
055  }
056
057  /**
058   * Constructor for testing purposes.
059   */
060  protected ServerWebApp(String name, String homeDir, Configuration config) {
061    super(name, homeDir, config);
062  }
063
064  /**
065   * Constructor. Subclasses must have a default constructor specifying
066   * the server name.
067   * <p/>
068   * The server name is used to resolve the Java System properties that define
069   * the server home, config, log and temp directories.
070   * <p/>
071   * The home directory is looked in the Java System property
072   * <code>#SERVER_NAME#.home.dir</code>.
073   * <p/>
074   * The config directory is looked in the Java System property
075   * <code>#SERVER_NAME#.config.dir</code>, if not defined it resolves to
076   * the <code>#SERVER_HOME_DIR#/conf</code> directory.
077   * <p/>
078   * The log directory is looked in the Java System property
079   * <code>#SERVER_NAME#.log.dir</code>, if not defined it resolves to
080   * the <code>#SERVER_HOME_DIR#/log</code> directory.
081   * <p/>
082   * The temp directory is looked in the Java System property
083   * <code>#SERVER_NAME#.temp.dir</code>, if not defined it resolves to
084   * the <code>#SERVER_HOME_DIR#/temp</code> directory.
085   *
086   * @param name server name.
087   */
088  public ServerWebApp(String name) {
089    super(name, getHomeDir(name),
090          getDir(name, CONFIG_DIR, getHomeDir(name) + "/conf"),
091          getDir(name, LOG_DIR, getHomeDir(name) + "/log"),
092          getDir(name, TEMP_DIR, getHomeDir(name) + "/temp"), null);
093  }
094
095  /**
096   * Returns the server home directory.
097   * <p/>
098   * It is looked up in the Java System property
099   * <code>#SERVER_NAME#.home.dir</code>.
100   *
101   * @param name the server home directory.
102   *
103   * @return the server home directory.
104   */
105  static String getHomeDir(String name) {
106    String homeDir = HOME_DIR_TL.get();
107    if (homeDir == null) {
108      String sysProp = name + HOME_DIR;
109      homeDir = System.getProperty(sysProp);
110      if (homeDir == null) {
111        throw new IllegalArgumentException(MessageFormat.format("System property [{0}] not defined", sysProp));
112      }
113    }
114    return homeDir;
115  }
116
117  /**
118   * Convenience method that looks for Java System property defining a
119   * diretory and if not present defaults to the specified directory.
120   *
121   * @param name server name, used as prefix of the Java System property.
122   * @param dirType dir type, use as postfix of the Java System property.
123   * @param defaultDir the default directory to return if the Java System
124   * property <code>name + dirType</code> is not defined.
125   *
126   * @return the directory defined in the Java System property or the
127   *         the default directory if the Java System property is not defined.
128   */
129  static String getDir(String name, String dirType, String defaultDir) {
130    String sysProp = name + dirType;
131    return System.getProperty(sysProp, defaultDir);
132  }
133
134  /**
135   * Initializes the <code>ServletContextListener</code> which initializes
136   * the Server.
137   *
138   * @param event servelt context event.
139   */
140  public void contextInitialized(ServletContextEvent event) {
141    try {
142      init();
143    } catch (ServerException ex) {
144      event.getServletContext().log("ERROR: " + ex.getMessage());
145      throw new RuntimeException(ex);
146    }
147  }
148
149  /**
150   * Destroys the <code>ServletContextListener</code> which destroys
151   * the Server.
152   *
153   * @param event servelt context event.
154   */
155  public void contextDestroyed(ServletContextEvent event) {
156    destroy();
157  }
158
159}