#! /bin/sh

# LaunchAnywhere (tm) version 2.5 standard
# (c) Copyright 1998, 1999 Zero G Software, Inc., all rights reserved.
#

#  This program is written in sh code, and uses awk and sed.  It
#  should work provided you have all these programs on your machine.
#
#  To run this script you will need to have the following:
#	1) a Java VM installed (however, it will handle a lack of Java nicely).
#	2) a Java-style properties file having the same name as this script 
#		with the suffix .lax.  If this script is appended to the
#		self-extractor, it will look for the properties file in the
#		directory specified by $templaxpath; otherwise, it will look in
#		the same directory that this script is in.
#	3) a Java program in the file "lax.jar".
#
#  The .lax property file must contain at least the following properties:
#	1)  lax.class.path  classpath (do not include the environment variable $CLASSPATH)
#	2)  lax.nl.java.launcher.main.class  (main class of LaunchAnywhere Executable)
#	3)  lax.currentVM  (VM to launch with)
#  Optional general properties
#	4)  lax.user.dir
#	5)  lax.stdout.redirect (to console or to file; suppressed by default)
#	6)  lax.stderr.redirect (to console or to file; suppressed by default)
#	7)  lax.nl.install.dir 
#	8)  lax.always.ask
#  Optional java invocation properties
#	9)	lax.nl.java.option.verify.mode
#	10) lax.nl.java.option.verbose
#	11) lax.nl.java.option.garbage.collection.extent
#	12) lax.nl.java.option.native.stack.max
#	13) lax.nl.java.option.java.stack.size.max
#	14) lax.nl.java.option.java.heap.size.max
#	15) lax.nl.java.option.java.heap.size.initial
#	16) lax.nl.java.option.debugging
#  Optional JIT property
#	17) lax.nl.[OperatingSystem.[Architecture.]]java.compiler
#		([] indicates optional information, i.e. property name can be
#		lax.nl.java.compiler; will use most specific property)
#
#  This program is also used for the "Try It!" feature of the InstallAnywhere
#  designer.  If the name of a VM is passed in as an argument when invoking
#  this script, the VM will be checked for validity and used to run the 
#  application specified in the .lax file.
#
#  Note: some versions of HP-UX apparently return the value "0" for any null strings
#  that result from parsing.  Just wanted to explain all the if conditions that
#  follow all parsing statements in this script.

#
# Do prep work for env.properties file if this launcher is
# not being excuted from a self-extractor
#
if [ -z "$USERENV" ]
then
	USERENV=`set | sed 's,^\(.*\),"\1",'`
fi
if [ -z "$envPropertiesFile" ]
then
	if [ -d /tmp ]
	then
		envPropertiesFile=/tmp/env.properties.$$
	else
		envPropertiesFile=$HOME/env.properties.$$
	fi
fi
# more env.properties stuff...
# create the properties files BEFORE writing to it
# so that we can change is permissions to be more
# secure... who knows? maybe the user has a password
# in an environment variable!
#
touch $envPropertiesFile
chmod 600 $envPropertiesFile
# even more env.properties stuff...
# The first sed call is to escape spaces and tables from
# the RHS of environment values.  This white space would
# be interpreted as separate arguments to the for statement.
# So this escaping with ||| for spaces and @@@ for tabs
# makes sure that env values with such whitespace is accounted
# for
for setting in $USERENV
do
	lhs=`echo $setting | sed 's/^"\(.*\)=.*/\1/'`
	rhs=`echo $setting | sed 's/^.*=\(.*\)"/\1/'`
	echo lax.nl.env.$lhs=$rhs >> $envPropertiesFile
	llhs=`echo $lhs | tr [:upper:] [:lower:]`
	# dont make duplicates, if the variablename was in all
	# lowercase, dont give it again
	if [ "$llhs" != "$lhs" ]
	then
		echo lax.nl.env.$llhs=$rhs >> $envPropertiesFile
	fi
done

# Storing command-line arguments
cmdlineargs=$*

#echo "Command Line Arguments"
#echo $cmdlineargs

# Tracing symbolic links to actual launcher location

olddir=`pwd`
linked=true
initname=`basename $0`
initdir=`dirname $0`
if [ ! $initdir = "." ] 
then
	cd $initdir
