#!/bin/bash
# or
#!/bin/ksh
##
## Apache Tomcat Instance Manager
## Copyright (c) 2015-2016 SATOH Fumiyasu @ OSS Technology Corp., Japan
##
## License: Apache License version 2.0
##

set -u
umask 0022

perr()
{
  echo "$0: ERROR: $1" 1>&2
}

pdie()
{
  perr "$1"
  exit "${2-1}"
}

## ======================================================================

setuidgid="/opt/osstech/bin/setuidgid"

instance_base="/opt/osstech/var/lib"
instance_name="tomcat"
catalina_home="${CATALINA_HOME-/usr/share/tomcat6}"
java_home="${JAVA_HOME-/usr/lib/jvm/jre-openjdk}"
tomcat_user="${TOMCAT_USER-tomcat}"

true='@(true|yes|on|1)'

## ----------------------------------------------------------------------

instance_cmd="$1"; shift
[[ $# -ge 1 ]] && { instance_name="$1"; shift; }

if [[ $instance_name == /* ]]; then
  catalina_base="$instance_name"
else
  catalina_base="$instance_base/$instance_name"
fi

tomcat_conf="$catalina_base/conf/tomcat.conf"
tomcat_conf_dir="$catalina_base/conf/tomcat.conf.d"

## ----------------------------------------------------------------------

unset LANG
unset HOME

CATALINA_HOME="$catalina_home"
CATALINA_BASE="$catalina_base"
CATALINA_OPTS=""
TOMCAT_USER="$tomcat_user"
JAVA_HOME="$java_home"
JAVA_OPTS="-Djava.awt.headless=true -Xmx128M"
JAVA_ENDORSED_DIRS=""
unset JAVA_TOOL_OPTIONS
unset _JAVA_OPTIONS
JPDA="false"
JPDA_TRANSPORT="dt_socket"
JPDA_ADDRESS="8000"
JPDA_SUSPEND="n"
LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"
LOGGING_CONFIG=""
SECURITY_MANAGER="false"

set -e
if [[ -f $tomcat_conf ]]; then
  . "$tomcat_conf"
fi
for tomcat_conf_dir_file in "$tomcat_conf_dir"/*.conf; do
  if [[ -f $tomcat_conf_dir_file ]]; then
    . "$tomcat_conf_dir_file"
  fi
done
set +e

: ${HOME:="$CATALINA_BASE"}
: ${CATALINA_TMPDIR:="$CATALINA_BASE/temp"}
: ${CATALINA_OUT:="$CATALINA_BASE/logs/catalina.out"}
: ${JRE_HOME:="$JAVA_HOME"}
: ${JAVA_PATH:="$JRE_HOME/bin/java"}
: ${JAVA_ENDORSED_DIRS:="$CATALINA_HOME/endorsed"}
: ${JPDA_OPTS:="-agentlib:jdwp=transport=$JPDA_TRANSPORT,address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND"}

JAVA_OPTS="${JAVA_OPTS:+$JAVA_OPTS }-Duser.home=$HOME"

CLASSPATH="$CATALINA_HOME/bin/bootstrap.jar"
if [[ -f $CATALINA_BASE/bin/tomcat-juli.jar ]]; then
  CLASSPATH="$CATALINA_BASE/bin/tomcat-juli.jar:$CLASSPATH"
else
  CLASSPATH="$CATALINA_HOME/bin/tomcat-juli.jar:$CLASSPATH"
fi

if [[ -z $LOGGING_CONFIG ]]; then
  if [[ -f $CATALINA_BASE/conf/logging.properties ]]; then
    LOGGING_CONFIG="-Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties"
  else
    LOGGING_CONFIG="-Dnop"
  fi
fi

## ----------------------------------------------------------------------

args=()

args+=(
  "$LOGGING_MANAGER"
  "$LOGGING_CONFIG"
)

if [[ $JPDA == $true ]]; then
  args+=("$JPDA_OPTS")
fi

if [[ $SECURITY_MANAGER == $true ]]; then
  args+=(
    -Djava.security.manager
    -Djava.security.policy=="$CATALINA_BASE/conf/catalina.policy"
  )
fi

## ======================================================================

java_class="org.apache.catalina.startup.Bootstrap"
java_class_args="$instance_cmd"

case $instance_cmd in
start|stop)
  ;;
run)
  java_class_args="start"
  ;;
version)
  java_class="org.apache.catalina.util.ServerInfo"
  java_class_args=
  CLASSPATH="$CATALINA_HOME/lib/catalina.jar"
  ;;
*)
  pdie "Invalid command: $instance_cmd"
  ;;
esac

## ----------------------------------------------------------------------

wrappers=(
  /usr/bin/env
    -
    LANG="${LANG-en_US.UTF-8}"
    ${TZ+TZ="$TZ"}
    ${PATH+PATH="$PATH"}
    ${JAVA_HOME+JAVA_HOME="$JAVA_HOME"}
    ${JAVA_TOOL_OPTIONS+JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS"}
    ${_JAVA_OPTIONS+_JAVA_OPTIONS="$_JAVA_OPTIONS"}
  "$setuidgid"
    "$TOMCAT_USER"
)

args=(
  "$JAVA_PATH"
    $JAVA_OPTS
    $CATALINA_OPTS
    -classpath "$CLASSPATH"
    -Dcatalina.base="$CATALINA_BASE"
    -Dcatalina.home="$CATALINA_HOME"
    -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS"
    -Djava.io.tmpdir="$CATALINA_TMPDIR"
    "${args[@]}"
    "$java_class"
    $java_class_args
)

if [[ -t 1 ]]; then
  echo "CATALINA_BASE:   $CATALINA_BASE"
  echo "CATALINA_HOME:   $CATALINA_HOME"
  echo "CATALINA_TMPDIR: $CATALINA_TMPDIR"
  echo "JAVA_HOME:       $JAVA_HOME"
  echo "JRE_HOME:        $JRE_HOME"
  echo "CLASSPATH:       $CLASSPATH"
  echo "Command line:"
  for wrapper in "${wrappers[@]}"; do
    echo "  $wrapper \\"
  done
  for arg in "${args[@]}"; do
    echo "  $arg \\"
  done
  echo "  ;"
fi

## ----------------------------------------------------------------------

cd "$CATALINA_BASE" || exit 1

case $instance_cmd in
run)
  exec "${wrappers[@]}" /bin/sh \
    -c 'out="$1"; shift; [[ -t 1 ]] || exec >>"$out" 2>&1 || exit 1; exec "$@"' \
    "$0 run: /bin/sh" \
    "$CATALINA_OUT" \
    "${args[@]}" \
  ;
  exit $?
  ;;
start)
  "${wrappers[@]}" /bin/sh \
    -c 'out="$1"; shift; exec "$@" >>"$out" 2>&1 </dev/null' \
    "$0 start: /bin/sh" \
    "$CATALINA_OUT" \
    "${args[@]}" \
  &
  exit $?
  ;;
esac

"${wrappers[@]}" "${args[@]}"
exit $?

