@echo off
REM ---------------------------------------------------------------------------
REM JOnAS: Java(TM) Open Application Server
REM Copyright (C) 2006 Bull S.A.S.
REM Contact: jonas-team@objectweb.org
REM
REM This library is free software; you can redistribute it and/or
REM modify it under the terms of the GNU Lesser General Public
REM License as published by the Free Software Foundation; either
REM version 2.1 of the License, or any later version.
REM
REM This library is distributed in the hope that it will be useful,
REM but WITHOUT ANY WARRANTY; without even the implied warranty of
REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
REM Lesser General Public License for more details.
REM
REM You should have received a copy of the GNU Lesser General Public
REM License along with this library; if not, write to the Free Software
REM Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
REM USA
REM
REM Initial developer(s): Jerome Pioux - Benoit Pelletier
REM ---------------------------------------------------------------------------
REM $Id: XXXXX $
REM ---------------------------------------------------------------------------

REM Start, Stop JONAS cluster nodes
REM Usage: jcl [-n <node>] start | stop

setlocal enabledelayedexpansion

REM ----- If SEPARATE_WINDOWS=yes or YES exists in the user env., then use -win on startup
if not defined SEPARATE_WINDOWS set SEPARATE_WINDOWS=No

:: ------------------------------------------
:: NO NEED TO MODIFY ANYTHING BELOW THIS LINE
:: ------------------------------------------

REM ----- Delay in seconds to apply between nodes startup/shutdown
set /a DELAY1_AFTER_NODE_START=10
set /a DELAY2_AFTER_NODE_START=4
set /a DELAY_BETWEEN_NODE_STOP=1

REM ----- Set defaults if this script is called directly w/o the script wrapper
if "%JCL_NUMBER_OF_NODES%"==""    set JCL_NUMBER_OF_NODES=4
if "%JCL_BASE_PREFIX%"==""        set JCL_BASE_PREFIX=%JCL_CLUSTER_DAEMON_DIR%\jb
if "%JCL_DOMAIN_NAME%"==""        set JCL_DOMAIN_NAME=sampleCluster2Domain
if "%JCL_EAR_FILE%"==""           set JCL_EAR_FILE=%JONAS_ROOT%\examples\sampleCluster2\output\apps\sampleCluster2.ear
if "%JCL_HA_EAR_FILE%"==""        set JCL_HA_EAR_FILE=%JONAS_ROOT%\examples\sampleCluster2\output\apps\haTransactions.ear
if "%JCL_NODE_NAME_PREFIX%"==""   set JCL_NODE_NAME_PREFIX=node
if "%JCL_CLUSTER_DAEMON_DIR%"=="" set JCL_CLUSTER_DAEMON_DIR=cd
if "%JCL_DB_DIR%"==""             set JCL_DB_DIR=db
if "%JCL_DB_NAME%"==""            set JCL_DB_NAME=db
if "%JCL_MASTER_DIR%"==""         set JCL_MASTER_DIR=master
if "%JCL_MASTER_NAME%"==""        set JCL_MASTER_NAME=master

REM ----- Defined list of supported actions
set /a numberOfCommands=2
set actionTable[1]=start
set actionTable[2]=stop

REM ----- CHECK if JONAS_ROOT is set
if not defined JONAS_ROOT (
    echo.
    echo Error: JONAS_ROOT is not defined
    goto endScript
)

REM ----- Check the PATH
set PATH | find "%JONAS_ROOT%\bin" >NUL
IF %ERRORLEVEL% NEQ 0 (
    echo.
    echo Error: %JONAS_ROOT%\bin is not in your PATH
    goto endScript
)

REM ----- Need findstr
findstr /? >nul 2>&1
if errorlevel 1 (
    echo.
    echo Error: findstr is not available!
    goto endScript
)

REM ----- Help wanted the "dos cmdline way"
if "%1X"=="/?X" goto usage

REM ----- Parse input parameters
set /a nflag=0
set /a err=0
set cluster=
set action=