fi

initdir=`pwd`
currname=$initname

while [ $linked = true ] 
do
	#lsstring=`ls -dgon $currname`
	lsstring=`ls -l $currname`
	islink="`expr "$lsstring" : ".*[\>]\(.*\)"`"
	if [ ${islink:-""} = "" -o ${islink:-"0"} = "0" ]
	then
		linked=false
	else
		nextdir="`expr "$islink" : "\(.*\).*/"`"
		currname="`expr "$islink" : ".*/\(.*\)"`"
		if [ ${currname:-""} = "" ]
		then
			currname=$islink
		fi
		if [ ${nextdir:-""} != "" -a ${nextdir:-"0"} != "0" ]
		then
			cd $nextdir
		fi
	fi
done



# Finding .lax file
	# If this is the self-extractor, use $templaxpath
if [ ! ${templaxpath:-""} = "" ]
then
	propfname=$templaxpath
else
	propfname=$currname.lax
fi

if [ ! -r $propfname ];
then
	echo "The file "$propfname" could not be found, and the"
	echo "program cannot be run without it.  Try reinstalling the program."
	exit;
fi;



# Getting the necessary properties from the .lax file

getparam='BEGIN { FS="=" } { if(index($1,"#")!=1) if($1==value) print $2}'

	# Reading in required information
clp=`awk 	"$getparam" value="lax.class.path" $propfname`
mainc=`awk 	"$getparam" value="lax.nl.java.launcher.main.class" $propfname`
tmp_vm=`awk 	"$getparam" value="lax.nl.current.vm" $propfname`
ud=`awk 	"$getparam" value="lax.user.dir" $propfname`
out=`awk 	"$getparam" value="lax.stdout.redirect" $propfname`
err=`awk 	"$getparam" value="lax.stderr.redirect" $propfname`
insdir=`awk 	"$getparam" value="lax.dir" $propfname`
ask=`awk 	"$getparam" value="lax.always.ask" $propfname`

# If the vm gets a relative path, we must make it absolute to the Install
#   Directory
# tm 3/3
if [ "${tmp_vm:-""}" = "" ]
then
	vm=""
else
	first_char=`echo $tmp_vm | sed 's,^\(.\).*,\1,'`
	if [ "$first_char" = "/" ]
	then
		vm=$tmp_vm
	else
		vm=$insdir$tmp_vm
	fi
fi

	# Reading in VM invocation options
verify=`awk	"$getparam" value="lax.nl.java.option.verify.mode" $propfname`
verbo=`awk	"$getparam" value="lax.nl.java.option.verbose" $propfname`
gcxtnt=`awk	"$getparam" value="lax.nl.java.option.garbage.collection.extent" $propfname`
gcthrd=`awk	"$getparam" value="lax.nl.java.option.garbage.collection.background.thread" $propfname`
nsmax=`awk	"$getparam" value="lax.nl.java.option.native.stack.max" $propfname`
jsmax=`awk	"$getparam" value="lax.nl.java.option.java.stack.size.max" $propfname`
jhmax=`awk	"$getparam" value="lax.nl.java.option.java.heap.size.max" $propfname`
jhinit=`awk	"$getparam" value="lax.nl.java.option.java.heap.size.initial" $propfname`
debug=`awk	"$getparam" value="lax.nl.java.option.debugging" $propfname`

# Checking for invalid classpath and/or main class

if [ "${clp:-""}" = "" ]
then
	echo "The classpath specified in the LAX properties file"
	echo "is invalid.  Try reinstalling the program."
	exit;
fi
if [ ${mainc:-""} = "" ]
then
	echo "The main class specified in the LAX properties file"
	echo "is invalid.  Try reinstalling the program."
	exit;
fi



# Determining absolute classpaths

	# Checking if environment variable CLASSPATH needs to be included 
clphead="`expr "$clp" : "\(.*\).*[$]ENV_CLASSPATH"`"
clptail="`expr "$clp" : ".*[$]\(.*\)"`"

if [ "${clphead:-"0"}" = "0" ]
then
	clphead=""
fi
if [ ${clptail:-"0"} = "0" ]
then
	clptail=""
fi

if [ "$clphead" = "$clptail" ]
then
	smclp=$clp
