#!/bin/sh
#
# NAME:
#	java_wrapper.sh - portable java wrapper
#
# DESCRIPTION:
#	This wrapper invokes java, kaffe or netscape as a
#	java runtime environment.  Simply invoke it as 'java', 'javac',
#	'appletviewer', 'rmic' ... and it will DTRT (Do The Right Thing).
#	Set "JDK" in the envronment to pick which JDK version you want
#	(otherwise it defaults to the highest installed version).
#
#	Unless we can find 'java' somewhere under jdk"JDK"/bin/"proc"
#	(where "proc" is the processor we are running on) we assume
#	that the jdk is not directly usable and go look for 'kaffe'
#	etc.  Set "JVM" in the environment to force use of something
#	other than what we would otherwise determine.
#
#	Astute readers will note that we look for 'kaffe-'"$JDK" before
#	we look for plain 'kaffe'.  This allows us to run multiple
#	versions.
#
#	We install 'kaffe-0.8.4' as 'kaffe-1.0.2' since it can handle
#	the jdk1.0.2 classes and compiler ok, while we install the
#	latest jdk1.1.x compliant 'kaffe' as well.  In order for
#	'kaffe-1.0.2' to work, we install its libs in '/usr/local/lib' as
#	normal but make the '*.so' links which the runtime looks for
#	in '/usr/local/share/kaffe-1.0.2/lib'. For example:
#.nf
#
#	/usr/local/share/kaffe-1.0.2/lib/libkaffe_native.so ->
#		/usr/local/lib/libkaffe_native.so.0.84
#.fi
#
#	To aid in debugging JDK ports, if run as 'gdb*' we setup the
#	environment and instead of directly running the JVM we run it
#	(${JVM}_g if available) via $GDB (gdb).
#
# BUGS:
#	In order for the above to work, we also need to install the
#	kaffe-0.9.x libs as '*.so.1.9x' so that kaffe-0.8.4 does not
#	load them.  The kaffe stuff is all seriously out of date.
#
#	We go to all this bother so that /share/bin/java etc can
#	simply point at this wrapper and the best JVM for a given
#	system will be invoked.  Preference is given to a real JDK.
#	
# AUTHOR:
#	Simon J. Gerraty <sjg@crufty.net>

# RCSid:
#	$Id: java_wrapper.sh,v 1.19 2002/06/22 05:30:27 sjg Exp $
#
#	@(#)Copyright (c) 1996-2002 Simon J. Gerraty
#
#	This file is provided in the hope that it will
#	be of use.  There is absolutely NO WARRANTY.
#	Permission to copy, redistribute or otherwise
#	use this file is hereby granted provided that 
#	the above copyright notice and this notice are
#	left intact. 

Myname=`basename $0 .sh`

case $Myname in
java_wrapper) Myname=java;;
esac

ttype=
vmtype=
opts=
args=
Dopts=

# these are the main functions we know about
# you can add extras in .java_wrapperrc
appletviewer_main=sun.applet.AppletViewer
javac_main=sun.tools.javac.Main
javadoc_main=main=sun.tools.javadoc.Main
jdb_main="-debuggable main=sun.tools.ttydebug.TTY"
javac_g_main="-verbosegc main=sun.tools.javac.Main"
jar_main=sun.tools.jar.Main
serialver_main=sun.tools.serialver.SerialVer
rmiregistry_main=sun.rmi.registry.RegistryImpl
rmic_main=sun.rmi.rmic.Main
native2ascii_main=sun.tools.native2ascii.Main
javap_main=sun.tools.javap.JavaP
javakey_main=sun.security.provider.Main

Mydir=`dirname $0`
OS=${OS:-`uname`}
OSREL=${OSREL:-`uname -r`}
# this is where I put it
JAVA_TOP=${JAVA_TOP:-/share/java}

rc=.java_wrapperrc

if test -s /etc/add_path.sh; then
	. /etc/add_path.sh