for %%i in (%*) do (
    REM ----- err=3: Command syntax error
    if defined action if %err% equ 0 set /a err=3

    REM ----- There is an error, break out of the parser
    if !err! equ 1 goto endParsing

    set param=%%i

    REM ----- Param starts with a dash
    if /I "!param:~0,1!"=="-" (
        set /a nflag=0
        set key=!param:~1,2!
        REM ----- Found -n flag to customize cluster nodes
        if /I "!key!"=="n" (
            set /a nflag=1
        REM ----- err=1: Invalid flag
        ) else (
            if %err% equ 0 set /a err=1
        )

    REM ----- Param does not start with a dash
    ) else (
        REM ----- Param is following up the -n flag
        if !nflag! equ 1 (
            REM ----- See if param is a known action
            for /l %%c in (1,1,%numberOfCommands%) do (
                REM ----- param is an action, register it and turn off the nflag
                if /I !param! equ !actionTable[%%c]! (
                    set action=!param!
                    set /a nflag=0
                )
            )
            REM ----- param was not an action, so it is a node - enter it in cluster
            if !nflag! equ 1 (
                call :IsNumeric !param! answer
                if "!answer!"=="yes" (
                    if !param! GTR %JCL_NUMBER_OF_NODES% if %err% equ 0 set /a err=4
                    set param=%JCL_NODE_NAME_PREFIX%!param!
                )
                if defined cluster (set cluster=!cluster!,!param!) else (set cluster=!param!)
            )

        REM ----- Param is not following up the -n
        ) else (
            REM ----- See if param is a known action
            for /l %%c in (1,1,%numberOfCommands%) do (
                REM ----- param is an action, register it and turn on the done flag
                if /I !param! equ !actionTable[%%c]! (
                    set action=!param!
                    set /a done=1
                )
            )
            REM ----- err=2: Invalid action specified
            if !done! equ 0 if %err% equ 0 set /a err=2
        )
    )
)
:endParsing

REM ----- err=2: No action specified
if %err% equ 0 if not defined action set /a err=2

REM ----- Work on the cluster nodes
set wholeCluster=
if not defined cluster set wholeCluster=1
if "%cluster%"=="all"  set wholeCluster=1
if "%cluster%"=="0"    set wholeCluster=1

if defined wholeCluster (
    set cluster=clusterd,db,master
    for /l %%c in (1,1,%JCL_NUMBER_OF_NODES%) do (
        set cluster=!cluster!,%JCL_NODE_NAME_PREFIX%%%c
    )
)

REM ----- report errors
if not %err% equ 0 (
    echo.
    if %err% equ 1 echo Error: Invalid flag ^(-%key%^)
    if %err% equ 2 echo Error: Invalid action or no action specified
    if %err% equ 3 echo Error: Command syntax error
    if %err% equ 4 echo Error: Node must be less than %JCL_NUMBER_OF_NODES%
    goto usage
)

REM Remember the number of nodes in the cluster
set /a nnodes=0
for %%i in (%cluster%) do (set /a nnodes+=1)

REM ----- Go do the work
call :%action%

:endScript
endlocal

REM ----- Unset variables
for /f "usebackq tokens=1-2 delims==" %%a in (`set JCL_`) do set %%a=

echo.
exit /b 0

REM ------------------------------- END MAIN -------------------------------

REM ------------------------------ SUBROUTINES -----------------------------
:: ---------------
:: CLUSTER DAEMON
:: ---------------
:ClusterDaemon
setlocal
set action=%1

if "%action%"=="start" (
    echo.
    echo *** Starting JOnAS cluster daemon ...
    call jclusterd start
    call :sleep %DELAY2_AFTER_NODE_START%
) else (
if "%action%"=="stop" (
    echo.
    echo *** Stopping JOnAS cluster daemon ...
    call jclusterd stop
    call :sleep %DELAY_BETWEEN_NODE_STOP%
))
endlocal&goto :eof

:: ---------------
:: START
:: ---------------
:start
setlocal

set /a n=1

echo %SEPARATE_WINDOWS%|findStr "[Yy][Ee][Ss]" >nul
if %errorlevel% equ 0 (set WIN=-win) else (set WIN=)