else
	smclp=$clphead$CLASSPATH$clptail	
fi

	# Creating absolute classpaths for relative paths
here=`pwd`

#commands is an awk script that divides up the classpath by semicolon, and then concatenates them together by colon
commands='{ numitems=split($0,arr); newitem = ""; for (item=1; item<=numitems; item++) {if (item<numitems) {sep=":"} else {sep=""};newitem = newitem arr[item] sep}; print newitem}'

smclp=`echo $smclp | awk -F\; "$commands"`
#`echo $smclp`


i=1
finished=false
while [ $finished = false ]
do
	commands='BEGIN { FS=":" } { print $arg }'
	thisclp=`echo $smclp | awk "$commands" arg=$i -`
	if [ "${thisclp:-""}" = "" ]
	then
		finished=true
	else
		testclp=`expr "$thisclp" : "\([/]\)"`
		if [ "${testclp:-""}" = "" -o "${testclp:-"0"}" = "0" ]
		then
			absclp=$absclp$here/$thisclp:
		else
			absclp=$absclp$thisclp:
		fi
	fi
	i=`expr $i + 1`
done
clp=$absclp



# Renaming .lax file by absolute classpath (if not self-extractor)

if [ ${templaxpath:-""} = "" ]
then
	propfname=$here/$propfname
fi



#  Determining VM invocation options to use

verify=${verify:="null"}
if [ $verify = "remote" ]
then
	options="-verifyremote"
elif [ $verify = "all" ]
then
	options="-verify"
elif [ $verify = "none" ]
then
	options="-noverify"
fi

verbo=${verbo:="none"}
if [ $verbo = "normal" ]
then
	options="$options -verbose"
elif [ $verbo = "all" ]
then
	options="$options -verbose -verbosegc"
elif [ $verbo = "gc" ]
then
	options="$options -verbosegc"
fi

gcxtnt=${gcxtnt:="none"}
if [ $gcxtnt = "min" ]
then
	options="$options -noclassgc"
fi

gcthrd=${gcthrd:="none"}
if [ $gcthrd = "off" ]
then
	options="$options -noasyncgc"
fi

if [ ! nsmax=${nsmax:="none"} ]
then
	options="$options -ss$nsmax"
fi

if [ ! ${jsmax:-"none"} = "none" ]
then
	options="$options -oss$jsmax"
fi

if [ ! ${jhmax:-""} = "" ]
then
	options="$options -mx$jhmax"
fi

if [ ! ${jhinit:-""} = "" ]
then
	options="$options -ms$jhinit"
fi



# Setting stdout and stderr redirection

laxdebug=$LAX_DEBUG

if [ ! ${laxdebug:-""} = "" ]
then
	out="console"
	err="console"
	options="-Dlax.stderr.redirect=console -Dlax.stdout.redirect=console $options"
else
	out=${out:=null}
	if [ $out = "null" -o $out = "NULL" ]
	then
		out="notconsole"
	fi
	err=${err:=null}
	if [ $err = "null" -o $err = "NULL" ]
	then
		err="notconsole"
	fi
fi



# Resetting java home and JIT compiler environment variables

J_HOME=
export J_HOME


# Determining what type of JIT to use (if any)

ostype=`uname -s`

if [ $ostype = "SunOS" ]
then
	ostype="Solaris"
	cputype=`uname -p`
else
	cputype=`uname -m`
fi

jitinvoc=""
jittype=""

	# Looking for JIT in props file
jittype=`awk "$getparam" value="lax.nl.$ostype.$cputype.java.compiler" $propfname`
if [ ${jittype:-""} = "" ]
then
	jittype=`awk "$getparam" value="lax.nl.$ostype.java.compiler" $propfname`
fi
if [ ${jittype:-""} = "" ]
then
	jittype=`awk "$getparam" value="lax.nl.java.compiler" $propfname`
fi

ostype=${ostype:=""}

if [ $ostype = "HP-UX" -o $ostype = "IRIX" ]
then
	if [ ${jittype:-""} = "off" ]
	then
		jitinvoc="-nojit -Djava.compiler="
	fi
elif [ $ostype = "Solaris" ]
then
	if [ ${jittype:-""} = "off" ]
	then
		jitinvoc="-Djava.compiler="
	fi