else
	# this lets us look for sparc/java along $PATH
	Which() {
	case "$1" in
	-*) t=$1; shift;;
	*) t=-x;;
	esac
	case "$1" in
	/*)	test $t $1 && echo $1;;
	*)
		for d in `IFS=:; echo ${2:-$PATH}`
		do
			test $t $d/$1 && { echo $d/$1; break; }
		done
		;;
	esac
	}

	add_path () { case "$1" in -*) t=$1; shift;; *) t=-d;; esac; [ $t $1 ] && eval ${2:-PATH}="\$${2:-PATH}:$1"; }
	pre_path () { case "$1" in -*) t=$1; shift;; *) t=-d;; esac; [ $t $1 ] && eval ${2:-PATH}="$1:\$${2:-PATH}"; }
	del_path () { eval ${2:-PATH}=`eval echo :'$'${2:-PATH}: | 
		sed -e "s;:$1:;:;g" -e "s;^:;;" -e "s;:\$;;"`; }
fi

rc=.java_wrapperrc
_rc=`Which -s $rc $Mydir:${JAVA_TOP}:/etc`
test "$_rc" && . $_rc
test -s ./$rc && . ./$rc

eval main="\$${Myname}_main"

GetJDK() {
	# we don't find the JVM this way as we may be
	# the wrong platform...
	for d in ${JAVA_TOP} /usr/local/share/java /usr/local/java
	do
		jvm=`/bin/ls -1 $d/jdk*/bin/java 2>/dev/null | tail -1`
		test "$jvm" && break
	done
	echo $jvm | sed 's,.*/jdk\([^/]*\)/bin/java,\1,'
}

JDK=${JDK:-`GetJDK`}

proc=`uname -p 2>/dev/null`
proc=${proc:-`uname -m`}

# we use this to compensate for lack of getpid() in java
Dopts="$Dopts -Dos.pid=$$"

JVM=${JVM:-`Which java ${JAVA_TOP}/jdk$JDK/jre/bin/$proc/native_threads:${JAVA_TOP}/jdk$JDK/jre/bin/$proc/green_threads:${JAVA_TOP}/jdk$JDK/jre/bin/$proc`}
JVM=${JVM:-`Which java ${JAVA_TOP}/jdk$JDK/bin/$proc/native_threads:${JAVA_TOP}/jdk$JDK/bin/$proc/green_threads:${JAVA_TOP}/jdk$JDK/bin/$proc`}
JVM=${JVM:-`Which $proc/java $HOME/java/bin:${JAVA_TOP}/jdk$JDK/bin:/usr/local/share/java/bin:$PATH`}

# find a JVM 
for jvm in $JAVA kaffe-$JDK kaffe netscape
do
	JVM=${JVM:-`Which $jvm`}
	test "$JVM" && break
done

case "$JVM" in
"")	echo "$Myname: no Java JVM available" >&2; exit 1;;
*/netscape*)	opts="-java $opts";;
*/kaffe*)
	k=`basename $JVM`
	KAFFEHOME=${KAFFEHOME:-/usr/local/share/$k}; export KAFFEHOME
	jre=$KAFFEHOME
	pre_path /usr/local/share/$k/lib LD_LIBRARY_PATH
	;;
*/bin/$proc/*)
	# real JDK installation
	# handles 1.1.x, 1.2 and 1.3
	jre=`echo $JVM | sed 's,\(.*\)/bin.*,\1,'`
	# The linux 1.3.1 jre needs to see this
	APPHOME=`cd $jre/..; pwd`; export APPHOME
	case $JVM in
	*/native_thread*)
		ttype=native_threads;;
	*)	ttype=green_threads;;
	esac
	case "$1" in
	-hotspot)	vmtype=hotspot; ttype=native_threads; shift;;
	-native)	vmtype=classic; ttype=native_threads; shift;;
	-green)		vmtype=classic; ttype=green_threads; shift;;
	-classic)	vmtype=classic; ttype=${DEFAULT_THREADS_FLAGS:-green}_threads; shift;;
	*)
		# the first non-comment entry is the default vmtype
		if [ -s ${jre}/lib/jvm.cfg ]; then
		    vmtype=`sed -n -e '/^-/s/^-//p' -e '/^[a-z]/q' ${jre}/lib/jvm.cfg`
                    case "$vmtype" in
		    classic) ttype=green_threads;;
		    esac
		elif [ -d ${jre}/lib/${proc}/hotspot ]; then
		    vmtype=hotspot
		    ttype=native_threads
		else
		    vmtype=classic
		fi
		ttype=${ttype:-${DEFAULT_THREADS_FLAGS:-green}_threads}
                ;;
	esac
	case "$vmtype" in
	classic)
	    case "$OS$OSREL" in
	    FreeBSD2*) # LD_BIND_NOW does not work.
		;;
	    *)
		case "$ttype" in
		green*) LD_BIND_NOW=yes; export LD_BIND_NOW;;
		esac
		;;
	    esac
		_JVM_THREADS_TYPE="${ttype}"
		THREADS_TYPE="${ttype}"
		export _JVM_THREADS_TYPE THREADS_TYPE
		;;
	esac
	jvm=$jre/bin/$proc/$ttype/$Myname
	# FreeBSD has a java_X as well as plain java.
	for j in ${DISPLAY:+${jvm}_X} $jvm
	do
	    if [ -x $j ]; then
		JVM=$j
		main=
		case $Myname in
		java|java_g) ;;
		*)	Dopts=;;# avoid upsetting javac
		esac
		break
	    fi
	done
#	opts="$opts -$vmtype"
	;;
*)
	jre=`echo $JVM | sed 's,\(.*\)/bin.*,\1,'`
	;;
esac
jre=${jre:-$JAVA_HOME}

pre_path ${jre}/lib/${proc} LD_LIBRARY_PATH
pre_path ${jre}/lib/${proc}/${vmtype} LD_LIBRARY_PATH
pre_path ${jre}/lib/${proc}/${ttype} LD_LIBRARY_PATH
case "$jre" in
*/jre*) add_path ${jre}/../lib/${proc} LD_LIBRARY_PATH;;
esac
add_path /usr/local/lib LD_LIBRARY_PATH

if [ -d ${jre}/lib/locale ]; then
    XFILESEARCHPATH="${jre}/lib/locale/%L/%T/%N%S:$XFILESEARCHPATH"
    export XFILESEARCHPATH
fi

setCLASSPATH() {
	add_path ${JAVA_TOP}/lib CLASSPATH
	add_path ${JAVA_TOP}/classes CLASSPATH
	case "$JVM" in
	*kaffe*)
		add_path ${JAVA_TOP}/biss/lib CLASSPATH
		x=`Which -s biss.zip $jre:$jre/lib:$CLASSPATH`
		test "$x" && CLASSPATH="$CLASSPATH:$x"
		;;
	esac
	JVMdir=`dirname $JVM`
	cl="$JAVA_HOME:$JVMdir/..:$JVMdir/../..:$JVMdir/../../..:${JAVA_TOP}/jdk$JDK:$HOME/java:/usr/local/share/java"
	x=`Which -s lib/classes.zip $cl`
	x=${x:-`Which -s classes.zip $cl`}
	if test "$x"; then
		d=`dirname $x`
		d=`cd $d; pwd`
		add_path $d CLASSPATH
		for x in classes.jar rt.jar i18n.jar classes.zip
		do
			add_path -s $d/$x CLASSPATH
		done
		if [ "x$JAVA_HOME" = x ]; then
			case "$d" in
			*/lib) d=`dirname $d`;;
			esac
			JAVA_HOME=$d
		fi
#		add_path $JAVA_HOME CLASSPATH
	fi
	test "$XCLASSPATH" && CLASSPATH=$XCLASSPATH:$CLASSPATH
	case $Myname in
	appletviewer) ;;
	*)	pre_path . CLASSPATH;;
	esac
}

while [ $# -gt 0 ]
do
	case $1 in
	-main)	main="$2"; shift;;
	-J)	opts="$opts $2"; shift;;
	-J*)	opts="$opts `expr "$1" : '-J\(..*\)'`";;
	-classpath)
		opts="$opts $1 $2"; shift;;
	*)	break;;
	esac
	shift
done

case "$opts" in
*classpath*) ;;
*) setCLASSPATH;;
esac
JAVA_HOME=${JAVA_HOME:-$jre}
export JAVA_HOME LD_LIBRARY_PATH CLASSPATH
case "$Myname" in
gdb*)	test -x ${JVM}_g && JVM=${JVM}_g
        echo "You'll likely need to:"
        echo "b main"
        echo "r <classname>"
        echo 
        set -x
        exec ${GDB:-gdb} $JVM "$@"
        ;;
*_g)	test -x ${JVM}_g && JVM=${JVM}_g;;
esac
if test -f ./.java_wrapper.dbg; then
	env > .java_wrapper.env
	echo "$JVM $Dopts $opts $main $@" >> .java_wrapper.env
fi
${JVM_EXEC:-exec} $JVM $Dopts $opts $main "$@"