REM ----- Startup cluster; If we are in control of the whole cluster, the nodes
REM ----- are already in the correct order for startup
for %%i in (%cluster%) do (
    set node=%%i

    call :SetJonasBase !node! base
    set JONAS_BASE=!base!
    set CATALINA_BASE=!JONAS_BASE!

    REM ----- Set debug and startup delay
    if /I "!node!"=="clusterd" (
        call :ClusterDaemon start
    ) else (

        if /I "!node!"=="master" (
            set /a delay=%DELAY1_AFTER_NODE_START%
        ) else (
        if /I "!node!"=="db" (
            set /a delay=%DELAY1_AFTER_NODE_START%
        ) else (
            set /a delay=%DELAY2_AFTER_NODE_START%
        ))

        REM ----- Save and clean up logs
        rmdir /S /Q !JONAS_BASE!\logs\old\* 2>NUL
        mkdir !JONAS_BASE!\logs\old 2>NUL
        xcopy /Q /Y !JONAS_BASE!\logs\* !JONAS_BASE!\logs\old >NUL

        REM ----- Eventually deploy apps
        if not "%JCL_EAR_FILE%"=="NULL" (
            if exist %JCL_EAR_FILE% (
                copy /Y %JCL_EAR_FILE% !JONAS_BASE!\apps\autoload >NUL
            )
        )
        if not "%JCL_HA_EAR_FILE%"=="NULL" (
            if exist %JCL_HA_EAR_FILE% (
                copy /Y %JCL_HA_EAR_FILE% !JONAS_BASE!\apps\autoload >NUL
            )
        )

        echo.
        echo *** Starting JOnAS !node! instance ...
        echo ^(jonas start !WIN! -n !node! -Ddomain.name=%JCL_DOMAIN_NAME%^)
        call jonas start !WIN! -n !node! -Ddomain.name=%JCL_DOMAIN_NAME%

        REM ----- Wait delay seconds between nodes startup
        if !n! LSS %nnodes% (
            if /I "!WIN!"=="-win" (
                echo.
                echo    Waiting !%delay!s before starting next node ...
                call :sleep !delay!
            )
        )
        set /a n+=1
    )
)
endlocal&goto :eof

:: ---------------
:: STOP
:: ---------------
:stop
setlocal

REM ----- Stop cluster; If we are in control of the whole cluster, the nodes
REM ----- are in the correct order for startup which is the reverse order of
REM ----- how we would like to stop them; so let's build a "reverse" cluster
set cluster2=
if defined wholeCluster (
    for %%i in (%cluster%) do (
        set node=%%i
        if defined cluster2 (set cluster2=!node!,!cluster2!) else (set cluster2=!node!)
  )
  set cluster=!cluster2!
)

REM ----- Stop cluster
for %%i in (%cluster%) do (
    set node=%%i

    call :SetJonasBase !node! base
    set JONAS_BASE=!base!
    set CATALINA_BASE=!JONAS_BASE!

    if /I "!node!"=="clusterd" (
        call :ClusterDaemon stop
    ) else (
        echo.
        echo *** Halting JOnAS !node! instance ...
        echo ^(jonas halt -n !node!^)
        call jonas halt -n !node!

        call :sleep %DELAY_BETWEEN_NODE_STOP%
    )
)
:endStop
endlocal&goto :eof

:: ---------------
:: SetJonasBase
:: ---------------
:SetJonasBase
setlocal
set node=%1

if "%node%"=="clusterd" (
    set base=%JCL_CLUSTER_DAEMON_DIR%
)else (
if "%node%"=="master" (
    set base=%JCL_MASTER_DIR%
) else (
if "%node%"=="db" (
    set base=%JCL_DB_DIR%
) else (
    set /a l=%node:node=%
    set base=%JCL_BASE_PREFIX%!l!
)))
endlocal&set %2=%base%&goto :eof

:: ---------------
:: ISNUMERIC
:: ---------------
:isnumeric
setlocal
set string=%1
REM ----- Do not consider quote if any
set string=%string:"=%
REM ----- Use findstr with reg.ex.
echo %string%|findStr "[^0-9]" >nul
set answer=no
if %errorlevel% equ 1 set answer=yes
endlocal&set %2=%answer%&goto :eof

:: ---------------
:: SLEEP
:: ---------------
:sleep
setlocal
set delay=%1
ping 1.1.1.1 -n 1 -w %delay%000 >nul
endlocal&goto :eof

:: ---------------
:: USAGE
:: ---------------
:usage
echo.
echo usage: %~n0 ^[ -n ^[clusterd^],^[db^],^[master^],^[node number^],... ^] start^|stop
echo Syntax notes:
echo        * At least, one space is mandatory after -n
echo        * If multiple values are used after -n, they must be separated by a
echo          delimiter ^(space, comma...^) or multiple -n can also be used
echo        * All nodes in the cluster will be used if -n is not specified
echo.
echo Example: -n db,1,3 addresses the db, node1 and node3 instances
echo.
echo Use "set SEPARATE_WINDOWS=yes" if you want to start the JVMs in dedicated windows
goto endScript