elif [ $ostype = "AIX" ]
then
	if [ ${jittype:-""} = "off" ]
	then
		JAVA_COMPILER=off
		export JAVA_COMPILER
	fi
else
	if [ ${jittype:-""} = "off" ]
	then
		jitinvoc="-Djava.compiler="
	fi
fi

options="$jitinvoc $options"



# Passing in PATH environment variable

options="$options -Dlax.nl.env.path=$PATH"


lax_vm="LAX_VM"
# Getting VM
#check to see if it was passed into us
#echo "checking for VM"

if [ ${1:-""} = $lax_vm ]
#if [ ! ${1:-""} = "" -a -x ${1:-""} ]
then
	# Using VM passed in as argument
	actvm=$2
#echo "USING VM PASSED IN"

#	actvm=$1
else

	#echo "Looking for Java VMs on your PATH"
	# Looking for VMs from props file on path 
	if [ ${ask:-"false"} = "true" ]
	then
		vm=""
	fi
	# check if the current VM still exists. If not, look for one.
	# tm 3/3
	if [ ! -x "$vm" -o -d "$vm" ];
	then
		echo ""
		echo "Please choose a Java virtual machine to run this program."
		echo "(These virtual machines were found on your PATH)"
		echo "---------------------------------------------------------"
		getpaths='BEGIN {FS=":"}{ for(i=1;i<=NF;i++) print $i; }'

		# Printing list of javas and jres
		pathc=1
		for file in `echo $PATH | awk "$getpaths"`
		do
			if [ -x $file/java -a ! -d $file/java ]
			then
				# if we're not a self-extractor, or we've found a non-1.2 VM, or oldjava exists...
				if [ \( ${templaxpath:-""} = "" \) -o \( ! -r "$file/../lib/rt.jar" \) -o \( -x "$file/oldjava" \) ]
				then
					echo $pathc: $file/java
					# check if "oldjava" is available, so we'll use that on Java 1.2
					if [ -x "$file/oldjava" ];
					then
						eval part$pathc="$file/oldjava"
					else
						eval part$pathc="$file/java"
					fi
					pathc=`expr $pathc + 1`
				fi
			fi
			if [ -x $file/jre -a ! -d $file/jre ]
			then
				echo $pathc: $file/jre
				eval part$pathc="$file/jre"
				pathc=`expr $pathc + 1`
			fi
		done
		echo "$pathc:  Exit."
	
		# If no VMs are found in path
		if [ $pathc -eq 1 ]
		then
			echo "No Java virtual machine could be found from your PATH"
			echo "environment variable.  You must install a VM prior to"
			echo "running this program."
			cd $olddir
			#rm -rf $ud
			exit
		fi
	
		#  Taking selection
		if [ ! ${LAX_NONINTERACTIVE:-""} = "" ]
		then
			# Automatically choosing first VM
			sel="1"
			eval actvm="\$part$sel"
			echo "Automatically selecting $actvm..."
		else
			echo "Please enter your selection (number):  "
			read sel
			#  Checking for validity
  			if [ $sel -eq $pathc ] 
  			then 
				cd $olddir
				#rm -rf $ud
  				exit 
			elif [ $sel -lt 1 -o $sel -ge $pathc ]
			then
				echo "Invalid Selection:  This program will terminate."
				cd $olddir
				#rm -rf $ud
				exit
			fi
		fi
	
		eval actvm="\$part$sel"
			# noLaxBackup is true for self-extractor
		noLaxBackup=${noLaxBackup:="false"}
		if [ ! $noLaxBackup = true -a -w $propfname ]
		then
			sedscript="s;lax.nl.current.vm.*;lax.nl.current.vm=$actvm;"
			sed $sedscript $propfname>file.lax 
			mv $propfname $propfname.bak > /dev/null 2>&1
			mv file.lax $propfname > /dev/null 2>&1
			rm $propfname.bak > /dev/null 2>&1
		fi
	else
		actvm=$vm
	fi
fi	



# Changing working directory

if [ ! ${ud:-""} = "" ]
then
	if [ ! $ud = "." ];
	then
		cd $ud;
	fi
else
	cd $olddir
fi

# Optional printout of all variable values for debugging purposes

if [ ! ${laxdebug:-""} = "" ] 
then
	echo "classpath: $clp"
	echo "main class: $mainc"
	echo ".lax file path: $propfname"
	echo "user directory: $ud"
	echo "stdout to: $out"
	echo "sterr to: $err"
	echo "install directory: $insdir"
	echo "JIT: $jittype"
	echo "option (verify): $verify"		
	echo "option (verbosity): $verbo"
	echo "option (garbage collection extent): $gcxtnt"
	echo "option (garbage collection thread): $gcthrd"
	echo "option (native stack max size): $nsmax"
	echo "option (java stack max size): $jsmax"
	echo "option (java heap max size): $jhmax"
	echo "option (java heap initial size): $jhinit"	
fi	

# Setting jre/java invocation command
#	if the VM was passed into us, then we shift the
#	arguments over by two, one for "LAX_VM" and one for
#	the vm path
if [ ${1:-""} = $lax_vm ]
then
	shift 2
fi

vmtype="`expr "$actvm" : ".*/\(.*\)"`"

runVM () {
	#
	# Setting the JAVA_HOME based on the location of the jre
	#
	# What we will do is strip off /bin$ from the END of this
	# variable. If the path doesn't contain 'bin' we leave
	# JAVA_HOME blank.  However, its useless to try and set
	# the home from a link, so we have to find the true home
	# on the disk of the VM first
	#
	actvm_remaining=$actvm
        #
        #first check to see if the VM is a link and follow it
        #
	linkDir=`dirname $actvm_remaining`
	minusLoutput=`ls -l $actvm_remaining`
	minusLoutput=`expr "$minusLoutput" : ".*[\>] \(.*\)"`
	while [ "$minusLoutput" != "" -a "$minusLoutput" != 0 ]
	do
		if [ `expr "$minusLoutput" : "^/"` = 0 ]; then
			minusLoutput=$linkDir/$minusLoutput
		fi
		minusLprev=$minusLoutput
		minusLoutput=`ls -l $minusLoutput`
		minusLoutput=`expr "$minusLoutput" : ".*[\>] \(.*\)"`
		linkDir=`dirname $minusLoutput`
		actvm_remaining=$minusLprev
	done
	#
	# from the true home of the VM, fill JAVA_HOME
	#
	JAVA_HOME=""
	until [ "$actvm_remaining" = "" ]
	do
		last=`expr "$actvm_remaining" : '.*/\(.*\)'`
		rest=`expr "$actvm_remaining" : '\(.*\)/.*'`
		if [ "$last" = "bin" ]
		then
			JAVA_HOME=$rest
			break
		else
			actvm_remaining=$rest
		fi
	done
	
	# Making $JAVA_HOME available to the application.
	export JAVA_HOME
	echo JAVA_HOME=\"$JAVA_HOME\"

	if [ $vmtype = "jre" ]
	then
		CLASSPATH=
		export CLASSPATH  
		# I split these up so they would be a bit
                #   clearer on the screen.
                echo "Running:"
		echo "-----"
		echo "$actvm $options -cp "$clp" $mainc $propfname $envPropertiesFile $cmdlineargs"
                echo "-----"
                # Here is where we actually run the app in Java:
		$actvm $options -cp "$clp" $mainc $propfname $envPropertiesFile $cmdlineargs
	else
		CLASSPATH=$clp
  		export CLASSPATH 
		debug=${debug:-"off"}
		if [ ! $debug = "off" ]
		then
			options="$options -debug"
		fi
		# I split these up so they would be a bit clearer on the screen.
                echo "Running:"
                echo "-----"
                echo "$actvm $options $mainc $propfname $envPropertiesFile $cmdlineargs"
                echo "-----"
                # Here is where we actually run the app in Java:
		$actvm $options $mainc $propfname $envPropertiesFile $cmdlineargs
	fi
}

#  Invocation of VM
 
if [ $out = "console" -a $err = "console" ]
then
	runVM
elif [ $out = "console" ]
then
	runVM 2> /dev/null
elif [ $err = "console" ]
then
	runVM 1> /dev/null
else 
	runVM 1> /dev/null 2> /dev/null
fi


#  Change back to directory used priory to this script running.

cd $olddir
rm -f $envPropertiesFile
