diff --git a/build/deploy.edex.awips2/esb/conf/security/keystoreUtil.sh b/build/deploy.edex.awips2/esb/conf/security/keystoreUtil.sh index 8613944237..6be5bbbe94 100755 --- a/build/deploy.edex.awips2/esb/conf/security/keystoreUtil.sh +++ b/build/deploy.edex.awips2/esb/conf/security/keystoreUtil.sh @@ -1,4 +1,5 @@ #!/bin/bash +# Temporary, only be used until we get DOD certs. # rewrite from 16.1.1 SETUP_ENV=/awips2/edex/bin/setup.env @@ -273,7 +274,6 @@ do done - cn=$(hostname) echo "Generating keystore..." diff --git a/build/deploy.edex.awips2/esb/conf/spring/edex.xml b/build/deploy.edex.awips2/esb/conf/spring/edex.xml index 28e52c27c7..dc3a07b537 100644 --- a/build/deploy.edex.awips2/esb/conf/spring/edex.xml +++ b/build/deploy.edex.awips2/esb/conf/spring/edex.xml @@ -100,6 +100,16 @@ --> + + + + + + + + + + @@ -109,7 +119,7 @@ - + diff --git a/build/deploy.edex.awips2/esb/conf/wrapper.conf b/build/deploy.edex.awips2/esb/conf/wrapper.conf index 7b9ff398ad..3b890a4005 100644 --- a/build/deploy.edex.awips2/esb/conf/wrapper.conf +++ b/build/deploy.edex.awips2/esb/conf/wrapper.conf @@ -90,6 +90,9 @@ wrapper.java.additional.4=-Dorg.apache.camel.jmx.disabled=true # Enforces GMT to be used as the timezone wrapper.java.additional.5=-Duser.timezone=GMT +# Set default tmp to awips controlled directory for security +wrapper.java.additional.6=-Djava.io.tmpdir=/awips2/tmp + # garbage collection settings wrapper.java.additional.gc.1=-XX:+UseConcMarkSweepGC wrapper.java.additional.gc.2=-XX:+CMSIncrementalMode diff --git a/cave/build/alertviz/customTargets.xml b/cave/build/alertviz/customTargets.xml index 2eb6406330..dac3d6af3a 100644 --- a/cave/build/alertviz/customTargets.xml +++ b/cave/build/alertviz/customTargets.xml @@ -186,16 +186,6 @@ - - - - - - - diff --git a/cave/build/build.sh b/cave/build/build.sh index 970b60e98e..2659f43a3a 100755 --- a/cave/build/build.sh +++ b/cave/build/build.sh @@ -69,6 +69,7 @@ java -jar $LAUNCHER_JAR -application org.eclipse.ant.core.antRunner \ -Dbuilder=$BUILDER \ -DbuildDirectory=${BUILDER}/tmp \ -Dbase=$BUILDER \ +-DproductFile=awips.product \ $OPTS_FOR_ANT rc=$? diff --git a/cave/build/build.xml b/cave/build/build.xml index 0f7cdc8ae3..b71ae6c773 100644 --- a/cave/build/build.xml +++ b/cave/build/build.xml @@ -7,6 +7,8 @@ value="gtk" /> + @@ -71,6 +73,7 @@ + - \ No newline at end of file + diff --git a/cave/build/cave/build.properties b/cave/build/cave/build.properties index 74de95c003..2da49f18bd 100644 --- a/cave/build/cave/build.properties +++ b/cave/build/cave/build.properties @@ -19,7 +19,10 @@ # them on the command line (e.g., -DbaseLocation=d:/eclipse ############# PRODUCT/PACKAGING CONTROL ############# -product=${base}/../../com.raytheon.viz.product.awips/awips.product + +# The product file is specified in the build.xml as a default and is +# overridable setting 'build.product' from ant. +product=${base}/../../com.raytheon.viz.product.awips/${productFile} #product=${base}/../../com.raytheon.viz.product.awips/developer.product runPackager=true diff --git a/cave/build/cave/customTargets.xml b/cave/build/cave/customTargets.xml index 05aef2673b..a971bcac3b 100644 --- a/cave/build/cave/customTargets.xml +++ b/cave/build/cave/customTargets.xml @@ -196,16 +196,6 @@ - - - - - - - diff --git a/cave/build/static/README.txt b/cave/build/static/README.txt index 51b6e5476a..7198f8f1ad 100644 --- a/cave/build/static/README.txt +++ b/cave/build/static/README.txt @@ -10,10 +10,8 @@ The following common directories exist within the static directory: architecture. We also have the following os / architecture specific directories within the static -directory. The name of the directories is based on the eclipse (3.6.1) os.arch +directory. The name of the directories is based on the eclipse (3.8.2) os.arch designation. linux.x86 - these files will only be installed on a 32-bit Linux Operating System. linux.x86_64 - these files will only be installed on a 64-bit Linux Operating System. - win32.x86 - these files will only be installed on a 32-bit MS Windows Operating System. win32.amd64 - these files will only be installed on a 64-bit Windows Operating System. - macosx.x86 - these files will only be installed on a 32-bit Apple OS X Operating System. \ No newline at end of file diff --git a/cave/build/static/linux/alertviz/alertviz.sh b/cave/build/static/linux/alertviz/alertviz.sh index 7f1a64ea4a..480ef84f76 100644 --- a/cave/build/static/linux/alertviz/alertviz.sh +++ b/cave/build/static/linux/alertviz/alertviz.sh @@ -26,6 +26,7 @@ # Date Ticket# Engineer Description # ------------ ---------- ----------- -------------------------- # Oct 09, 2014 #3675 bclement added cleanExit signal trap +# Jun 17, 2015 #4148 rferrel Logback needs fewer environment variables. # user=`/usr/bin/whoami` @@ -96,7 +97,7 @@ fi #check for the logs directory, which may not be present at first start hostName=`hostname -s` -LOGDIR=$HOME/caveData/logs/consoleLogs/$hostName/ +export LOGDIR=$HOME/caveData/logs/consoleLogs/$hostName/ if [ ! -d $LOGDIR ]; then mkdir -p $LOGDIR @@ -122,27 +123,17 @@ trap 'cleanExit $pid' SIGHUP SIGINT SIGQUIT SIGTERM count=0 while [ $exitVal -ne 0 -a $count -lt 10 ] do - count=`expr $count + 1` - curTime=`date +%Y%m%d_%H%M%S` - LOGFILE=${LOGDIR}/alertviz_${curTime}_console.log - export LOGFILE_ALERTVIZ=${LOGDIR}/alertviz_${curTime}_admin.log - - #first check if we can write to the directory - if [ -w ${LOGDIR} ]; then - touch ${LOGFILE} - fi - - #check for display; if no display then exit - if [ -z "${DISPLAY}" ]; then - echo "Display is not available." - exitVal=0 - else - #finally check if we can write to the file - if [ -w ${LOGFILE} ]; then - ${dir}/alertviz $* > ${LOGFILE} 2>&1 & + count=`expr $count + 1` + #check for display; if no display then exit + if [ -z "${DISPLAY}" ]; then + echo "Display is not available." + exitVal=0 else - ${dir}/alertviz $* & - fi + if [ -w ${LOGDIR} ] ; then + ${dir}/alertviz $* > /dev/null 2>&1 & + else + ${dir}/alertviz $* & + fi pid=$! wait $pid exitVal=$? diff --git a/cave/build/static/linux/cave/cave.sh b/cave/build/static/linux/cave/cave.sh index fd98b5f75b..32dd9e993e 100644 --- a/cave/build/static/linux/cave/cave.sh +++ b/cave/build/static/linux/cave/cave.sh @@ -34,6 +34,7 @@ # Oct 10, 2014 #3675 njensen Logback now does console logging to ensure correct pid # Oct 13, 2014 #3675 bclement startup shutdown log includes both launching pid and placeholder # Jan 28, 2015 #4018 randerso Added a productEditor log file to changes in the GFE product editor +# Jun 17, 2015 #4148 rferrel Logback needs fewer environment variables. # @@ -194,7 +195,7 @@ then fi BASE_LOGDIR=$HOME/caveData/logs/consoleLogs -LOGDIR=$BASE_LOGDIR/$hostName/ +export LOGDIR=$BASE_LOGDIR/$hostName/ # make sure directory exists if [ ! -d $LOGDIR ]; then @@ -212,13 +213,6 @@ export LOGFILE_STARTUP_SHUTDOWN="${LOGDIR}/${PROGRAM_NAME}_${pid}_${curTime}_pid # At this point fork so that log files can be set up with the process pid and # this process can log the exit status of cave. ( - # we include the PID of the launching process along with - # a %PID% placeholder to be replaced with the "real" PID - export LOGFILE_CAVE="${LOGDIR}/${PROGRAM_NAME}_${curTime}_pid_%PID%_logs.log" - export LOGFILE_CONSOLE="${LOGDIR}/${PROGRAM_NAME}_${curTime}_pid_%PID%_console.log" - export LOGFILE_PERFORMANCE="${LOGDIR}/${PROGRAM_NAME}_${curTime}_pid_%PID%_perf.log" - export LOGFILE_PRODUCT_EDITOR="${LOGDIR}/${PROGRAM_NAME}_${curTime}_pid_%PID%_productEditor.log" - # can we write to log directory if [ -w ${LOGDIR} ]; then touch ${LOGFILE_STARTUP_SHUTDOWN} diff --git a/cave/build/static/win32.amd64/alertviz/alertviz.bat b/cave/build/static/win32.amd64/alertviz/alertviz.bat deleted file mode 100644 index b6b641bab0..0000000000 --- a/cave/build/static/win32.amd64/alertviz/alertviz.bat +++ /dev/null @@ -1,52 +0,0 @@ -@echo OFF - -REM Determine where we are located. -SET CONTAINING_DIRECTORY=%~dp0 - -REM Prepare the environment. - -REM Location of AWIPS II Java (the jre). -SET JavaJreDirectory=C:\Program Files\Raytheon\AWIPS II\Java\jre7 -REM Location of AWIPS II Python. -SET PythonInstallDirectory=C:\Program Files\Raytheon\AWIPS II\Python - -REM Add Java and Python to the path. -SET Path=%PythonInstallDirectory%;%PythonInstallDirectory%\DLLs;%Path% -SET Path=%JavaJreDirectory%\bin;%Path% -REM Define 'PythonPath'. -SET PythonPath=%PythonInstallDirectory%\Lib\lib-tk;%PythonPath% -SET PythonPath=%PythonInstallDirectory%\DLLs;%PythonPath% -SET PythonPath=%PythonInstallDirectory%\Lib;%PythonPath% -SET PythonPath=%PythonInstallDirectory%;%PythonPath% - -REM Eliminate variables that will no longer be used. -SET PythonInstallDirectory= -SET JavaJreDirectory= - -REM Determine where we will be logging to. -SET HOME_DIRECTORY=%USERPROFILE% -SET CAVEDATA_LOG_DIRECTORY=%HOME_DIRECTORY%\caveData\logs -SET CONSOLE_LOG_DIRECTORY=%CAVEDATA_LOG_DIRECTORY%\consoleLogs\%COMPUTERNAME% -IF NOT EXIST "%CONSOLE_LOG_DIRECTORY%" (MKDIR "%CONSOLE_LOG_DIRECTORY%") - -echo Starting ALERTVIZ; leave this CMD window open to enable AlertViz 'restart'. -REM Start AlertViz (and implement the alertviz restart capability). -:AlertVizLoopStart -SET RND=%random% -SET RND_DATETIME_FILE=%TMP%\awips2dt_%RND%.tmp -REM Python is used to retrieve the current date and time because the order -REM of the Windows date/time fields is not necessarily guaranteed and the -REM Windows date/time fields can only be extracted using substring operations -REM instead of -formatter- strings like Linux allows. -python -c "from datetime import datetime; print datetime.now().strftime('%%Y%%m%%d_%%H%%M%%S');" > %RND_DATETIME_FILE% -SET /p LOG_DATETIME= < %RND_DATETIME_FILE% -DEL %RND_DATETIME_FILE% - -SET LOGFILE_CONSOLE=%CAVEDATA_LOG_DIRECTORY%\alertviz_%LOG_DATETIME%_console.log -SET LOGFILE_ALERTVIZ=%CAVEDATA_LOG_DIRECTORY%\alertviz_%LOG_DATETIME%_admin.log - -"%CONTAINING_DIRECTORY%alertviz.exe" %* > "%CONSOLE_LOG_DIRECTORY%\alertviz_%LOG_DATETIME%.log" 2>&1 -IF %ERRORLEVEL% == 0 (EXIT) -echo Restarting AlertViz. -GOTO AlertVizLoopStart - diff --git a/cave/build/static/win32.amd64/cave/cave.bat b/cave/build/static/win32.amd64/cave/cave.bat deleted file mode 100644 index a343b81be7..0000000000 --- a/cave/build/static/win32.amd64/cave/cave.bat +++ /dev/null @@ -1,56 +0,0 @@ -@echo OFF - -REM Determine where we are located. -SET CONTAINING_DIRECTORY=%~dp0 - -REM Prepare the environment. - -REM Location of AWIPS II Java (the jre). -SET JavaJreDirectory=C:\Program Files\Raytheon\AWIPS II\Java\jre7 -REM Location of AWIPS II Python. -SET PythonInstallDirectory=C:\Program Files\Raytheon\AWIPS II\Python - -REM Add Java and Python to the path. -SET Path=%PythonInstallDirectory%;%PythonInstallDirectory%\DLLs;%Path% -SET Path=%JavaJreDirectory%\bin;%Path% -REM Add the CAVE lib directory to the path. -SET Path=%CONTAINING_DIRECTORY%lib;%Path% -REM Define 'PythonPath'. -SET PythonPath=%CONTAINING_DIRECTORY%lib;%PythonPath% -SET PythonPath=%PythonInstallDirectory%\Lib\lib-tk;%PythonPath% -SET PythonPath=%PythonInstallDirectory%\DLLs;%PythonPath% -SET PythonPath=%PythonInstallDirectory%\Lib;%PythonPath% -SET PythonPath=%PythonInstallDirectory%;%PythonPath% - -REM Eliminate variables that will no longer be used. -SET PythonInstallDirectory= -SET JavaJreDirectory= - -REM Determine where we will be logging to. -SET HOME_DIRECTORY=%USERPROFILE% -SET CAVEDATA_LOG_DIRECTORY=%HOME_DIRECTORY%\caveData\logs -SET CONSOLE_LOG_DIRECTORY=%CAVEDATA_LOG_DIRECTORY%\consoleLogs\%COMPUTERNAME% -IF NOT EXIST "%CONSOLE_LOG_DIRECTORY%" (MKDIR "%CONSOLE_LOG_DIRECTORY%") - -SET RND=%random% -SET RND_DATETIME_FILE=%TMP%\awips2dt_%RND%.tmp -REM Python is used to retrieve the current date and time because the order -REM of the Windows date/time fields is not necessarily guaranteed and the -REM Windows date/time fields can only be extracted using substring operations -REM instead of -formatter- strings like Linux allows. -python -c "from datetime import datetime; print datetime.now().strftime('%%Y%%m%%d_%%H%%M%%S');" > %RND_DATETIME_FILE% -SET /p LOG_DATETIME= < %RND_DATETIME_FILE% -DEL %RND_DATETIME_FILE% - -SET LOGFILE_CAVE=%CAVEDATA_LOG_DIRECTORY%\cave_%LOG_DATETIME%_logs.log -SET LOGFILE_CONSOLE=%CAVEDATA_LOG_DIRECTORY%\cave_%LOG_DATETIME%_console.log -SET LOGFILE_PERFORMANCE=%CAVEDATA_LOG_DIRECTORY%\cave_%LOG_DATETIME%_perf.log -SET LOGFILE_PRODUCT_EDITOR=%CAVEDATA_LOG_DIRECTORY%\cave_%LOG_DATETIME%_productEditor.log - -echo THIS CMD WINDOW CAN BE CLOSED AT ANY TIME! -cd %HOMEPATH% -REM Start CAVE. -"%CONTAINING_DIRECTORY%cave.exe" %* > "%CONSOLE_LOG_DIRECTORY%\cave_%LOG_DATETIME%.log" 2>&1 -IF ERRORLEVEL 1 (echo CAVE ERROR - check the logs for additional information. && PAUSE) - -EXIT diff --git a/cave/build/static/win32.x86/alertviz/alertviz.bat b/cave/build/static/win32.x86/alertviz/alertviz.bat deleted file mode 100644 index 5e4b50ee83..0000000000 --- a/cave/build/static/win32.x86/alertviz/alertviz.bat +++ /dev/null @@ -1,69 +0,0 @@ -@echo OFF - -REM Determine if we are running on a 32-bit or 64-bit OS. -IF NOT EXIST C:\Windows\SysWOW64\reg.exe ( - SET REG_EXE=C:\Windows\System32\reg.exe -) ELSE ( - SET REG_EXE=C:\Windows\SysWOW64\reg.exe -) - -REM Determine where we are located. -SET CONTAINING_DIRECTORY=%~dp0 - -REM Prepare the environment. - -REM Registry Query Variables. -SET A2_JAVA_REG="HKLM\Software\Raytheon\Runtime Environment\AWIPS II Java" -SET A2_PYTHON_REG="HKLM\Software\Raytheon\Runtime Environment\AWIPS II Python" -REM Determine where AWIPS II Java (the jre) is located. -%REG_EXE% QUERY %A2_JAVA_REG% /v JavaJreDirectory > NUL 2>&1 -IF ERRORLEVEL 1 (echo ENVIRONMENT ERROR - Unable to find AWIPS II Java. && PAUSE && EXIT) -FOR /F "tokens=2* delims= " %%A IN ( -'%REG_EXE% QUERY %A2_JAVA_REG% /v JavaJreDirectory') DO ( -SET JavaJreDirectory=%%B) -REM Determine where AWIPS II Python is located. -%REG_EXE% QUERY %A2_PYTHON_REG% /v PythonInstallDirectory > NUL 2>&1 -IF ERRORLEVEL 1 (echo ENVIRONMENT ERROR - Unable to find AWIPS II Python. && PAUSE && EXIT) -FOR /F "tokens=2* delims= " %%A IN ( -'%REG_EXE% QUERY %A2_PYTHON_REG% /v PythonInstallDirectory') DO ( -SET PythonInstallDirectory=%%B) - -REM Add Java and Python to the path. -SET Path=%PythonInstallDirectory%;%PythonInstallDirectory%\DLLs;%Path% -SET Path=%JavaJreDirectory%\bin;%Path% -REM Define 'PythonPath'. -SET PythonPath=%PythonInstallDirectory%\Lib\lib-tk;%PythonPath% -SET PythonPath=%PythonInstallDirectory%\DLLs;%PythonPath% -SET PythonPath=%PythonInstallDirectory%\Lib;%PythonPath% -SET PythonPath=%PythonInstallDirectory%;%PythonPath% - -REM Eliminate variables that will no longer be used. -SET PythonInstallDirectory= -SET JavaJreDirectory= -SET REG_EXE= -SET A2_JAVA_REG= -SET A2_PYTHON_REG= - -REM Determine where we will be logging to. -SET HOME_DIRECTORY=%HOMEDRIVE%%HOMEPATH% -SET CAVEDATA_LOG_DIRECTORY=%HOMEDRIVE%%HOMEPATH%\caveData\logs -SET CONSOLE_LOG_DIRECTORY=%CAVEDATA_LOG_DIRECTORY%\consoleLogs\%COMPUTERNAME% -IF NOT EXIST "%CONSOLE_LOG_DIRECTORY%" (MKDIR "%CONSOLE_LOG_DIRECTORY%") - -echo Starting ALERTVIZ; leave this CMD window open to enable AlertViz 'restart'. -REM Start AlertViz (and implement the alertviz restart capability). -:AlertVizLoopStart -SET RND=%random% -SET RND_DATETIME_FILE=%TMP%\awips2dt_%RND%.tmp -REM Python is used to retrieve the current date and time because the order -REM of the Windows date/time fields is not necessarily guaranteed and the -REM Windows date/time fields can only be extracted using substring operations -REM instead of -formatter- strings like Linux allows. -python -c "from datetime import datetime; print datetime.now().strftime('%%Y%%m%%d_%%H%%M%%S');" > %RND_DATETIME_FILE% -SET /p LOG_DATETIME= < %RND_DATETIME_FILE% -DEL %RND_DATETIME_FILE% -"%CONTAINING_DIRECTORY%alertviz.exe" %* > "%CONSOLE_LOG_DIRECTORY%\alertviz_%LOG_DATETIME%.log" 2>&1 -IF %ERRORLEVEL% == 0 (EXIT) -echo Restarting AlertViz. -GOTO AlertVizLoopStart - diff --git a/cave/build/static/win32.x86/cave/cave.bat b/cave/build/static/win32.x86/cave/cave.bat deleted file mode 100644 index 0b347287dd..0000000000 --- a/cave/build/static/win32.x86/cave/cave.bat +++ /dev/null @@ -1,72 +0,0 @@ -@echo OFF - -REM Determine if we are running on a 32-bit or 64-bit OS. -IF NOT EXIST C:\Windows\SysWOW64\reg.exe ( - SET REG_EXE=C:\Windows\System32\reg.exe -) ELSE ( - SET REG_EXE=C:\Windows\SysWOW64\reg.exe -) - -REM Determine where we are located. -SET CONTAINING_DIRECTORY=%~dp0 - -REM Prepare the environment. - -REM Registry Query Variables. -SET A2_JAVA_REG="HKLM\Software\Raytheon\Runtime Environment\AWIPS II Java" -SET A2_PYTHON_REG="HKLM\Software\Raytheon\Runtime Environment\AWIPS II Python" -REM Determine where AWIPS II Java (the jre) is located. -%REG_EXE% QUERY %A2_JAVA_REG% /v JavaJreDirectory > NUL 2>&1 -IF ERRORLEVEL 1 (echo ENVIRONMENT ERROR - Unable to find AWIPS II Java. && PAUSE && EXIT) -FOR /F "tokens=2* delims= " %%A IN ( -'%REG_EXE% QUERY %A2_JAVA_REG% /v JavaJreDirectory') DO ( -SET JavaJreDirectory=%%B) -REM Determine where AWIPS II Python is located. -%REG_EXE% QUERY %A2_PYTHON_REG% /v PythonInstallDirectory > NUL 2>&1 -IF ERRORLEVEL 1 (echo ENVIRONMENT ERROR - Unable to find AWIPS II Python. && PAUSE && EXIT) -FOR /F "tokens=2* delims= " %%A IN ( -'%REG_EXE% QUERY %A2_PYTHON_REG% /v PythonInstallDirectory') DO ( -SET PythonInstallDirectory=%%B) - -REM Add Java and Python to the path. -SET Path=%PythonInstallDirectory%;%PythonInstallDirectory%\DLLs;%Path% -SET Path=%JavaJreDirectory%\bin;%Path% -REM Add the CAVE lib directory to the path. -SET Path=%CONTAINING_DIRECTORY%lib;%Path% -REM Define 'PythonPath'. -SET PythonPath=%CONTAINING_DIRECTORY%lib;%PythonPath% -SET PythonPath=%PythonInstallDirectory%\Lib\lib-tk;%PythonPath% -SET PythonPath=%PythonInstallDirectory%\DLLs;%PythonPath% -SET PythonPath=%PythonInstallDirectory%\Lib;%PythonPath% -SET PythonPath=%PythonInstallDirectory%;%PythonPath% - -REM Eliminate variables that will no longer be used. -SET PythonInstallDirectory= -SET JavaJreDirectory= -SET REG_EXE= -SET A2_JAVA_REG= -SET A2_PYTHON_REG= - -REM Determine where we will be logging to. -SET HOME_DIRECTORY=%HOMEDRIVE%%HOMEPATH% -SET CAVEDATA_LOG_DIRECTORY=%HOMEDRIVE%%HOMEPATH%\caveData\logs -SET CONSOLE_LOG_DIRECTORY=%CAVEDATA_LOG_DIRECTORY%\consoleLogs\%COMPUTERNAME% -IF NOT EXIST "%CONSOLE_LOG_DIRECTORY%" (MKDIR "%CONSOLE_LOG_DIRECTORY%") - -SET RND=%random% -SET RND_DATETIME_FILE=%TMP%\awips2dt_%RND%.tmp -REM Python is used to retrieve the current date and time because the order -REM of the Windows date/time fields is not necessarily guaranteed and the -REM Windows date/time fields can only be extracted using substring operations -REM instead of -formatter- strings like Linux allows. -python -c "from datetime import datetime; print datetime.now().strftime('%%Y%%m%%d_%%H%%M%%S');" > %RND_DATETIME_FILE% -SET /p LOG_DATETIME= < %RND_DATETIME_FILE% -DEL %RND_DATETIME_FILE% - -echo THIS CMD WINDOW CAN BE CLOSED AT ANY TIME! -cd %HOMEPATH% -REM Start CAVE. -"%CONTAINING_DIRECTORY%cave.exe" %* > "%CONSOLE_LOG_DIRECTORY%\cave_%LOG_DATETIME%.log" 2>&1 -IF ERRORLEVEL 1 (echo CAVE ERROR - check the logs for additional information. && PAUSE) - -EXIT diff --git a/cave/build/static/win32.x86/cave/lib/gridslice.pyd b/cave/build/static/win32.x86/cave/lib/gridslice.pyd deleted file mode 100644 index e4e744bb67..0000000000 Binary files a/cave/build/static/win32.x86/cave/lib/gridslice.pyd and /dev/null differ diff --git a/cave/build/static/win32.x86/cave/lib/libgcc_s_dw2-1.dll b/cave/build/static/win32.x86/cave/lib/libgcc_s_dw2-1.dll deleted file mode 100644 index 8e343cd382..0000000000 Binary files a/cave/build/static/win32.x86/cave/lib/libgcc_s_dw2-1.dll and /dev/null differ diff --git a/cave/build/static/win32.x86/cave/lib/libgfortran-3.dll b/cave/build/static/win32.x86/cave/lib/libgfortran-3.dll deleted file mode 100644 index 98181eb311..0000000000 Binary files a/cave/build/static/win32.x86/cave/lib/libgfortran-3.dll and /dev/null differ diff --git a/cave/build/static/win32.x86/cave/lib/libquadmath-0.dll b/cave/build/static/win32.x86/cave/lib/libquadmath-0.dll deleted file mode 100644 index 08de7b74a4..0000000000 Binary files a/cave/build/static/win32.x86/cave/lib/libquadmath-0.dll and /dev/null differ diff --git a/cave/build/static/win32.x86/cave/lib/zlib1.dll b/cave/build/static/win32.x86/cave/lib/zlib1.dll deleted file mode 100644 index 076f50336d..0000000000 Binary files a/cave/build/static/win32.x86/cave/lib/zlib1.dll and /dev/null differ diff --git a/cave/com.raytheon.uf.viz.alertview.feature/.project b/cave/com.raytheon.uf.viz.alertview.feature/.project new file mode 100644 index 0000000000..2269f0de66 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview.feature/.project @@ -0,0 +1,17 @@ + + + com.raytheon.uf.viz.alertview.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/cave/com.raytheon.uf.viz.alertview.feature/build.properties b/cave/com.raytheon.uf.viz.alertview.feature/build.properties new file mode 100644 index 0000000000..64f93a9f0b --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview.feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/cave/com.raytheon.uf.viz.alertview.feature/feature.xml b/cave/com.raytheon.uf.viz.alertview.feature/feature.xml new file mode 100644 index 0000000000..f2cfce4996 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview.feature/feature.xml @@ -0,0 +1,44 @@ + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.alertview.localization/.classpath b/cave/com.raytheon.uf.viz.alertview.localization/.classpath new file mode 100644 index 0000000000..098194ca4b --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview.localization/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/cave/com.raytheon.uf.viz.alertview.localization/.project b/cave/com.raytheon.uf.viz.alertview.localization/.project new file mode 100644 index 0000000000..b1e1ee01af --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview.localization/.project @@ -0,0 +1,33 @@ + + + com.raytheon.uf.viz.alertview.localization + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/cave/com.raytheon.uf.viz.alertview.localization/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.alertview.localization/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..f635d38227 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview.localization/META-INF/MANIFEST.MF @@ -0,0 +1,12 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: AlertView Localization +Bundle-SymbolicName: com.raytheon.uf.viz.alertview.localization +Bundle-Version: 1.15.0.qualifier +Bundle-Vendor: RAYTHEON +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-ActivationPolicy: lazy +Require-Bundle: com.raytheon.uf.common.localization;bundle-version="1.14.1", + com.raytheon.uf.viz.alertview;bundle-version="1.15.0" +Service-Component: OSGI-INF/*.xml + diff --git a/cave/com.raytheon.uf.viz.alertview.localization/OSGI-INF/alertPrefs.xml b/cave/com.raytheon.uf.viz.alertview.localization/OSGI-INF/alertPrefs.xml new file mode 100644 index 0000000000..7bd654f059 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview.localization/OSGI-INF/alertPrefs.xml @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.alertview.localization/build.properties b/cave/com.raytheon.uf.viz.alertview.localization/build.properties new file mode 100644 index 0000000000..c58ea2178c --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview.localization/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + OSGI-INF/ diff --git a/cave/com.raytheon.uf.viz.alertview.localization/src/com/raytheon/uf/viz/alertview/localization/AlertViewLocalizationPrefStore.java b/cave/com.raytheon.uf.viz.alertview.localization/src/com/raytheon/uf/viz/alertview/localization/AlertViewLocalizationPrefStore.java new file mode 100644 index 0000000000..243db1d14c --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview.localization/src/com/raytheon/uf/viz/alertview/localization/AlertViewLocalizationPrefStore.java @@ -0,0 +1,170 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.localization; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; + +import com.raytheon.uf.common.localization.FileUpdatedMessage; +import com.raytheon.uf.common.localization.ILocalizationFileObserver; +import com.raytheon.uf.common.localization.IPathManager; +import com.raytheon.uf.common.localization.LocalizationContext; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; +import com.raytheon.uf.common.localization.LocalizationFile; +import com.raytheon.uf.common.localization.LocalizationFileOutputStream; +import com.raytheon.uf.common.localization.exception.LocalizationException; +import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException; +import com.raytheon.uf.viz.alertview.AlertViewPrefStore; + +/** + * + * An {@link AlertViewPrefStore} that stores preferences in + * {@link LocalizationFile}s. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 26, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class AlertViewLocalizationPrefStore implements AlertViewPrefStore, + ILocalizationFileObserver { + + private static final String BASE_PATH = "alertView" + + IPathManager.SEPARATOR; + + private final Set listeners = new CopyOnWriteArraySet<>(); + + private IPathManager pathManager; + + protected LocalizationFile getRootFile() { + LocalizationContext context = pathManager.getContext( + LocalizationType.COMMON_STATIC, LocalizationLevel.BASE); + return pathManager.getLocalizationFile(context, BASE_PATH); + } + + public void setPathManager(IPathManager pathManager) { + this.pathManager = pathManager; + getRootFile().addFileUpdatedObserver(this); + } + + public void unsetPathManager(IPathManager pathManager) { + if (pathManager == this.pathManager) { + getRootFile().removeFileUpdatedObserver(this); + this.pathManager = null; + } + } + + @Override + public InputStream readConfigFile(String fileName) throws IOException { + LocalizationFile file = pathManager.getStaticLocalizationFile( + LocalizationType.COMMON_STATIC, BASE_PATH + fileName); + if (file == null) { + return null; + } else { + try { + return file.openInputStream(); + } catch (LocalizationException e) { + throw new IOException(e); + } + } + } + + @Override + public OutputStream writeConfigFile(String fileName) throws IOException { + LocalizationContext context = pathManager.getContext( + LocalizationType.COMMON_STATIC, LocalizationLevel.USER); + LocalizationFile file = pathManager.getLocalizationFile(context, + BASE_PATH + fileName); + if (file == null) { + return null; + } else { + try { + return new SavingOutputStream(file.openOutputStream()); + } catch (LocalizationException e) { + throw new IOException(e); + } + } + } + + @Override + public void addListener(AlertViewPrefListener listener) { + listeners.remove(listener); + } + + @Override + public void removeListener(AlertViewPrefListener listener) { + listeners.add(listener); + } + + @Override + public void fileUpdated(FileUpdatedMessage message) { + String fileName = message.getFileName().substring(BASE_PATH.length()); + for (AlertViewPrefListener listener : listeners) { + listener.prefFileChanged(fileName); + } + } + + private class SavingOutputStream extends OutputStream { + + private final LocalizationFileOutputStream stream; + + public SavingOutputStream(LocalizationFileOutputStream stream) { + this.stream = stream; + } + + @Override + public void close() throws IOException { + try { + stream.closeAndSave(); + } catch (LocalizationOpFailedException e) { + throw new IOException(e); + } + } + + @Override + public void write(int b) throws IOException { + stream.write(b); + } + + @Override + public void write(byte[] b) throws IOException { + stream.write(b); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + stream.write(b, off, len); + } + + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview.logback/.classpath b/cave/com.raytheon.uf.viz.alertview.logback/.classpath new file mode 100644 index 0000000000..098194ca4b --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview.logback/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/cave/com.raytheon.uf.viz.alertview.logback/.project b/cave/com.raytheon.uf.viz.alertview.logback/.project new file mode 100644 index 0000000000..983c827ff2 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview.logback/.project @@ -0,0 +1,28 @@ + + + com.raytheon.uf.viz.alertview.logback + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/cave/com.raytheon.uf.viz.alertview.logback/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.alertview.logback/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..07e0730480 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview.logback/META-INF/MANIFEST.MF @@ -0,0 +1,14 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: LogBack AlertView compatibility +Bundle-SymbolicName: com.raytheon.uf.viz.alertview.logback +Bundle-Version: 1.15.0.qualifier +Bundle-Vendor: RAYTHEON +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Eclipse-RegisterBuddy: ch.qos.logback +Require-Bundle: ch.qos.logback;bundle-version="1.1.2", + com.raytheon.uf.viz.alertview;bundle-version="1.15.0", + org.slf4j;bundle-version="1.7.5" +Import-Package: org.osgi.framework;version="1.7.0", + org.osgi.util.tracker;version="1.5.1" +Bundle-ActivationPolicy: lazy diff --git a/cave/com.raytheon.uf.viz.alertview.logback/build.properties b/cave/com.raytheon.uf.viz.alertview.logback/build.properties new file mode 100644 index 0000000000..34d2e4d2da --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview.logback/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/cave/com.raytheon.uf.viz.alertview.logback/src/com/raytheon/uf/viz/alertview/logback/AlertViewAppender.java b/cave/com.raytheon.uf.viz.alertview.logback/src/com/raytheon/uf/viz/alertview/logback/AlertViewAppender.java new file mode 100644 index 0000000000..1655f4fa74 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview.logback/src/com/raytheon/uf/viz/alertview/logback/AlertViewAppender.java @@ -0,0 +1,118 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.logback; + +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.util.tracker.ServiceTracker; + +import ch.qos.logback.classic.PatternLayout; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.Appender; +import ch.qos.logback.core.AppenderBase; +import ch.qos.logback.core.Layout; + +import com.raytheon.uf.viz.alertview.Alert; +import com.raytheon.uf.viz.alertview.AlertDestination; + +/** + * + * An {@link Appender} that converts {@link ILoggingEvent}s to {@link Alert}s + * and sends them to all registered {@link AlertDestination}s. The + * {@link Appender} can be configured with a {@link Layout} to provide custom + * details in the alert, if no layout is provided the default layout is just the + * exception with a full stack trace. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 16, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class AlertViewAppender extends AppenderBase { + + protected Layout layout; + + private transient ServiceTracker destinationTracker; + + @Override + protected void append(ILoggingEvent event) { + AlertDestination[] destinations = destinationTracker + .getServices(new AlertDestination[0]); + if(destinations == null || destinations.length == 0){ + return; + } + Alert alert = new LoggingEventAlert(layout, event); + for (AlertDestination destination : destinations) { + destination.handleAlert(alert); + } + + } + + @Override + public void start() { + Bundle bundle = FrameworkUtil.getBundle(getClass()); + BundleContext context = bundle.getBundleContext(); + context.addBundleListener(new AppenderBundleListener(bundle, this)); + destinationTracker = new ServiceTracker<>(context, AlertDestination.class, + null); + destinationTracker.open(); + if (layout == null) { + PatternLayout patternLayout = new PatternLayout(); + patternLayout.setContext(this.context); + patternLayout.setPattern("%ex"); + layout = patternLayout; + } + layout.start(); + super.start(); + } + + @Override + public void stop() { + super.stop(); + layout.stop(); + if (destinationTracker != null) { + destinationTracker.close(); + destinationTracker = null; + } + } + + @Override + public boolean isStarted() { + if (super.isStarted()) { + return destinationTracker != null; + } else { + return false; + } + } + + public void setLayout(Layout layout) { + this.layout = layout; + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview.logback/src/com/raytheon/uf/viz/alertview/logback/AppenderBundleListener.java b/cave/com.raytheon.uf.viz.alertview.logback/src/com/raytheon/uf/viz/alertview/logback/AppenderBundleListener.java new file mode 100644 index 0000000000..c5f9ad75f9 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview.logback/src/com/raytheon/uf/viz/alertview/logback/AppenderBundleListener.java @@ -0,0 +1,63 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.logback; + +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleEvent; +import org.osgi.framework.BundleListener; +import org.osgi.framework.SynchronousBundleListener; + +/** + * + * A {@link BundleListener} that is used by the {@link AlertViewAppender} to + * ensure that when the bundle stops the appender is also stopped. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 24, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class AppenderBundleListener implements SynchronousBundleListener { + + private final Bundle bundle; + + private final AlertViewAppender appender; + + public AppenderBundleListener(Bundle bundle, AlertViewAppender appender) { + this.bundle = bundle; + this.appender = appender; + } + + @Override + public void bundleChanged(BundleEvent event) { + if (event.getType() == BundleEvent.STOPPING + && event.getBundle() == bundle) { + appender.stop(); + } + } +} \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.alertview.logback/src/com/raytheon/uf/viz/alertview/logback/LoggingEventAlert.java b/cave/com.raytheon.uf.viz.alertview.logback/src/com/raytheon/uf/viz/alertview/logback/LoggingEventAlert.java new file mode 100644 index 0000000000..65343d3979 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview.logback/src/com/raytheon/uf/viz/alertview/logback/LoggingEventAlert.java @@ -0,0 +1,92 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.logback; + +import java.util.Date; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.Layout; + +import com.raytheon.uf.viz.alertview.Alert; + +/** + * + * Wraps an {@link ILoggingEvent} in the {@link Alert} interface so it can be + * added to the AlertView. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 16, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class LoggingEventAlert implements Alert { + + private final Layout layout; + + private final ILoggingEvent event; + + public LoggingEventAlert(Layout layout, ILoggingEvent event) { + this.layout = layout; + this.event = event; + } + + @Override + public Date getTime() { + return new Date(event.getTimeStamp()); + } + + @Override + public Priority getPriority() { + if (event.getLevel() == Level.ERROR) { + return Priority.ERROR; + } else if (event.getLevel() == Level.WARN) { + return Priority.WARN; + } else if (event.getLevel() == Level.INFO) { + return Priority.INFO; + } else { + return Priority.DEBUG; + } + } + + @Override + public String getOrigin() { + return event.getLoggerName(); + } + + @Override + public String getMessage() { + return event.getFormattedMessage(); + } + + @Override + public String getDetails() { + return layout.doLayout(event); + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview/.classpath b/cave/com.raytheon.uf.viz.alertview/.classpath new file mode 100644 index 0000000000..098194ca4b --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/cave/com.raytheon.uf.viz.alertview/.project b/cave/com.raytheon.uf.viz.alertview/.project new file mode 100644 index 0000000000..d4130d6ea3 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/.project @@ -0,0 +1,33 @@ + + + com.raytheon.uf.viz.alertview + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/cave/com.raytheon.uf.viz.alertview/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.alertview/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..14666825ac --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/META-INF/MANIFEST.MF @@ -0,0 +1,18 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: AlertView +Bundle-SymbolicName: com.raytheon.uf.viz.alertview;singleton:=true +Bundle-Version: 1.15.0.qualifier +Bundle-Vendor: RAYTHEON +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Export-Package: com.raytheon.uf.viz.alertview +Require-Bundle: org.eclipse.ui;bundle-version="3.8.2", + org.eclipse.core.runtime;bundle-version="3.8.0", + org.eclipse.jface.text;bundle-version="3.8.2", + org.eclipse.ui.console;bundle-version="3.5.100", + org.slf4j;bundle-version="1.7.5" +Bundle-ActivationPolicy: lazy +Bundle-ClassPath: com.raytheon.uf.viz.alertview.jar +Service-Component: OSGI-INF/*.xml +Bundle-Activator: com.raytheon.uf.viz.alertview.AlertViewActivator + diff --git a/cave/com.raytheon.uf.viz.alertview/OSGI-INF/alertAutoOpen.xml b/cave/com.raytheon.uf.viz.alertview/OSGI-INF/alertAutoOpen.xml new file mode 100644 index 0000000000..ccb03574d3 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/OSGI-INF/alertAutoOpen.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/cave/com.raytheon.uf.viz.alertview/OSGI-INF/alertPopup.xml b/cave/com.raytheon.uf.viz.alertview/OSGI-INF/alertPopup.xml new file mode 100644 index 0000000000..fd2b44773a --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/OSGI-INF/alertPopup.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/cave/com.raytheon.uf.viz.alertview/OSGI-INF/alertPrefs.xml b/cave/com.raytheon.uf.viz.alertview/OSGI-INF/alertPrefs.xml new file mode 100644 index 0000000000..4819832d66 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/OSGI-INF/alertPrefs.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/cave/com.raytheon.uf.viz.alertview/OSGI-INF/alertStore.xml b/cave/com.raytheon.uf.viz.alertview/OSGI-INF/alertStore.xml new file mode 100644 index 0000000000..24f121c051 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/OSGI-INF/alertStore.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.alertview/build.properties b/cave/com.raytheon.uf.viz.alertview/build.properties new file mode 100644 index 0000000000..cf00724406 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/build.properties @@ -0,0 +1,9 @@ +jars.compile.order = com.raytheon.uf.viz.alertview.jar +source.com.raytheon.uf.viz.alertview.jar = src/ +output.com.raytheon.uf.viz.alertview.jar = bin/ +bin.includes = META-INF/,\ + OSGI-INF/,\ + icons/,\ + plugin.xml,\ + defaultPrefs/,\ + com.raytheon.uf.viz.alertview.jar \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.alertview/defaultPrefs/alert_popup.xml b/cave/com.raytheon.uf.viz.alertview/defaultPrefs/alert_popup.xml new file mode 100644 index 0000000000..6b956ccfee --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/defaultPrefs/alert_popup.xml @@ -0,0 +1,7 @@ + + error + 3000 + 500 + 50 + LOWER_RIGHT + \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.alertview/defaultPrefs/alert_styles.xml b/cave/com.raytheon.uf.viz.alertview/defaultPrefs/alert_styles.xml new file mode 100644 index 0000000000..a276ff49ae --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/defaultPrefs/alert_styles.xml @@ -0,0 +1,7 @@ + + + + diff --git a/cave/com.raytheon.uf.viz.alertview/defaultPrefs/alert_view.xml b/cave/com.raytheon.uf.viz.alertview/defaultPrefs/alert_view.xml new file mode 100644 index 0000000000..35633404b9 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/defaultPrefs/alert_view.xml @@ -0,0 +1,21 @@ + + none + warnPlus + + all + All + + + error + Only Errors + + + warnPlus + Errors and Warnings + + Time + Priority + Message + 1000 + 1000 + \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.alertview/icons/alertView.png b/cave/com.raytheon.uf.viz.alertview/icons/alertView.png new file mode 100644 index 0000000000..47b0c857ad Binary files /dev/null and b/cave/com.raytheon.uf.viz.alertview/icons/alertView.png differ diff --git a/cave/com.raytheon.uf.viz.alertview/plugin.xml b/cave/com.raytheon.uf.viz.alertview/plugin.xml new file mode 100644 index 0000000000..e05ca65c58 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/plugin.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/Alert.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/Alert.java new file mode 100644 index 0000000000..1f254d4ca3 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/Alert.java @@ -0,0 +1,77 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview; + +import java.util.Date; + +import com.raytheon.uf.viz.alertview.ui.view.AlertView; + +/** + * The primary interface for items that should be displayed in {@link AlertView} + * . + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 17, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public interface Alert { + + public enum Priority { + DEBUG, INFO, WARN, ERROR; + } + + /** + * @return The time the event occured that generated this alert. + */ + public Date getTime(); + + /** + * @return The importance of the alert. + */ + public Priority getPriority(); + + /** + * @return An arbitrary string describing the origin of the Alert. This + * should be a short word or phrase that can be used by the user to + * take special action based on origins that are more or less + * important for a specific user. + */ + public String getOrigin(); + + /** + * @return A short summary of the alert. + */ + public String getMessage(); + + /** + * @return A detailed description of the alert. + */ + public String getDetails(); + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/AlertDestination.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/AlertDestination.java new file mode 100644 index 0000000000..4ff459e9d8 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/AlertDestination.java @@ -0,0 +1,47 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview; + +/** + * + * An OSGi service interface for any service component that needs to know about + * {@link Alert}s. Any component which wants to contribute new alerts should + * broadcast the Alert to all registered {@link AlertDestination}s. Any + * componenet that needs to know about new Alerts should implement this + * interface and register as a service. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 17, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public interface AlertDestination { + + public void handleAlert(Alert alert); + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/AlertStore.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/AlertStore.java new file mode 100644 index 0000000000..e5faa6322c --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/AlertStore.java @@ -0,0 +1,50 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview; + +import java.util.List; + +/** + * + * An OSGi service interface that provides a way for the AlertView to load + * {@link Alert}s that arrive while it is not open. At a minimum a store should + * be accumulating new messages as they arrive. A store may want to provide + * persistant storage so that old alerts can be viewed from a new cave. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 17, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public interface AlertStore { + + /** + * @return All stored alerts. + */ + public List getAlerts(); +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/AlertViewActivator.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/AlertViewActivator.java new file mode 100644 index 0000000000..f9cda9d7cc --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/AlertViewActivator.java @@ -0,0 +1,136 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview; + +import org.eclipse.jface.preference.PreferenceManager; +import org.eclipse.jface.preference.PreferenceNode; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.PlatformUI; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceEvent; +import org.osgi.framework.ServiceListener; + +import com.raytheon.uf.viz.alertview.ui.prefs.AlertViewPreferencePage; +import com.raytheon.uf.viz.alertview.ui.prefs.PopupPreferencePage; +import com.raytheon.uf.viz.alertview.ui.prefs.StylePreferencePage; + +/** + * + * {@link BundleActivator} that is used to only show the preference pages if + * AlertView is being used. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 30, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class AlertViewActivator implements BundleActivator { + + + @Override + public void start(BundleContext context) throws InvalidSyntaxException { + /* + * Only show the preferences if this bundle is activated which will + * happen through declarative services if anyone is using the + * destination. + */ + if (PlatformUI.isWorkbenchRunning()) { + addPreferencePages(); + } else { + String workbenchFilter = "(" + Constants.OBJECTCLASS + "=" + + IWorkbench.class.getName() + ")"; + context.addServiceListener(new ServiceListener() { + + @Override + public void serviceChanged(ServiceEvent event) { + if (event.getType() == ServiceEvent.REGISTERED) { + addPreferencePages(); + } + } + }, workbenchFilter); + } + } + + protected void addPreferencePages() { + PreferenceManager pm = PlatformUI.getWorkbench().getPreferenceManager(); + PreferenceNode alertViewNode = new PreferenceNode( + AlertViewPreferencePage.class.getName(), "Alert View", null, + null) { + + @Override + public void createPage() { + AlertViewPreferencePage page = new AlertViewPreferencePage(); + page.setTitle(getLabelText()); + page.setDescription("Configure AlertView appearance and behavior."); + setPage(page); + } + + }; + PreferenceNode popUpNode = new PreferenceNode( + PopupPreferencePage.class.getName(), "Popup", null, null) { + + @Override + public void createPage() { + PopupPreferencePage page = new PopupPreferencePage(); + page.setTitle(getLabelText()); + page.setDescription("Configure Alert Popup appearance and behavior."); + setPage(page); + } + + }; + PreferenceNode styleNode = new PreferenceNode( + StylePreferencePage.class.getName(), "Style", null, null) { + + @Override + public void createPage() { + StylePreferencePage page = new StylePreferencePage(); + page.setTitle(getLabelText()); + page.setDescription("Configure the way alerts appear in the alert table."); + setPage(page); + } + + }; + + alertViewNode.add(popUpNode); + alertViewNode.add(styleNode); + pm.addToRoot(alertViewNode); + } + + @Override + public void stop(BundleContext context) throws Exception { + if (PlatformUI.isWorkbenchRunning()) { + PreferenceManager pm = PlatformUI.getWorkbench() + .getPreferenceManager(); + pm.remove(AlertViewPreferencePage.class.getName()); + } + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/AlertViewPrefStore.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/AlertViewPrefStore.java new file mode 100644 index 0000000000..edd3663fc2 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/AlertViewPrefStore.java @@ -0,0 +1,60 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * + * An OSGi service interface that supplies configuration information to + * AlertView components. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 17, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public interface AlertViewPrefStore { + + public InputStream readConfigFile(String fileName) throws IOException; + + public OutputStream writeConfigFile(String fileName) throws IOException; + + public void addListener(AlertViewPrefListener listener); + + public void removeListener(AlertViewPrefListener listener); + + public static interface AlertViewPrefListener { + + public void prefFileChanged(String fileName); + + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/action/SaveToFileAction.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/action/SaveToFileAction.java new file mode 100644 index 0000000000..118eae6b01 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/action/SaveToFileAction.java @@ -0,0 +1,215 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.action; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.eclipse.jface.action.Action; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.ui.PlatformUI; +import org.osgi.framework.Bundle; +import org.osgi.framework.FrameworkUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.raytheon.uf.viz.alertview.Alert; +import com.raytheon.uf.viz.alertview.Alert.Priority; +import com.raytheon.uf.viz.alertview.ui.view.AlertView; + +/** + * + * Action for writing an alert to a file. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 24, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class SaveToFileAction extends Action { + + private static final Charset UTF8 = Charset.forName("UTF-8"); + + private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat( + "yyyy-MM-dd HH:mm:ss,SSS"); + + /** Don't waste memory keeping excessive details. */ + private static final int MAX_DETAILS_SIZE = 16 * 1024; + + private static Logger logger = LoggerFactory.getLogger(AlertView.class); + + private final Alert alert; + + private final Path path; + + public SaveToFileAction(Alert alert) { + super("Save to file..."); + this.alert = alert; + this.path = null; + } + + public SaveToFileAction(Alert alert, Path path) { + super("Save to file..."); + this.alert = alert; + this.path = path; + } + + @Override + public void run() { + Path path = this.path; + if (path == null) { + FileDialog fd = new FileDialog(PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getShell(), SWT.SAVE); + fd.setFileName("alert.txt"); + fd.setFilterExtensions(new String[] { "*.txt" }); + String fileName = fd.open(); + if (fileName != null) { + path = Paths.get(fileName); + } else { + return; + } + } + try { + write(path, alert); + } catch (IOException e) { + logger.error("Unable to save alert", e); + } + } + + public static void write(Path path, Alert alert) throws IOException { + Bundle bundle = FrameworkUtil.getBundle(SaveToFileAction.class); + try (BufferedWriter writer = Files.newBufferedWriter(path, UTF8)) { + writer.write("# Written by " + bundle.getSymbolicName() + " " + + bundle.getVersion() + "\n"); + writer.write(alert.getPriority().toString()); + writer.write(" "); + writer.write(TIME_FORMAT.format(alert.getTime())); + writer.write(" "); + writer.write(alert.getMessage()); + writer.write("\n"); + writer.write(alert.getDetails()); + } + } + + public static Alert read(Path path) throws IOException { + byte[] bytes = Files.readAllBytes(path); + String content = new String(bytes, UTF8); + String first = "#"; + String details = content; + while (first.startsWith("#")) { + String[] split = details.split("\n", 2); + if (split.length != 2) { + throw new IOException(path.toString() + + " is not a valid alert file"); + } + first = split[0]; + details = split[1]; + } + String[] split = first.split(" ", 4); + if (split.length != 4) { + throw new IOException(path.toString() + + " is not a valid alert file"); + } + Priority priority; + try { + priority = Priority.valueOf(split[0]); + } catch (IllegalArgumentException e) { + throw new IOException(split[0] + " is not a valid priority."); + } + Date time; + try { + time = TIME_FORMAT.parse(split[1] + " " + split[2]); + } catch (ParseException e) { + throw new IOException(path.toString() + + " is not a valid alert file", e); + } + String message = split[3]; + if (details.length() > MAX_DETAILS_SIZE) { + details = details.substring(0, MAX_DETAILS_SIZE) + + "\n...file content truncated..."; + } + return new ParsedAlert(priority, time, path.toString(), message, + details); + } + + private static class ParsedAlert implements Alert { + + private final Priority priority; + + private final Date time; + + private final String origin; + + private final String message; + + private final String details; + + public ParsedAlert(Priority priority, Date time, String origin, + String message, String details) { + this.priority = priority; + this.time = time; + this.origin = origin; + this.message = message; + this.details = details; + } + + @Override + public Date getTime() { + return time; + } + + @Override + public Priority getPriority() { + return priority; + } + + @Override + public String getOrigin() { + return origin; + } + + @Override + public String getMessage() { + return message; + } + + @Override + public String getDetails() { + return details; + } + + } +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/filter/AlertFilter.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/filter/AlertFilter.java new file mode 100644 index 0000000000..7b903c0d3a --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/filter/AlertFilter.java @@ -0,0 +1,45 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.filter; + +import com.raytheon.uf.viz.alertview.Alert; + +/** + * + * Interface for an object that filters {@link Alert}s. This is used throughout + * alertview to ensure the user can see only alerts they are interested in. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 17, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public interface AlertFilter { + + public boolean filter(Alert alert); +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/filter/ConstantFilter.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/filter/ConstantFilter.java new file mode 100644 index 0000000000..20909e9b0c --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/filter/ConstantFilter.java @@ -0,0 +1,55 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.filter; + +import com.raytheon.uf.viz.alertview.Alert; + +/** + * An {@link AlertFilter} that always returns true, or always returns false, + * ignoring the {@link Alert} that is passed in. This is used to implement a + * filter that either always accepts or always rejects Alerts. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 17, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class ConstantFilter implements AlertFilter { + + public final boolean result; + + public ConstantFilter(boolean result) { + this.result = result; + } + + @Override + public boolean filter(Alert alert) { + return result; + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/filter/FilterManager.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/filter/FilterManager.java new file mode 100644 index 0000000000..b1a154ab36 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/filter/FilterManager.java @@ -0,0 +1,99 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.filter; + +import java.util.HashMap; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.raytheon.uf.viz.alertview.Alert.Priority; + +/** + * + * Provides a lookup mechanism for getting {@link AlertFilter}s using an id. + * This is especially useful when a filter is stored in a preference file + * because the id provides a convenient representation to store it and the + * manager provides a reliable way to lookup filters. + * + * TODO the current implementation just uses a small set of hard-coded filters. + * This should be implemented so that new filters can be added by other plugins + * and possibly even allow user defined filters to do things like regex the + * message. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 17, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class FilterManager { + + /** Name for a filter that accepts all alerts. */ + public static final String ALL = "all"; + + /** Name for a filter that accepts no alerts. */ + public static final String NONE = "none"; + + /** Name for a filter that accepts alerts with priority >= WARN. */ + public static final String WARN_PLUS = "warnPlus"; + + /** Name for a filter that accepts alerts with priority >= INFO. */ + public static final String INFO_PLUS = "infoPlus"; + + private static Logger logger = LoggerFactory.getLogger(FilterManager.class); + + private static final AlertFilter NONE_FILTER = new ConstantFilter(false); + + private final Map filters = new HashMap<>(); + + public FilterManager() { + loadDefaultFilters(); + } + + private void loadDefaultFilters() { + filters.put(ALL, new ConstantFilter(true)); + filters.put(NONE, new ConstantFilter(false)); + for (Priority p : Priority.values()) { + filters.put(p.name().toLowerCase(), new PriorityFilter(p)); + } + filters.put(WARN_PLUS, new MinPriorityFilter(Priority.WARN)); + filters.put(INFO_PLUS, new MinPriorityFilter(Priority.INFO)); + } + + public AlertFilter getFilter(String id) { + AlertFilter filter = filters.get(id); + if (filter == null) { + logger.warn("AlertView FilterManager failed to find a filter with an id of " + + id); + filter = NONE_FILTER; + } + return filter; + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/filter/MinPriorityFilter.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/filter/MinPriorityFilter.java new file mode 100644 index 0000000000..b9c6a52f16 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/filter/MinPriorityFilter.java @@ -0,0 +1,55 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.filter; + +import com.raytheon.uf.viz.alertview.Alert; +import com.raytheon.uf.viz.alertview.Alert.Priority; + +/** + * An {@link AlertFilter} that returns true for {@link Alert}s that have a + * priority equal to or above a specified level. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 17, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class MinPriorityFilter implements AlertFilter { + + private final Priority priority; + + public MinPriorityFilter(Priority priority) { + this.priority = priority; + } + + @Override + public boolean filter(Alert alert) { + return alert.getPriority().ordinal() >= priority.ordinal(); + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/filter/PriorityFilter.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/filter/PriorityFilter.java new file mode 100644 index 0000000000..7c1649ba78 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/filter/PriorityFilter.java @@ -0,0 +1,55 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.filter; + +import com.raytheon.uf.viz.alertview.Alert; +import com.raytheon.uf.viz.alertview.Alert.Priority; + +/** + * An {@link AlertFilter} that returns true for {@link Alert}s that have a + * priority equal to a specified level. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 17, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class PriorityFilter implements AlertFilter { + + private final Priority priority; + + public PriorityFilter(Priority priority) { + this.priority = priority; + } + + @Override + public boolean filter(Alert alert) { + return alert.getPriority() == priority; + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/prefs/AlertViewPreferences.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/prefs/AlertViewPreferences.java new file mode 100644 index 0000000000..a1feec57cf --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/prefs/AlertViewPreferences.java @@ -0,0 +1,269 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.prefs; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import com.raytheon.uf.viz.alertview.Alert.Priority; +import com.raytheon.uf.viz.alertview.filter.FilterManager; +import com.raytheon.uf.viz.alertview.ui.view.AlertTable; +import com.raytheon.uf.viz.alertview.ui.view.AlertView; + +/** + * Contains the preferences that control how {@link AlertView} appears to the + * user. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 17, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +@XmlRootElement +public class AlertViewPreferences { + + private final List DEFAULT_FILTERS = Arrays.asList( + new FilterMenu("All", FilterManager.ALL), new FilterMenu( + "Only Errors", Priority.ERROR.name().toLowerCase()), + new FilterMenu("Errors + Warnings", FilterManager.WARN_PLUS)); + + private final List DEFAULT_COLUMNS = Arrays.asList( + AlertTable.COLUMN_TIME, AlertTable.COLUMN_PRIORITY, + AlertTable.COLUMN_MESSAGE); + + private String openFilter; + + private String activeFilter; + + private List filterMenu; + + private List columns; + + private int alertsToLoad; + + /* Time in ms */ + private int mergeRepeatInterval; + + public AlertViewPreferences() { + /* Everything needs reasonable defaults to keep PreferenceFile happy. */ + openFilter = FilterManager.NONE; + activeFilter = FilterManager.WARN_PLUS; + filterMenu = new ArrayList<>(DEFAULT_FILTERS); + columns = new ArrayList<>(DEFAULT_COLUMNS); + alertsToLoad = 1000; + mergeRepeatInterval = 1000; + } + + public AlertViewPreferences(AlertViewPreferences other) { + this.openFilter = other.getOpenFilter(); + this.activeFilter = other.getActiveFilter(); + this.filterMenu = other.getFilterMenu(); + this.columns = other.getColumns(); + this.alertsToLoad = other.getAlertsToLoad(); + this.mergeRepeatInterval = other.getMergeRepeatInterval(); + } + + public String getOpenFilter() { + return openFilter; + } + + public void setOpenFilter(String openFilter) { + this.openFilter = openFilter; + } + + public String getActiveFilter() { + return activeFilter; + } + + public void setActiveFilter(String activeFilter) { + this.activeFilter = activeFilter; + } + + public List getFilterMenu() { + return filterMenu; + } + + public void setFilterMenu(List filterMenu) { + this.filterMenu = filterMenu; + } + + public int getAlertsToLoad() { + return alertsToLoad; + } + + public void setAlertsToLoad(int alertsToLoad) { + this.alertsToLoad = alertsToLoad; + } + + @XmlElement(name = "column") + public List getColumns() { + return columns; + } + + public void setColumns(List columns) { + this.columns = columns; + } + + public int getMergeRepeatInterval() { + return mergeRepeatInterval; + } + + public void setMergeRepeatInterval(int mergeRepeatInterval) { + this.mergeRepeatInterval = mergeRepeatInterval; + } + + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((activeFilter == null) ? 0 : activeFilter.hashCode()); + result = prime * result + alertsToLoad; + result = prime * result + ((columns == null) ? 0 : columns.hashCode()); + result = prime * result + + ((filterMenu == null) ? 0 : filterMenu.hashCode()); + result = prime * result + mergeRepeatInterval; + result = prime * result + + ((openFilter == null) ? 0 : openFilter.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AlertViewPreferences other = (AlertViewPreferences) obj; + if (activeFilter == null) { + if (other.activeFilter != null) + return false; + } else if (!activeFilter.equals(other.activeFilter)) + return false; + if (alertsToLoad != other.alertsToLoad) + return false; + if (columns == null) { + if (other.columns != null) + return false; + } else if (!columns.equals(other.columns)) + return false; + if (filterMenu == null) { + if (other.filterMenu != null) + return false; + } else if (!filterMenu.equals(other.filterMenu)) + return false; + if (mergeRepeatInterval != other.mergeRepeatInterval) + return false; + if (openFilter == null) { + if (other.openFilter != null) + return false; + } else if (!openFilter.equals(other.openFilter)) + return false; + return true; + } + + + public static class FilterMenu { + + private String text; + + private String filter; + + public FilterMenu() { + + } + + public FilterMenu(String text, String filter) { + this.text = text; + this.filter = filter; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public String getFilter() { + return filter; + } + + public void setFilter(String filter) { + this.filter = filter; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((filter == null) ? 0 : filter.hashCode()); + result = prime * result + ((text == null) ? 0 : text.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + FilterMenu other = (FilterMenu) obj; + if (filter == null) { + if (other.filter != null) + return false; + } else if (!filter.equals(other.filter)) + return false; + if (text == null) { + if (other.text != null) + return false; + } else if (!text.equals(other.text)) + return false; + return true; + } + + } + + public static PreferenceFile load( + PreferenceFile.Listener listener) { + return new PreferenceFile<>("alert_view.xml", + AlertViewPreferences.class, listener); + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/prefs/PopUpPreferences.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/prefs/PopUpPreferences.java new file mode 100644 index 0000000000..4ca4f8a8b9 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/prefs/PopUpPreferences.java @@ -0,0 +1,180 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.prefs; + +import javax.xml.bind.annotation.XmlRootElement; + +import com.raytheon.uf.viz.alertview.Alert.Priority; +import com.raytheon.uf.viz.alertview.ui.popup.AlertPopup; + +/** + * Contains the preferences that control how {@link AlertPopup} appears to the + * user. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 17, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +@XmlRootElement +public class PopUpPreferences { + + public static enum PopUpCorner { + UPPER_LEFT, UPPER_RIGHT, LOWER_LEFT, LOWER_RIGHT; + + public String getPrettyName() { + String name = name(); + String[] words = name.split("_"); + StringBuilder pretty = new StringBuilder(name.length()); + for (String word : words) { + if (pretty.length() > 0) { + pretty.append(' '); + } + pretty.append(word.charAt(0)); + pretty.append(word.substring(1).toLowerCase()); + } + return pretty.toString(); + } + + public static PopUpCorner fromPrettyName(String corner) { + return valueOf(corner.replace(' ', '_').toUpperCase()); + } + } + + private String filter; + + /* Time in ms. */ + private int duration; + + private PopUpCorner corner; + + private int width; + + private int height; + + public PopUpPreferences() { + /* Everything needs reasonable defaults to keep PreferenceFile happy. */ + filter = Priority.ERROR.name().toLowerCase(); + duration = 3000; + corner = PopUpCorner.LOWER_RIGHT; + width = 500; + height = 50; + } + + public PopUpPreferences(PopUpPreferences other) { + this.filter = other.getFilter(); + this.duration = other.getDuration(); + this.corner = other.getCorner(); + this.width = other.getWidth(); + this.height = other.getHeight(); + } + + public String getFilter() { + return filter; + } + + public void setFilter(String filter) { + this.filter = filter; + } + + public int getDuration() { + return duration; + } + + public void setDuration(int duration) { + this.duration = duration; + } + + public PopUpCorner getCorner() { + return corner; + } + + public void setCorner(PopUpCorner corner) { + this.corner = corner; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((corner == null) ? 0 : corner.hashCode()); + result = prime * result + duration; + result = prime * result + ((filter == null) ? 0 : filter.hashCode()); + result = prime * result + height; + result = prime * result + width; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + PopUpPreferences other = (PopUpPreferences) obj; + if (corner != other.corner) + return false; + if (duration != other.duration) + return false; + if (filter == null) { + if (other.filter != null) + return false; + } else if (!filter.equals(other.filter)) + return false; + if (height != other.height) + return false; + if (width != other.width) + return false; + return true; + } + + public static PreferenceFile load( + PreferenceFile.Listener listener) { + return new PreferenceFile<>("alert_popup.xml", PopUpPreferences.class, + listener); + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/prefs/PreferenceFile.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/prefs/PreferenceFile.java new file mode 100644 index 0000000000..ef1d7d0743 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/prefs/PreferenceFile.java @@ -0,0 +1,239 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.prefs; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import javax.xml.bind.DataBindingException; +import javax.xml.bind.JAXB; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceEvent; +import org.osgi.framework.ServiceListener; +import org.osgi.framework.ServiceReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.raytheon.uf.viz.alertview.AlertViewPrefStore; +import com.raytheon.uf.viz.alertview.AlertViewPrefStore.AlertViewPrefListener; + +/** + * + * Handles the serialization and service management of a preference file. This + * class is designed to be a more friendly way to consume an + * {@link AlertViewPrefStore} service. To load preferences using this class the + * Preference class P should be JAXB serializable and must provide a no-arg + * constructor that initializaes the preferences to a usable state. In cases + * when loading the preferences from files fails the no-arg constructor will be + * used to return a default preference object. + * + * This class listens to changes from the {@link AlertViewPrefStore} service and + * notifies its own listeners of changes to the specified file. It also listens + * to changes to the available AlertViewPrefStore services and when a better + * service becomes available it will reload the preferences from the new service + * and notify listeners. This is especially useful during startup if the + * prefered AlertViewPrefStore starts after other components. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 16, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + * @param

+ */ +public class PreferenceFile

{ + + private static final String FILTER = "(" + Constants.OBJECTCLASS + "=" + + AlertViewPrefStore.class.getName() + ")"; + + private Logger logger = LoggerFactory.getLogger(getClass()); + + private final BundleContext context; + + private final String fileName; + + private final Class

type; + + private final Listener listener; + + private final AlertViewPrefListener prefStoreListener = new AlertViewPrefListener() { + + @Override + public void prefFileChanged(String fileName) { + if (fileName.equals(PreferenceFile.this.fileName)) { + updatePreferences(loadFromStore()); + } + } + }; + + private final ServiceListener serviceListener = new ServiceListener() { + + @Override + public void serviceChanged(ServiceEvent event) { + @SuppressWarnings("unchecked") + ServiceReference ref = (ServiceReference) event + .getServiceReference(); + if (event.getType() == ServiceEvent.REGISTERED) { + add(ref); + } else if (event.getType() == ServiceEvent.UNREGISTERING) { + remove(ref); + } + } + }; + + private ServiceReference serviceReference; + + private AlertViewPrefStore prefStore; + + private P preferences; + + public PreferenceFile(String fileName, Class

type, + Listener listener) { + this.fileName = fileName; + this.type = type; + this.listener = listener; + context = FrameworkUtil.getBundle(getClass()).getBundleContext(); + try { + context.addServiceListener(serviceListener, FILTER); + } catch (InvalidSyntaxException e) { + /* + * The FILTER is statically defined and very simple syntax so it is + * unlikely that this will ever happen. + */ + throw new RuntimeException(e); + } + this.preferences = updateServiceReference(context + .getServiceReference(AlertViewPrefStore.class)); + } + + public void close(){ + if(serviceReference != null){ + prefStore.removeListener(prefStoreListener); + context.ungetService(serviceReference); + } + context.removeServiceListener(serviceListener); + } + + protected P updateServiceReference( + ServiceReference serviceReference) { + this.serviceReference = serviceReference; + if (serviceReference != null) { + return updatePrefStore(context.getService(serviceReference)); + } else { + return updatePrefStore(null); + } + } + + protected P updatePrefStore(AlertViewPrefStore prefStore) { + this.prefStore = prefStore; + if (prefStore != null) { + prefStore.addListener(prefStoreListener); + } + return loadFromStore(); + } + + protected P loadFromStore() { + P preferences = null; + if (prefStore != null) { + try (InputStream in = prefStore.readConfigFile(fileName)) { + if (in != null) { + preferences = JAXB.unmarshal(in, type); + } + } catch (IOException | DataBindingException e) { + logger.error("Unable to load {} from {}", type.getSimpleName(), + fileName, e); + } + } + if (preferences == null) { + try { + preferences = type.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + /* + * Docs indicate you should have a public no arg constructor, if + * there isn't one then you get RuntimeExceptions. + */ + throw new RuntimeException(e); + } + } + return preferences; + } + + protected void updatePreferences(P preferences) { + if (!this.preferences.equals(preferences)) { + this.preferences = preferences; + listener.update(preferences); + } + } + + + protected void add(ServiceReference ref) { + if (serviceReference == null || ref.compareTo(serviceReference) > 0) { + if (serviceReference != null) { + prefStore.removeListener(prefStoreListener); + context.ungetService(serviceReference); + } + updatePreferences(updateServiceReference(ref)); + } + } + + protected void remove(ServiceReference ref) { + if (ref.equals(serviceReference)) { + prefStore.removeListener(prefStoreListener); + context.ungetService(serviceReference); + updatePreferences(updateServiceReference(context + .getServiceReference(AlertViewPrefStore.class))); + } + } + + public P get() { + return preferences; + } + + public void write(P preferences) { + if (prefStore != null) { + try (OutputStream out = prefStore.writeConfigFile(fileName)) { + JAXB.marshal(preferences, out); + } catch (IOException e) { + logger.error("Unable to write {} to {}", type.getSimpleName(), + fileName, e); + } + } + updatePreferences(preferences); + } + + public static interface Listener

{ + + public void update(P preference); + + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/prefs/RCPPrefStore.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/prefs/RCPPrefStore.java new file mode 100644 index 0000000000..22b087b325 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/prefs/RCPPrefStore.java @@ -0,0 +1,120 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.prefs; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.osgi.framework.Bundle; +import org.osgi.framework.FrameworkUtil; + +import com.raytheon.uf.viz.alertview.AlertViewPrefStore; + +/** + * + * A simple {@link AlertViewPrefStore} that stores preferences in the state area + * that the Eclipse Runtime Platform provides for this bundle. When no user file + * is available the default version of the file is loaded from within this + * bundle. + * + *

+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 17, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class RCPPrefStore implements AlertViewPrefStore { + + private final Bundle bundle; + + private final IPath root = new Path("defaultPrefs"); + + private final Set listeners = new CopyOnWriteArraySet<>(); + + public RCPPrefStore() { + this.bundle = FrameworkUtil.getBundle(getClass()); + } + + @Override + public InputStream readConfigFile(String fileName) throws IOException { + IPath userPath = Platform.getStateLocation(bundle).append(fileName); + File file = userPath.toFile(); + if (file.exists()) { + return new FileInputStream(file); + } else { + return FileLocator.openStream(bundle, root.append(fileName), false); + } + } + + @Override + public OutputStream writeConfigFile(String fileName) + throws FileNotFoundException { + IPath userPath = Platform.getStateLocation(bundle).append(fileName); + return new NotificationOutputStream(userPath.toFile()); + } + + @Override + public void addListener(AlertViewPrefListener listener) { + listeners.add(listener); + } + + @Override + public void removeListener(AlertViewPrefListener listener) { + listeners.remove(listener); + } + + private class NotificationOutputStream extends FileOutputStream { + + private final String fileName; + + public NotificationOutputStream(File file) throws FileNotFoundException { + super(file); + this.fileName = file.getName(); + } + + @Override + public void close() throws IOException { + super.close(); + for (AlertViewPrefListener listener : listeners) { + listener.prefFileChanged(fileName); + } + } + + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/store/MemoryAlertStore.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/store/MemoryAlertStore.java new file mode 100644 index 0000000000..6e339b392b --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/store/MemoryAlertStore.java @@ -0,0 +1,94 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.store; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ConcurrentLinkedQueue; + +import com.raytheon.uf.viz.alertview.Alert; +import com.raytheon.uf.viz.alertview.AlertDestination; +import com.raytheon.uf.viz.alertview.AlertStore; +import com.raytheon.uf.viz.alertview.prefs.AlertViewPreferences; +import com.raytheon.uf.viz.alertview.prefs.PreferenceFile; + +/** + * + * A simple {@link AlertStore} that retains all {@link Alert}s that arrive in + * memory. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 17, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class MemoryAlertStore implements AlertStore, AlertDestination, + PreferenceFile.Listener { + + private ConcurrentLinkedQueue alerts = new ConcurrentLinkedQueue<>(); + + private final PreferenceFile prefsFile; + + private int retentionCount; + + public MemoryAlertStore() { + prefsFile = AlertViewPreferences.load(this); + retentionCount = prefsFile.get().getAlertsToLoad(); + } + + @Override + public void update(AlertViewPreferences preferences) { + retentionCount = preferences.getAlertsToLoad(); + while (alerts.size() > retentionCount) { + alerts.poll(); + } + } + + /** + * This will get called automatically by declaritive services. + */ + public void deactivate() { + prefsFile.close(); + } + + @Override + public void handleAlert(Alert alert) { + /* Trim too desired number of alerts */ + if (alerts.size() >= retentionCount) { + alerts.poll(); + } + alerts.offer(alert); + + } + + @Override + public List getAlerts() { + return Arrays.asList(alerts.toArray(new Alert[0])); + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/style/AlertStyle.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/style/AlertStyle.java new file mode 100644 index 0000000000..a047c79ca7 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/style/AlertStyle.java @@ -0,0 +1,174 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.style; + +import com.raytheon.uf.viz.alertview.Alert; + +/** + * + * Styles that apply to an {@link Alert}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 18, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class AlertStyle { + + private String filter; + + private String backgroundColor; + + private String foregroundColor; + + private String fontName; + + private String fontStyle; + + private Integer fontSize; + + public AlertStyle() { + + } + + public AlertStyle(AlertStyle other) { + this.filter = other.filter; + this.backgroundColor = other.backgroundColor; + this.foregroundColor = other.foregroundColor; + } + + public String getFilter() { + return filter; + } + + public void setFilter(String filter) { + this.filter = filter; + } + + public String getBackgroundColor() { + return backgroundColor; + } + + public void setBackgroundColor(String backgroundColor) { + this.backgroundColor = backgroundColor; + } + + public String getForegroundColor() { + return foregroundColor; + } + + public void setForegroundColor(String foregroundColor) { + this.foregroundColor = foregroundColor; + } + + public String getFontName() { + return fontName; + } + + public void setFontName(String fontName) { + this.fontName = fontName; + } + + public String getFontStyle() { + return fontStyle; + } + + public void setFontStyle(String fontStyle) { + this.fontStyle = fontStyle; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((backgroundColor == null) ? 0 : backgroundColor.hashCode()); + result = prime * result + ((filter == null) ? 0 : filter.hashCode()); + result = prime * result + + ((fontName == null) ? 0 : fontName.hashCode()); + result = prime * result + + ((fontSize == null) ? 0 : fontSize.hashCode()); + result = prime * result + + ((fontStyle == null) ? 0 : fontStyle.hashCode()); + result = prime * result + + ((foregroundColor == null) ? 0 : foregroundColor.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AlertStyle other = (AlertStyle) obj; + if (backgroundColor == null) { + if (other.backgroundColor != null) + return false; + } else if (!backgroundColor.equals(other.backgroundColor)) + return false; + if (filter == null) { + if (other.filter != null) + return false; + } else if (!filter.equals(other.filter)) + return false; + if (fontName == null) { + if (other.fontName != null) + return false; + } else if (!fontName.equals(other.fontName)) + return false; + if (fontSize == null) { + if (other.fontSize != null) + return false; + } else if (!fontSize.equals(other.fontSize)) + return false; + if (fontStyle == null) { + if (other.fontStyle != null) + return false; + } else if (!fontStyle.equals(other.fontStyle)) + return false; + if (foregroundColor == null) { + if (other.foregroundColor != null) + return false; + } else if (!foregroundColor.equals(other.foregroundColor)) + return false; + return true; + } + + public Integer getFontSize() { + return fontSize; + } + + public void setFontSize(Integer fontSize) { + this.fontSize = fontSize; + } + + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/style/StyleManager.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/style/StyleManager.java new file mode 100644 index 0000000000..57ea126c12 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/style/StyleManager.java @@ -0,0 +1,234 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.style; + +import java.util.concurrent.CopyOnWriteArraySet; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.viz.alertview.Alert; +import com.raytheon.uf.viz.alertview.filter.AlertFilter; +import com.raytheon.uf.viz.alertview.filter.FilterManager; +import com.raytheon.uf.viz.alertview.prefs.PreferenceFile; + +/** + * Converts {@link AlertStyle}s into SWT colors and fonts. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 18, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class StyleManager implements PreferenceFile.Listener { + + private static final String REGULAR = "Regular"; + + private static final String BOLD = "Bold"; + + private static final String ITALIC = "Italic"; + + private static final String BOLD_ITALIC = BOLD + "-" + ITALIC; + + private final FilterManager filterManager = new FilterManager(); + + private final PreferenceFile preferenceFile; + + private final CopyOnWriteArraySet listeners = new CopyOnWriteArraySet<>(); + + public StyleManager() { + preferenceFile = StylePreferences.load(this); + } + + public void addListener(StyleListener listener) { + listeners.add(listener); + } + + public void removeListener(StyleListener listener) { + listeners.remove(listener); + } + + @Override + public void update(StylePreferences preference) { + for(StyleListener listener : listeners){ + listener.updateStyle(); + } + } + + public void close() { + preferenceFile.close(); + } + + public Color getForegroundColor(Device device, Alert alert) { + for (AlertStyle style : preferenceFile.get().getStyles()) { + if (style.getForegroundColor() != null) { + AlertFilter filter = filterManager.getFilter(style.getFilter()); + if (filter.filter(alert)) { + return parseColor(device, style.getForegroundColor()); + } + } + } + return null; + } + + public Color getBackgroundColor(Device device, Alert alert) { + for (AlertStyle style : preferenceFile.get().getStyles()) { + if (style.getBackgroundColor() != null) { + AlertFilter filter = filterManager.getFilter(style.getFilter()); + if (filter.filter(alert)) { + return parseColor(device, style.getBackgroundColor()); + } + } + } + return null; + } + + public Font getFont(Device device, Alert alert) { + String name = null; + Integer size = null; + String fstyle = null; + for (AlertStyle style : preferenceFile.get().getStyles()) { + if (name == null && style.getFontName() != null) { + AlertFilter filter = filterManager.getFilter(style.getFilter()); + if (filter.filter(alert)) { + name = style.getFontName(); + } + } + if (size == null && style.getFontSize() != null) { + AlertFilter filter = filterManager.getFilter(style.getFilter()); + if (filter.filter(alert)) { + size = style.getFontSize(); + } + } + if (fstyle == null && style.getFontStyle() != null) { + AlertFilter filter = filterManager.getFilter(style.getFilter()); + if (filter.filter(alert)) { + fstyle = style.getFontStyle(); + } + } + if (name != null && size != null && fstyle != null) { + break; + } + } + return getFont(device, name, size, fstyle); + } + + public static Font getFont(Device device, AlertStyle style) { + return getFont(device, style.getFontName(), style.getFontSize(), + style.getFontStyle()); + } + + public static Font getFont(Device device, String name, Integer size, + String style) { + Integer fstyle = parseFontStyle(style); + if (name != null && size != null && fstyle != null) { + return new Font(device, new FontData(name, size, fstyle)); + } + if (name == null && size == null && fstyle == null) { + return device.getSystemFont(); + } + FontData systemFontData = device.getSystemFont().getFontData()[0]; + if (name == null) { + name = systemFontData.getName(); + } + if (size == null) { + size = systemFontData.getHeight(); + } + if (fstyle == null) { + fstyle = systemFontData.getStyle(); + } + return new Font(device, new FontData(name, size, fstyle)); + } + + public static void setFont(AlertStyle style, FontData data) { + style.setFontName(data.getName()); + style.setFontSize(data.getHeight()); + style.setFontStyle(formatFontStyle(data.getStyle())); + } + + private static Integer parseFontStyle(String style) { + if (style == null) { + return null; + } else if (style.equalsIgnoreCase(REGULAR)) { + return SWT.NORMAL; + } else if (style.equalsIgnoreCase(BOLD)) { + return SWT.BOLD; + } else if (style.equals(ITALIC)) { + return SWT.ITALIC; + } else if (style.equals(BOLD_ITALIC)) { + return SWT.BOLD | SWT.ITALIC; + } + return null; + } + + private static String formatFontStyle(Integer style) { + if (style == null) { + return null; + } else if ((style & SWT.BOLD) == SWT.BOLD + && (style & SWT.ITALIC) == SWT.ITALIC) { + return BOLD_ITALIC; + } else if ((style & SWT.BOLD) == SWT.BOLD) { + return BOLD; + } else if ((style & SWT.ITALIC) == SWT.ITALIC) { + return ITALIC; + } else if ((style & SWT.NORMAL) == SWT.NORMAL) { + return REGULAR; + } + return null; + } + + public static Color parseColor(Device device, String str) { + if (str == null) { + return null; + } + try { + int red = Integer.parseInt(str.substring(1, 3), 16); + int green = Integer.parseInt(str.substring(3, 5), 16); + int blue = Integer.parseInt(str.substring(5, 7), 16); + return new Color(device, red, green, blue); + } catch (NumberFormatException e) { + e.printStackTrace(); + } + return null; + } + + public static String formatColor(RGB colorValue) { + return String.format("#%02x%02x%02x", colorValue.red, colorValue.green, + colorValue.blue); + } + + public static interface StyleListener { + + public void updateStyle(); + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/style/StylePreferences.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/style/StylePreferences.java new file mode 100644 index 0000000000..0ac58d3359 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/style/StylePreferences.java @@ -0,0 +1,117 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.style; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.viz.alertview.Alert.Priority; +import com.raytheon.uf.viz.alertview.prefs.PreferenceFile; + +/** + * + * JAXB serializable list of {@link AlertStyle}s. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 18, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class StylePreferences { + + @XmlElement(name = "style") + private List styles = new ArrayList<>(); + + public StylePreferences() { + AlertStyle errorStyle = new AlertStyle(); + errorStyle.setFilter(Priority.ERROR.name().toLowerCase()); + errorStyle.setForegroundColor(StyleManager.formatColor(new RGB(255, 0, + 0))); + styles.add(errorStyle); + } + + public StylePreferences(List styles) { + this.styles = styles; + } + + public List getStyles() { + return styles; + } + + public void setStyles(List styles) { + this.styles = styles; + } + + public void addStyle(AlertStyle style) { + if (styles == null) { + styles = new ArrayList(); + } + styles.add(style); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((styles == null) ? 0 : styles.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + StylePreferences other = (StylePreferences) obj; + if (styles == null) { + if (other.styles != null) + return false; + } else if (!styles.equals(other.styles)) + return false; + return true; + } + + public static PreferenceFile load( + PreferenceFile.Listener listener) { + return new PreferenceFile<>("alert_styles.xml", StylePreferences.class, + listener); + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/popup/AlertPopup.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/popup/AlertPopup.java new file mode 100644 index 0000000000..452f119c45 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/popup/AlertPopup.java @@ -0,0 +1,276 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.ui.popup; + +import java.util.Timer; +import java.util.TimerTask; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; + +import com.raytheon.uf.viz.alertview.Alert; +import com.raytheon.uf.viz.alertview.AlertDestination; +import com.raytheon.uf.viz.alertview.filter.FilterManager; +import com.raytheon.uf.viz.alertview.prefs.PopUpPreferences; +import com.raytheon.uf.viz.alertview.prefs.PreferenceFile; +import com.raytheon.uf.viz.alertview.style.StyleManager; +import com.raytheon.uf.viz.alertview.ui.view.AlertView; +import com.raytheon.uf.viz.alertview.ui.view.OpenAlertViewHandler; + +/** + * + * An {@link AlertDestination} which displays {@link Alert}s in a small popup + * window. The window only display for a few seconds(exact time is configurable) + * and then disappears. If the user clicks the popup it will open the displayed + * alert in the {@link AlertView} + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 17, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class AlertPopup implements AlertDestination, + PreferenceFile.Listener { + + private final PopupAlertTask task = new PopupAlertTask(); + + private final PreferenceFile prefsFile; + + protected final FilterManager filters = new FilterManager(); + + protected final StyleManager styles = new StyleManager(); + + protected PopUpPreferences prefs; + + public AlertPopup() { + prefsFile = PopUpPreferences.load(this); + prefs = prefsFile.get(); + } + + @Override + public void update(PopUpPreferences preferences) { + prefs = preferences; + } + + /** + * This will get called automatically by declaritive services. + */ + public void deactivate() { + prefsFile.close(); + styles.close(); + } + + @Override + public void handleAlert(Alert alert) { + if (filters.getFilter(prefs.getFilter()).filter(alert)) { + task.update(alert); + } + } + + /** + * This task will run on the UI thread and is responsible for managing the + * popup window. This should not be run directly but will schedule itself + * when {@link #update(Alert)} or {@link #clear(Alert)} is called. + */ + private class PopupAlertTask implements Runnable { + + private final Timer timer = new Timer("Remove Alert Popup"); + + private Shell shell; + + private Label label; + + /** + * This is the alert that should be dispalyed, the most recent alert + * passed to update which has not been passed to clear. + */ + private volatile Alert alert; + + /** + * This is the currently displayed alert, it should only be used from + * the UI thread. If this task is waiting to be run on the UI thread + * then this will not be the same as alert. + */ + private Alert displayedAlert; + + /** + * Update the popup window with the provided alert. If the window is not + * currently open then a new popup window will be opened to display the + * alert. If a popup window is already displayed then this alert will + * replace any other alert in the popup window. This method schedules an + * update on the UI thread but it does not block. If multiple calls to + * {@link #update(Alert)} are made before the UI thread becomes + * available then only the most recent Alert will be displayed. + */ + public synchronized void update(Alert alert) { + this.alert = alert; + Display.getDefault().asyncExec(this); + } + + /** + * Close the popup if the provided alert is the most recent alert that + * should be displayed. The alert is provided to make clear an atomic + * operation. If another alert has been provided to + * {@link #update(Alert)} since clear was called then it will be a no-op + * because the more recent alert needs to be displayed. + */ + public synchronized void clear(Alert alert) { + if (alert == this.alert) { + this.alert = null; + Display.getDefault().asyncExec(this); + } + } + + public void openInAlertView() { + if (displayedAlert != null) { + OpenAlertViewHandler.openInAlertView(displayedAlert); + clear(displayedAlert); + } + } + + @Override + public void run() { + this.displayedAlert = this.alert; + if (displayedAlert != null && (shell == null || shell.isDisposed())) { + shell = new Shell(Display.getDefault(), SWT.NO_FOCUS + | SWT.NO_TRIM | SWT.ON_TOP); + GridLayout layout = new GridLayout(1, false); + layout.marginHeight = 0; + layout.marginWidth = 0; + shell.setLayout(layout); + shell.setForeground(Display.getDefault().getSystemColor( + SWT.COLOR_BLACK)); + shell.addListener(SWT.Dispose, new Listener() { + @Override + public void handleEvent(Event event) { + shell = null; + } + }); + + final Composite comp = new Composite(shell, SWT.BORDER); + + layout = new GridLayout(1, false); + layout.marginHeight = 0; + layout.marginWidth = 0; + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + comp.setLayout(layout); + comp.setLayoutData(data); + + label = new Label(comp, SWT.WRAP); + data = new GridData(SWT.FILL, SWT.FILL, true, true); + label.setLayoutData(data); + label.addMouseListener(new MouseAdapter() { + @Override + public void mouseUp(MouseEvent e) { + openInAlertView(); + } + + }); + shell.setSize(prefs.getWidth(), prefs.getHeight()); + + Rectangle clientArea = Display.getDefault().getMonitors()[0] + .getClientArea(); + + int offset = 2; + int startX = offset; + int startY = offset; + switch (prefs.getCorner()) { + case UPPER_LEFT: + startX = clientArea.x + offset; + startY = clientArea.y + offset; + break; + case UPPER_RIGHT: + startX = clientArea.x + clientArea.width + - shell.getSize().x - offset; + startY = clientArea.y + offset; + break; + case LOWER_LEFT: + startX = clientArea.x + offset; + startY = clientArea.y + clientArea.height + - shell.getSize().y - offset; + break; + case LOWER_RIGHT: + startX = clientArea.x + clientArea.width + - shell.getSize().x - offset; + startY = clientArea.y + clientArea.height + - shell.getSize().y - offset; + break; + } + + shell.setLocation(startX, startY); + shell.setVisible(true); + } + if (displayedAlert == null) { + if (shell != null && !shell.isDisposed()) { + shell.dispose(); + } + } else { + Display display = shell.getDisplay(); + label.setBackground(styles.getBackgroundColor(display, + displayedAlert)); + label.setForeground(styles.getForegroundColor(display, + displayedAlert)); + label.setFont(styles.getFont(display, displayedAlert)); + label.setText(displayedAlert.getMessage()); + timer.schedule(new ClosePopupTask(displayedAlert), + prefs.getDuration()); + } + } + } + + /** + * This task is scheduled from the UI thread whenever an alert is displayed + * in a popup. It will call clear after the popup has expired. It is never + * canceled but instead it relies on the atomic nature of + * {@link #clear(Alert)} to ensure that if another alert arrives it will not + * close the popup. + */ + private class ClosePopupTask extends TimerTask { + + private final Alert alert; + + public ClosePopupTask(Alert alert) { + this.alert = alert; + } + + @Override + public void run() { + task.clear(alert); + } + } +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/prefs/AlertViewPreferencePage.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/prefs/AlertViewPreferencePage.java new file mode 100644 index 0000000000..b91fdb69b6 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/prefs/AlertViewPreferencePage.java @@ -0,0 +1,213 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.ui.prefs; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; + +import com.raytheon.uf.viz.alertview.prefs.AlertViewPreferences; +import com.raytheon.uf.viz.alertview.prefs.PreferenceFile; +import com.raytheon.uf.viz.alertview.ui.view.AlertTable; + +/** + * Preference page for configuring {@link AlertViewPreferences} + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 25, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class AlertViewPreferencePage extends PreferencePage implements + PreferenceFile.Listener { + + protected PreferenceFile preferenceFile; + + protected PriorityFilterCombo openFilterCombo; + + protected Text intervalText; + + protected Table columnTable; + + @Override + protected Control createContents(Composite parent) { + preferenceFile = AlertViewPreferences.load(this); + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayout(new GridLayout(2, false)); + + new Label(composite, SWT.NONE).setText("Auto Open Priority: "); + openFilterCombo = new PriorityFilterCombo(composite); + + new Label(composite, SWT.NONE) + .setText("Hide Duplicate Interval(seconds): "); + intervalText = new Text(composite, SWT.SINGLE | SWT.BORDER); + GridData gridData = new GridData(); + gridData.widthHint = 30; + intervalText.setLayoutData(gridData); + Group columnGroup = new Group(composite, SWT.NONE); + columnGroup.setLayout(new GridLayout(2, false)); + columnGroup.setText("Column Configuration"); + columnTable = new Table(columnGroup, SWT.CHECK); + Composite columnButtonComp = new Composite(columnGroup, SWT.NONE); + RowLayout rowLayout = new RowLayout(SWT.VERTICAL); + rowLayout.fill = true; + rowLayout.justify = true; + columnButtonComp.setLayout(rowLayout); + Button up = new Button(columnButtonComp, SWT.PUSH); + up.setText("Up"); + up.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + moveColumn(true); + } + + }); + Button down = new Button(columnButtonComp, SWT.PUSH); + down.setText("Down"); + down.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + moveColumn(false); + } + + }); + populate(); + return composite; + } + + public void moveColumn(boolean up) { + int selection = columnTable.getSelectionIndex(); + if (selection < 0) { + return; + } + int newIndex; + if (up) { + if (selection == 0) { + return; + } + newIndex = selection - 1; + } else { + if (selection == columnTable.getItemCount() - 1) { + return; + } + newIndex = selection + 2; + } + TableItem oldItem = columnTable.getItem(selection); + TableItem newItem = new TableItem(columnTable, SWT.NONE, newIndex); + newItem.setText(oldItem.getText()); + newItem.setChecked(oldItem.getChecked()); + oldItem.dispose(); + columnTable.setSelection(newItem); + } + + protected void populate() { + AlertViewPreferences preferences = preferenceFile.get(); + openFilterCombo.setSelection(preferences.getOpenFilter()); + intervalText.setText(Double.toString(preferences + .getMergeRepeatInterval() / 1000.0)); + columnTable.removeAll(); + List columns = preferences.getColumns(); + for (String column : columns) { + TableItem item = new TableItem(columnTable, SWT.NONE); + item.setText(column); + item.setChecked(true); + } + for (String column : AlertTable.ALL_COLUMNS) { + if (!columns.contains(column)) { + TableItem item = new TableItem(columnTable, SWT.NONE); + item.setText(column); + item.setChecked(false); + } + } + } + + @Override + protected void performDefaults() { + populate(); + super.performDefaults(); + } + + @Override + public boolean performOk() { + AlertViewPreferences newPrefs = new AlertViewPreferences( + preferenceFile.get()); + String openFilter = openFilterCombo.getSelection(); + if (openFilter != null) { + newPrefs.setOpenFilter(openFilter); + } + newPrefs.setMergeRepeatInterval((int) (Double.parseDouble(intervalText + .getText()) * 1000)); + List columns = new ArrayList<>(); + for (TableItem item : columnTable.getItems()) { + if (item.getChecked()) { + columns.add(item.getText()); + } + } + newPrefs.setColumns(columns); + preferenceFile.write(newPrefs); + return super.performOk(); + } + + @Override + public void dispose() { + preferenceFile.close(); + super.dispose(); + } + + @Override + public void update(AlertViewPreferences preferences) { + Display.getDefault().asyncExec(new Runnable() { + + @Override + public void run() { + if (!getControl().isDisposed()) { + populate(); + } + } + }); + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/prefs/OpenPreferencesAction.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/prefs/OpenPreferencesAction.java new file mode 100644 index 0000000000..5e8d1cd52a --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/prefs/OpenPreferencesAction.java @@ -0,0 +1,60 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.ui.prefs; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.preference.IPreferencePage; +import org.eclipse.jface.preference.PreferenceDialog; +import org.eclipse.ui.dialogs.PreferencesUtil; + +/** + * Action which opens {@link PreferenceDialog} with the + * {@link AlertViewPreferencePage} and other associated {@link IPreferencePage}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 25, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class OpenPreferencesAction extends Action { + + public OpenPreferencesAction() { + super("Preferences"); + } + + @Override + public void run() { + PreferencesUtil.createPreferenceDialogOn( + null, + AlertViewPreferencePage.class.getName(), + new String[] { AlertViewPreferencePage.class.getName(), + StylePreferencePage.class.getName(), + PopupPreferencePage.class.getName() }, null).open(); + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/prefs/PopupPreferencePage.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/prefs/PopupPreferencePage.java new file mode 100644 index 0000000000..e4ab1236c8 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/prefs/PopupPreferencePage.java @@ -0,0 +1,172 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.ui.prefs; + +import java.util.Arrays; +import java.util.List; + +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +import com.raytheon.uf.viz.alertview.prefs.PopUpPreferences; +import com.raytheon.uf.viz.alertview.prefs.PopUpPreferences.PopUpCorner; +import com.raytheon.uf.viz.alertview.prefs.PreferenceFile; + +/** + * Preference page for configuring {@link PopUpPreferences} + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 25, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class PopupPreferencePage extends PreferencePage implements + PreferenceFile.Listener { + + private static final List SIZES = Arrays.asList("Small", "Medium", + "Large"); + + private static final int BASE_WIDTH = 500; + + private static final int BASE_HEIGHT = 50; + + protected PreferenceFile preferenceFile; + + protected PriorityFilterCombo filterCombo; + + protected Text durationText; + + protected Combo positionCombo; + + protected Combo sizeCombo; + + @Override + protected Control createContents(Composite parent) { + preferenceFile = PopUpPreferences.load(this); + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayout(new GridLayout(2, false)); + new Label(composite, SWT.NONE).setText("Popup Priority: "); + filterCombo = new PriorityFilterCombo(composite); + new Label(composite, SWT.NONE).setText("Duration(seconds): "); + durationText = new Text(composite, SWT.SINGLE | SWT.BORDER); + GridData gridData = new GridData(); + gridData.widthHint = 30; + durationText.setLayoutData(gridData); + new Label(composite, SWT.NONE).setText("Position: "); + positionCombo = new Combo(composite, SWT.READ_ONLY); + for (PopUpCorner position : PopUpCorner.values()) { + positionCombo.add(position.getPrettyName()); + } + + new Label(composite, SWT.NONE).setText("Size: "); + sizeCombo = new Combo(composite, SWT.READ_ONLY); + for (String size : SIZES) { + sizeCombo.add(size); + } + populate(); + return composite; + } + + protected void populate() { + PopUpPreferences preferences = preferenceFile.get(); + filterCombo.setSelection(preferences.getFilter()); + durationText + .setText(Double.toString(preferences.getDuration() / 1000.0)); + positionCombo.select(positionCombo.indexOf(preferences.getCorner() + .getPrettyName())); + boolean sizeFound = false; + for (int i = 0; i < SIZES.size(); i += 1) { + if (preferences.getHeight() == BASE_HEIGHT + 25 * i + && preferences.getWidth() == BASE_WIDTH + 50 * i) { + sizeCombo.select(i); + sizeFound = true; + break; + } + } + if (!sizeFound) { + if (sizeCombo.getItemCount() > SIZES.size()) { + sizeCombo.remove(SIZES.size()); + } + sizeCombo.add(preferences.getWidth() + " x " + + preferences.getHeight()); + sizeCombo.select(SIZES.size()); + } + } + + @Override + protected void performDefaults() { + populate(); + super.performDefaults(); + } + + @Override + public boolean performOk() { + PopUpPreferences newPrefs = new PopUpPreferences(preferenceFile.get()); + String filter = filterCombo.getSelection(); + if (filter != null) { + newPrefs.setFilter(filter); + } + newPrefs.setDuration((int) (Double.parseDouble(durationText.getText()) * 1000)); + newPrefs.setCorner(PopUpCorner.fromPrettyName(positionCombo.getText())); + int index = SIZES.indexOf(sizeCombo.getText()); + if (index >= 0) { + newPrefs.setWidth(BASE_WIDTH + 50 * index); + newPrefs.setHeight(BASE_HEIGHT + 25 * index); + } + preferenceFile.write(newPrefs); + return super.performOk(); + } + + @Override + public void dispose() { + preferenceFile.close(); + super.dispose(); + } + + @Override + public void update(PopUpPreferences preferences) { + Display.getDefault().asyncExec(new Runnable() { + + @Override + public void run() { + if (!getControl().isDisposed()) { + populate(); + } + } + }); + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/prefs/PriorityFilterCombo.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/prefs/PriorityFilterCombo.java new file mode 100644 index 0000000000..65534e7c25 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/prefs/PriorityFilterCombo.java @@ -0,0 +1,96 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.ui.prefs; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; + +import com.raytheon.uf.viz.alertview.Alert.Priority; +import com.raytheon.uf.viz.alertview.filter.FilterManager; + +/** + * Class for using an {@link Combo} to select a priority level. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 25, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class PriorityFilterCombo { + + /** + * Mapping for pretty user text to filter names for populating priority + * combos. + */ + private static final Map MAPPING = getPriorityFilterMapping(); + + private final Combo combo; + + public PriorityFilterCombo(Composite parent) { + combo = new Combo(parent, SWT.READ_ONLY); + for (Entry entry : MAPPING.entrySet()) { + combo.add(entry.getKey()); + } + } + + public void setSelection(String filter) { + for (Entry entry : MAPPING.entrySet()) { + if (filter.equals(entry.getValue())) { + int index = combo.indexOf(entry.getKey()); + if (index >= 0) { + combo.select(index); + } else { + combo.deselectAll(); + } + } + } + } + + public String getSelection() { + String filter = combo.getText(); + if (filter != null && !filter.isEmpty()) { + return MAPPING.get(filter); + } + return null; + } + + private static Map getPriorityFilterMapping() { + Map mapping = new LinkedHashMap<>(); + mapping.put("None", FilterManager.NONE); + mapping.put("Error", Priority.ERROR.name().toLowerCase()); + mapping.put("Error+Warning", FilterManager.WARN_PLUS); + mapping.put("Error+Warning+Info", FilterManager.INFO_PLUS); + mapping.put("All", FilterManager.ALL); + return mapping; + } +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/prefs/StylePreferencePage.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/prefs/StylePreferencePage.java new file mode 100644 index 0000000000..95cf67a4a8 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/prefs/StylePreferencePage.java @@ -0,0 +1,306 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.ui.prefs; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.preference.ColorSelector; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.FontDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; + +import com.raytheon.uf.viz.alertview.Alert.Priority; +import com.raytheon.uf.viz.alertview.prefs.PreferenceFile; +import com.raytheon.uf.viz.alertview.style.AlertStyle; +import com.raytheon.uf.viz.alertview.style.StyleManager; +import com.raytheon.uf.viz.alertview.style.StylePreferences; + +/** + * Preference page for configuring {@link StylePreferences} + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 25, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class StylePreferencePage extends PreferencePage implements + PreferenceFile.Listener { + + protected PreferenceFile preferenceFile; + + protected Table table; + + protected Combo filterCombo; + + protected ColorSelector foregroundSelector; + + protected ColorSelector backgroundSelector; + + protected Button fontButton; + + @Override + protected Control createContents(Composite parent) { + preferenceFile = StylePreferences.load(this); + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayout(new GridLayout(1, false)); + Composite tableComp = new Composite(composite, SWT.NONE); + tableComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + tableComp.setLayout(new GridLayout(2, false)); + table = new Table(tableComp, SWT.NONE); + table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + table.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + styleSelected(); + } + + }); + Composite columnButtonComp = new Composite(tableComp, SWT.NONE); + RowLayout rowLayout = new RowLayout(SWT.VERTICAL); + rowLayout.fill = true; + rowLayout.justify = true; + columnButtonComp.setLayout(rowLayout); + columnButtonComp.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, false, + true)); + Button newButton = new Button(columnButtonComp, SWT.PUSH); + newButton.setText("New"); + newButton.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + newStyle(); + } + + }); + Button deleteButton = new Button(columnButtonComp, SWT.PUSH); + deleteButton.setText("Delete"); + deleteButton.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + deleteStyle(); + } + + }); + + Composite editComp = new Composite(composite, SWT.NONE); + editComp.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, + false)); + editComp.setLayout(new GridLayout(2, false)); + new Label(editComp, SWT.NONE).setText("Priority: "); + filterCombo = new Combo(editComp, SWT.READ_ONLY); + for (Priority priority : Priority.values()) { + filterCombo.add(priority.name()); + } + filterCombo.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + filterSelected(); + } + + }); + new Label(editComp, SWT.NONE).setText("Foreground Color: "); + foregroundSelector = new ColorSelector(editComp); + foregroundSelector.getButton().setLayoutData( + new GridData(GridData.FILL_HORIZONTAL)); + foregroundSelector.addListener(new IPropertyChangeListener() { + + @Override + public void propertyChange(PropertyChangeEvent event) { + foregroundSelected(); + } + }); + new Label(editComp, SWT.NONE).setText("Background Color: "); + backgroundSelector = new ColorSelector(editComp); + backgroundSelector.getButton().setLayoutData( + new GridData(GridData.FILL_HORIZONTAL)); + backgroundSelector.addListener(new IPropertyChangeListener() { + + @Override + public void propertyChange(PropertyChangeEvent event) { + backgroundSelected(); + } + }); + new Label(editComp, SWT.NONE).setText("Font: "); + fontButton = new Button(editComp, SWT.PUSH); + fontButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + fontButton.setText("Configure Font"); + fontButton.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + fontSelected(); + } + + }); + performDefaults(); + styleSelected(); + return composite; + } + + protected void fontSelected() { + FontData data = new FontDialog(getShell()).open(); + if (data == null) { + return; + } + TableItem selection = table.getSelection()[0]; + AlertStyle style = (AlertStyle) selection.getData(); + StyleManager.setFont(style, data); + selection.setFont(StyleManager.getFont(getShell().getDisplay(), style)); + } + + protected void backgroundSelected() { + TableItem selection = table.getSelection()[0]; + selection.setBackground(new Color(getShell().getDisplay(), + backgroundSelector.getColorValue())); + AlertStyle style = (AlertStyle) selection.getData(); + style.setBackgroundColor(StyleManager.formatColor(backgroundSelector + .getColorValue())); + } + + protected void foregroundSelected() { + TableItem selection = table.getSelection()[0]; + selection.setForeground(new Color(getShell().getDisplay(), + foregroundSelector.getColorValue())); + AlertStyle style = (AlertStyle) selection.getData(); + style.setForegroundColor(StyleManager.formatColor(foregroundSelector + .getColorValue())); + } + + protected void filterSelected() { + TableItem selection = table.getSelection()[0]; + selection.setText(filterCombo.getItem(filterCombo.getSelectionIndex())); + AlertStyle style = (AlertStyle) selection.getData(); + style.setFilter(selection.getText().toLowerCase()); + } + + protected void newStyle() { + TableItem item = new TableItem(table, SWT.NONE); + item.setText("INFO"); + AlertStyle style = new AlertStyle(); + style.setFilter(item.getText().toLowerCase()); + item.setData(style); + table.select(table.indexOf(item)); + styleSelected(); + } + + @Override + public void dispose() { + preferenceFile.close(); + super.dispose(); + } + + protected void deleteStyle() { + table.getSelection()[0].dispose(); + styleSelected(); + } + + protected void styleSelected() { + int index = table.getSelectionIndex(); + if (index < 0) { + filterCombo.deselectAll(); + filterCombo.setEnabled(false); + foregroundSelector.setEnabled(false); + backgroundSelector.setEnabled(false); + fontButton.setEnabled(false); + return; + } + TableItem selection = table.getItem(index); + filterCombo.setEnabled(true); + foregroundSelector.setEnabled(true); + backgroundSelector.setEnabled(true); + fontButton.setEnabled(true); + + index = filterCombo.indexOf(selection.getText()); + filterCombo.select(index); + backgroundSelector.setColorValue(selection.getBackground().getRGB()); + foregroundSelector.setColorValue(selection.getForeground().getRGB()); + } + + @Override + protected void performDefaults() { + table.removeAll(); + for (AlertStyle style : preferenceFile.get().getStyles()) { + TableItem item = new TableItem(table, SWT.NONE); + item.setText(style.getFilter().toUpperCase()); + item.setBackground(StyleManager.parseColor(getShell().getDisplay(), + style.getBackgroundColor())); + item.setForeground(StyleManager.parseColor(getShell().getDisplay(), + style.getForegroundColor())); + item.setFont(StyleManager.getFont(getShell().getDisplay(), style)); + item.setData(new AlertStyle(style)); + } + super.performDefaults(); + } + + @Override + public boolean performOk() { + List styles = new ArrayList(); + for (TableItem item : table.getItems()) { + styles.add((AlertStyle) item.getData()); + } + StylePreferences newPrefs = new StylePreferences(); + newPrefs.setStyles(styles); + preferenceFile.write(newPrefs); + return super.performOk(); + } + + @Override + public void update(StylePreferences preferences) { + Display.getDefault().asyncExec(new Runnable() { + + @Override + public void run() { + if (!getControl().isDisposed()) { + performDefaults(); + } + } + }); + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/view/AlertConsoleViewer.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/view/AlertConsoleViewer.java new file mode 100644 index 0000000000..f6db062fe4 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/view/AlertConsoleViewer.java @@ -0,0 +1,160 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.ui.view; + +import java.io.IOException; + +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.MenuAdapter; +import org.eclipse.swt.events.MenuEvent; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.ui.console.ConsolePlugin; +import org.eclipse.ui.console.IHyperlink; +import org.eclipse.ui.console.IOConsole; +import org.eclipse.ui.console.IOConsoleOutputStream; +import org.eclipse.ui.console.TextConsoleViewer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.raytheon.uf.viz.alertview.Alert; +import com.raytheon.uf.viz.alertview.action.SaveToFileAction; + +/** + * + * Used for viewing the details of {@link Alert}s. Since most alerts are + * generated from logged errors this console is created so that links appear in + * stack traces when the view is used in eclipse. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 18, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class AlertConsoleViewer extends TextConsoleViewer { + + private static Logger logger = LoggerFactory.getLogger(AlertView.class); + + private AlertConsole console; + + private Alert alert; + + public AlertConsoleViewer(Composite parent) { + this(parent, new AlertConsole()); + } + + private AlertConsoleViewer(Composite parent, AlertConsole console) { + super(parent, console); + this.console = console; + console.setViewer(this); + initialize(); + } + + private void initialize() { + StyledText text = getTextWidget(); + text.setEditable(false); + Menu menu = new Menu(text); + text.setMenu(menu); + menu.addMenuListener(new MenuAdapter() { + + @Override + public void menuShown(MenuEvent e) { + populateContextMenu(getTextWidget().getMenu()); + } + + }); + } + + protected void populateContextMenu(Menu menu) { + for (MenuItem item : menu.getItems()) { + item.dispose(); + } + if (alert == null) { + return; + } + new ActionContributionItem(new SaveToFileAction(alert)).fill(menu, -1); + } + + public void setAlert(Alert alert) { + if (this.alert == alert) { + return; + } + this.alert = alert; + console.clearConsole(); + if (alert == null) { + return; + } + String details = alert.getDetails(); + if (details.isEmpty()) { + details = alert.getMessage(); + } + try (IOConsoleOutputStream os = console.newOutputStream()) { + os.write(details); + } catch (IOException e) { + logger.error("Unexpected IO exception writing to console.", e); + } + } + + protected void redraw() { + Display.getDefault().syncExec(new Runnable() { + + @Override + public void run() { + getTextWidget().redraw(); + } + + }); + } + + private static class AlertConsole extends IOConsole { + + private AlertConsoleViewer viewer; + + public AlertConsole() { + super("AlertViewConsole", "javaStackTraceConsole", null); + ConsolePlugin.getDefault().getConsoleManager() + .createPatternMatchListeners(this); + } + + public void setViewer(AlertConsoleViewer viewer) { + this.viewer = viewer; + } + + @Override + public void addHyperlink(IHyperlink hyperlink, int offset, int length) + throws BadLocationException { + super.addHyperlink(hyperlink, offset, length); + viewer.redraw(); + } + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/view/AlertTable.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/view/AlertTable.java new file mode 100644 index 0000000000..8e93696712 --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/view/AlertTable.java @@ -0,0 +1,456 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.ui.view; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MenuAdapter; +import org.eclipse.swt.events.MenuEvent; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseTrackAdapter; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.ui.progress.UIJob; + +import com.raytheon.uf.viz.alertview.Alert; +import com.raytheon.uf.viz.alertview.action.SaveToFileAction; +import com.raytheon.uf.viz.alertview.filter.AlertFilter; +import com.raytheon.uf.viz.alertview.style.StyleManager; +import com.raytheon.uf.viz.alertview.style.StyleManager.StyleListener; + +/** + * + * Table that displays {@link Alert}s. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 18, 2015  4474     bsteffen  Initial creation
+ * Jun 23, 2015  4474     njensen   Added removeAll() and getFilter()
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class AlertTable extends Composite implements StyleListener { + + public static final String COLUMN_TIME = "Time"; + + public static final String COLUMN_PRIORITY = "Priority"; + + public static final String COLUMN_ORIGIN = "Origin"; + + public static final String COLUMN_MESSAGE = "Message"; + + public static final String[] ALL_COLUMNS = { COLUMN_TIME, COLUMN_PRIORITY, + COLUMN_ORIGIN, COLUMN_MESSAGE }; + + private StyleManager styles = new StyleManager(); + + private BlockingQueue alertsToAdd = new LinkedBlockingQueue(); + + private Table alertTable; + + private AlertFilter filter; + + private int mergeRepeatInterval; + + /** + * When things are going terribly wrong and a gazillion alerts are coming in + * the UI will freeze if they aren't throttled a bit. This job tries to be + * reasonablish about how much CPU to suck updating the table. + */ + private Job addAlertJob = new UIJob("Updating AlertView") { + + @Override + public IStatus runInUIThread(IProgressMonitor monitor) { + if (AlertTable.this.isDisposed()) { + alertsToAdd.clear(); + return Status.OK_STATUS; + } + Alert next = alertsToAdd.poll(); + if (next != null) { + int processed = 0; + while (next != null) { + + addAlertInternal(next); + if (processed++ > 500) { + this.schedule(100); + break; + } + next = alertsToAdd.poll(); + } + packColumns(); + } + return Status.OK_STATUS; + } + }; + + public AlertTable(Composite parent, List columns) { + super(parent, SWT.NONE); + this.setLayout(new FillLayout()); + createAlertTable(); + rebuildColums(columns); + styles.addListener(this); + } + + protected void createAlertTable() { + alertTable = new Table(this, SWT.H_SCROLL | SWT.V_SCROLL + | SWT.FULL_SELECTION | SWT.MULTI); + alertTable.setHeaderVisible(true); + alertTable.setLinesVisible(true); + alertTable.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + alertSelected(); + } + + }); + alertTable.addMouseListener(new MouseAdapter() { + + @Override + public void mouseDoubleClick(MouseEvent e) { + alertDoubleClick(); + } + + }); + + alertTable.addMouseMoveListener(new MouseMoveListener() { + + @Override + public void mouseMove(MouseEvent e) { + alertTable.setToolTipText(null); + } + }); + + alertTable.addMouseTrackListener(new MouseTrackAdapter() { + + @Override + public void mouseHover(MouseEvent e) { + TableItem item = alertTable.getItem(new Point(e.x, e.y)); + if (item == null) { + alertTable.setToolTipText(null); + } else { + Alert alert = getAlert(item); + alertTable.setToolTipText(getToolTip(alert)); + } + } + }); + Menu menu = new Menu(alertTable); + alertTable.setMenu(menu); + menu.addMenuListener(new MenuAdapter() { + + @Override + public void menuShown(MenuEvent e) { + populateContextMenu(alertTable.getMenu()); + } + + }); + } + + public void addAlert(Alert alert) { + alertsToAdd.add(alert); + addAlertJob.schedule(); + } + + protected TableItem addAlertInternal(Alert alert) { + if (filter != null && !filter.filter(alert)) { + return null; + } + TableItem newItem = null; + for (int index = 0; index < alertTable.getItemCount(); index += 1) { + TableItem item = alertTable.getItem(index); + List alerts = getAlerts(item); + Alert sample = alerts.get(0); + if (alerts.contains(alert)) { + return item; + } else if (equalsEnough(sample, alert)) { + alerts.add(alert); + return item; + } else if (sample.getTime().before(alert.getTime())) { + newItem = new TableItem(alertTable, SWT.NONE, index); + break; + } + } + if (newItem == null) { + newItem = new TableItem(alertTable, SWT.NONE); + } + newItem.setData(new ArrayList(Arrays.asList(alert))); + newItem.setText(getText(alert)); + applyStyle(newItem); + alertTable.showItem(newItem); + return newItem; + } + + /** + * Used to determine if 2 messages are similar enough that they should not + * be displayed as separate items. + */ + protected boolean equalsEnough(Alert a1, Alert a2) { + if (a1.getMessage() == null) { + if (a2.getMessage() != null) { + return false; + } + } else if (!a1.getMessage().equals(a2.getMessage())) { + return false; + } + if (a1.getOrigin() == null) { + if (a2.getOrigin() != null) { + return false; + } + } else if (!a1.getOrigin().equals(a2.getOrigin())) { + return false; + } + if (a1.getDetails() == null) { + if (a2.getDetails() != null) { + return false; + } + } else if (!a1.getDetails().equals(a2.getDetails())) { + return false; + } + + long timeDiff = Math.abs(a2.getTime().getTime() + - a1.getTime().getTime()); + if (timeDiff > mergeRepeatInterval) { + return false; + } else { + return true; + } + } + + public void setMergeRepeatInterval(int mergeRepeatInterval) { + this.mergeRepeatInterval = mergeRepeatInterval; + } + + protected void applyStyle(TableItem item) { + Alert alert = getAlert(item); + item.setBackground(styles.getBackgroundColor(item.getDisplay(), alert)); + item.setForeground(styles.getForegroundColor(item.getDisplay(), alert)); + item.setFont(styles.getFont(item.getDisplay(), alert)); + } + + public void setFilter(AlertFilter filter) { + this.filter = filter; + for (TableItem item : alertTable.getSelection()) { + Alert alert = getAlert(item); + if (!filter.filter(alert)) { + item.dispose(); + } + } + for (TableItem item : alertTable.getItems()) { + Alert alert = getAlert(item); + if (!filter.filter(alert)) { + item.dispose(); + } + } + } + + protected AlertFilter getFilter() { + return this.filter; + } + + public void select(Alert alert) { + if (alertsToAdd.contains(alert)) { + TableItem item = addAlertInternal(alert); + alertTable.setSelection(alertTable.indexOf(item)); + alertSelected(); + return; + } + for (TableItem item : alertTable.getItems()) { + List alerts = getAlerts(item); + if (alerts.contains(alert)) { + alertTable.setSelection(alertTable.indexOf(item)); + alertSelected(); + return; + } + } + } + + public void packColumns() { + for (TableColumn column : alertTable.getColumns()) { + column.pack(); + } + } + + protected String[] getText(Alert alert) { + TableColumn[] columns = alertTable.getColumns(); + String[] text = new String[columns.length]; + for (int i = 0; i < columns.length; i += 1) { + if (columns[i].getText().equals(COLUMN_MESSAGE)) { + text[i] = alert.getMessage().split("\n")[0]; + } else if (columns[i].getText().equals(COLUMN_TIME)) { + text[i] = new SimpleDateFormat("hh:mm a").format(alert + .getTime()); + } else if (columns[i].getText().equals(COLUMN_PRIORITY)) { + text[i] = alert.getPriority().toString(); + } else if (columns[i].getText().equals(COLUMN_ORIGIN)) { + text[i] = alert.getOrigin(); + } else { + text[i] = "Unknown Field"; + } + } + return text; + } + + public void rebuildColums(List columns) { + for (TableColumn column : alertTable.getColumns()) { + column.dispose(); + } + for (String columnText : columns) { + TableColumn column = new TableColumn(alertTable, SWT.NONE); + column.setText(columnText); + } + for (TableItem item : alertTable.getItems()) { + item.setText(getText(getAlert(item))); + } + for (TableColumn column : alertTable.getColumns()) { + column.pack(); + } + } + + protected String getToolTip(Alert alert) { + StringBuilder toolTip = new StringBuilder(); + if (alert.getTime() != null) { + SimpleDateFormat sdf = new SimpleDateFormat( + "yyyy-MM-dd_HH:mm:ss.SSS"); + toolTip.append("Time: ").append(sdf.format(alert.getTime())) + .append("\n"); + } + if (alert.getPriority() != null) { + toolTip.append("Priority: ").append(alert.getPriority()) + .append("\n"); + } + if (toolTip.charAt(toolTip.length() - 1) == '\n') { + toolTip.deleteCharAt(toolTip.length() - 1); + } + return toolTip.toString(); + } + + protected void populateContextMenu(Menu menu) { + for (MenuItem item : menu.getItems()) { + item.dispose(); + } + Alert alert = getSingleSelection(); + if (alert != null) { + new ActionContributionItem(new SaveToFileAction(alert)).fill(menu, + -1); + } + } + + public Alert getSingleSelection() { + TableItem[] selection = alertTable.getSelection(); + if (selection == null || selection.length != 1) { + return null; + } else { + return getAlert(selection[0]); + } + } + + public List getMultiSelection() { + TableItem[] selection = alertTable.getSelection(); + if (selection == null || selection.length == 0) { + return Collections.emptyList(); + } + List result = new ArrayList(); + for (int i = 0; i < selection.length; i += 1) { + result.addAll(getAlerts(selection[i])); + } + return result; + } + + public Alert getAlert(TableItem item) { + return getAlerts(item).get(0); + } + + @SuppressWarnings("unchecked") + public List getAlerts(TableItem item) { + return (List) item.getData(); + } + + public void removeAll() { + alertTable.removeAll(); + } + + @Override + public void dispose() { + super.dispose(); + styles.close(); + } + + protected void alertSelected() { + // sub classes can override this easily + } + + protected void alertDoubleClick() { + // sub classes can override this easily + + } + + @Override + public void updateStyle() { + Display display = getDisplay(); + if (display.isDisposed()) { + return; + } + display.asyncExec(new Runnable() { + + @Override + public void run() { + if (alertTable.isDisposed()) { + return; + } + for (TableItem item : alertTable.getItems()) { + applyStyle(item); + } + } + + }); + + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/view/AlertView.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/view/AlertView.java new file mode 100644 index 0000000000..c9df26e73b --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/view/AlertView.java @@ -0,0 +1,245 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.ui.view; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.part.ViewPart; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.raytheon.uf.viz.alertview.Alert; +import com.raytheon.uf.viz.alertview.AlertDestination; +import com.raytheon.uf.viz.alertview.AlertStore; +import com.raytheon.uf.viz.alertview.filter.AlertFilter; +import com.raytheon.uf.viz.alertview.filter.FilterManager; +import com.raytheon.uf.viz.alertview.prefs.AlertViewPreferences; +import com.raytheon.uf.viz.alertview.prefs.AlertViewPreferences.FilterMenu; +import com.raytheon.uf.viz.alertview.prefs.PreferenceFile; +import com.raytheon.uf.viz.alertview.ui.prefs.OpenPreferencesAction; + +/** + * + * {@link IViewPart} for displaying {@link Alert}s. View is essentially just a + * combination of an {@link AlertTable} and an {@link AlertConsoleViewer}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 18, 2015  4474     bsteffen  Initial creation
+ * Jun 22, 2015  4474     njensen   Fix bugs
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class AlertView extends ViewPart implements AlertDestination, + PreferenceFile.Listener { + + private static Logger logger = LoggerFactory.getLogger(AlertView.class); + + private FilterManager filterManager = new FilterManager(); + + private ServiceRegistration destinationRegistration; + + private PreferenceFile preferencesFile; + + private SashForm sashForm; + + private AlertTable alertTable; + + private AlertConsoleViewer detailsConsoleViewer; + + @Override + public void createPartControl(Composite parent) { + preferencesFile = AlertViewPreferences.load(this); + AlertViewPreferences preferences = preferencesFile.get(); + + sashForm = new SashForm(parent, SWT.NONE); + sashForm.setOrientation(SWT.VERTICAL); + + alertTable = new AlertTable(sashForm, preferences.getColumns()) { + + @Override + protected void alertSelected() { + detailsConsoleViewer.setAlert(alertTable.getSingleSelection()); + } + + @Override + protected void alertDoubleClick() { + if (sashForm.getMaximizedControl() == alertTable) { + sashForm.setMaximizedControl(null); + } else { + sashForm.setMaximizedControl(alertTable); + } + } + + }; + + detailsConsoleViewer = new AlertConsoleViewer(sashForm); + + sashForm.setMaximizedControl(alertTable); + + alertTable.setMergeRepeatInterval(preferences.getMergeRepeatInterval()); + + populateFilterMenu(); + destinationRegistration = getBundleContext().registerService( + AlertDestination.class, this, null); + } + + protected void populateFilterMenu() { + /* + * TODO the menu button creates excessive unusable space in CAVE because + * there are no toolbar items and the tabs are so small. + */ + IMenuManager menuManager = getViewSite().getActionBars() + .getMenuManager(); + menuManager.removeAll(); + MenuManager filterMenu = new MenuManager("Show", null); + menuManager.add(filterMenu); + AlertViewPreferences prefs = preferencesFile.get(); + for (FilterMenu menuItem : prefs.getFilterMenu()) { + Action action = new ShowFilteredAction(menuItem); + if (prefs.getActiveFilter().equals(menuItem.getFilter())) { + action.setChecked(true); + action.run(); + } + filterMenu.add(action); + } + menuManager.add(new OpenPreferencesAction()); + } + + private void loadAlerts() { + BundleContext context = getBundleContext(); + ServiceReference ref = context + .getServiceReference(AlertStore.class); + if (ref != null) { + AlertStore store = context.getService(ref); + for (Alert alert : store.getAlerts()) { + alertTable.addAlert(alert); + } + context.ungetService(ref); + } + alertTable.packColumns(); + } + + @Override + public void setFocus() { + alertTable.setFocus(); + } + + @Override + public void dispose() { + destinationRegistration.unregister(); + preferencesFile.close(); + super.dispose(); + } + + @Override + public void handleAlert(Alert alert) { + alertTable.addAlert(alert); + } + + @Override + public void update(final AlertViewPreferences preferences) { + Display display = Display.getCurrent(); + if (display.isDisposed()) { + return; + } + display.asyncExec(new Runnable() { + @Override + public void run() { + if (alertTable.isDisposed()) { + return; + } + alertTable.setMergeRepeatInterval(preferences + .getMergeRepeatInterval()); + alertTable.rebuildColums(preferences.getColumns()); + populateFilterMenu(); + } + }); + } + + public static void show(IWorkbenchWindow window, Alert alert) { + IWorkbenchPage activePage = window.getActivePage(); + + try { + AlertView view = (AlertView) activePage.showView(AlertView.class + .getName()); + if (alert != null) { + view.handleAlert(alert); + view.alertTable.select(alert); + view.sashForm.setMaximizedControl(null); + } + } catch (PartInitException e) { + logger.error("Cannot open AlertView", e); + } + } + + protected static BundleContext getBundleContext() { + return FrameworkUtil.getBundle(AlertView.class).getBundleContext(); + } + + private class ShowFilteredAction extends Action { + + private final String filterName; + + private final AlertFilter filter; + + public ShowFilteredAction(FilterMenu menuItem) { + super(menuItem.getText(), IAction.AS_RADIO_BUTTON); + this.filterName = menuItem.getFilter(); + this.filter = filterManager.getFilter(filterName); + } + + @Override + public void run() { + if (!this.filter.equals(alertTable.getFilter())) { + alertTable.setFilter(filter); + detailsConsoleViewer.setAlert(alertTable.getSingleSelection()); + loadAlerts(); + AlertViewPreferences prefs = preferencesFile.get(); + if (!filterName.equals(prefs.getActiveFilter())) { + prefs = new AlertViewPreferences(prefs); + prefs.setActiveFilter(filterName); + preferencesFile.write(prefs); + } + } + } + } +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/view/AlertViewAutoOpen.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/view/AlertViewAutoOpen.java new file mode 100644 index 0000000000..193de1a4cd --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/view/AlertViewAutoOpen.java @@ -0,0 +1,81 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.ui.view; + +import org.eclipse.swt.widgets.Display; + +import com.raytheon.uf.viz.alertview.Alert; +import com.raytheon.uf.viz.alertview.AlertDestination; +import com.raytheon.uf.viz.alertview.filter.AlertFilter; +import com.raytheon.uf.viz.alertview.filter.FilterManager; +import com.raytheon.uf.viz.alertview.prefs.AlertViewPreferences; +import com.raytheon.uf.viz.alertview.prefs.PreferenceFile; + +/** + * Automatically open {@link AlertView} whenever new {@link Alert}s arrive that + * have a high enough priority. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 25, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class AlertViewAutoOpen implements AlertDestination, + PreferenceFile.Listener { + + private final PreferenceFile prefsFile; + + private final FilterManager filters = new FilterManager(); + + private AlertFilter filter; + + public AlertViewAutoOpen() { + prefsFile = AlertViewPreferences.load(this); + filter = filters.getFilter(prefsFile.get().getOpenFilter()); + } + + @Override + public void update(AlertViewPreferences preference) { + filter = filters.getFilter(prefsFile.get().getOpenFilter()); + + } + + @Override + public void handleAlert(final Alert alert) { + if (filter.filter(alert)) { + Display.getDefault().asyncExec(new Runnable() { + + @Override + public void run() { + OpenAlertViewHandler.openInAlertView(alert); + } + }); + } + } + +} diff --git a/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/view/OpenAlertViewHandler.java b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/view/OpenAlertViewHandler.java new file mode 100644 index 0000000000..4183fe4e8c --- /dev/null +++ b/cave/com.raytheon.uf.viz.alertview/src/com/raytheon/uf/viz/alertview/ui/view/OpenAlertViewHandler.java @@ -0,0 +1,113 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.alertview.ui.view; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.ui.IWindowListener; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +import com.raytheon.uf.viz.alertview.Alert; + +/** + * + * {@link IHandler} that opens an {@link AlertView}. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer  Description
+ * ------------- -------- --------- --------------------------
+ * Jun 18, 2015  4474     bsteffen  Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class OpenAlertViewHandler extends AbstractHandler { + + private final Alert alert; + + public OpenAlertViewHandler() { + this.alert = null; + } + + public OpenAlertViewHandler(Alert alert) { + this.alert = alert; + } + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + openInAlertView(alert); + return null; + } + + public static void openInAlertView(Alert alert) { + IWorkbench workbench = PlatformUI.getWorkbench(); + IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); + if (workbench.isStarting()) { + workbench.addWindowListener(new ShowAlertViewWindowListener(alert)); + } else if (window != null) { + AlertView.show(window, alert); + } + } + + /** + * If the user clicks on the alert popup while the workbench is starting + * then this listener will be used to wait until the workbench window is + * opened and then display the alert. + */ + private static class ShowAlertViewWindowListener implements IWindowListener { + + private final Alert alert; + + public ShowAlertViewWindowListener(Alert alert) { + this.alert = alert; + } + + @Override + public void windowOpened(IWorkbenchWindow window) { + AlertView.show(window, alert); + window.getWorkbench().removeWindowListener(this); + } + + @Override + public void windowDeactivated(IWorkbenchWindow window) { + /* Unused method required by interface. */ + } + + @Override + public void windowClosed(IWorkbenchWindow window) { + /* Unused method required by interface. */ + } + + @Override + public void windowActivated(IWorkbenchWindow window) { + /* Unused method required by interface. */ + } + } + +} diff --git a/cave/com.raytheon.uf.viz.alertviz.ui/src/com/raytheon/uf/viz/alertviz/ui/dialogs/AlertPopupMessageDlg.java b/cave/com.raytheon.uf.viz.alertviz.ui/src/com/raytheon/uf/viz/alertviz/ui/dialogs/AlertPopupMessageDlg.java index a54bf887fa..0d4cac05f4 100644 --- a/cave/com.raytheon.uf.viz.alertviz.ui/src/com/raytheon/uf/viz/alertviz/ui/dialogs/AlertPopupMessageDlg.java +++ b/cave/com.raytheon.uf.viz.alertviz.ui/src/com/raytheon/uf/viz/alertviz/ui/dialogs/AlertPopupMessageDlg.java @@ -33,6 +33,8 @@ import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.Rectangle; @@ -68,6 +70,7 @@ import com.raytheon.uf.viz.alertviz.config.AlertMetadata; * 13 Jan 2011 7375 cjeanbap Commented out shell.setVisible(...) in * acknowledgeLastMessage(). * 20 Apr 2015 4311 lvenable Fixed text field to accept really long text strings. + * 29 Jun 2015 4311 randerso Reworking AlertViz dialogs to be resizable. * * * @@ -77,6 +80,20 @@ import com.raytheon.uf.viz.alertviz.config.AlertMetadata; */ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener, MouseListener { + private static final int MAX_INITIAL_LINES = 5; + + private static final int WIDTH_IN_CHARS = 135; + + private static final double PERCENT_OF_SCREEN_WIDTH = 0.75; + + private static final int NUM_LIST_ITEMS = 10; + + /* + * Adjustment for SWT bug where shell.getSize() returns incorrect value when + * SWT.ON_TOP style is used. + */ + private static final int SWT_BUG_FACTOR = 6; + /** * Dialog shell. */ @@ -87,21 +104,11 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener, */ private Display display; - /** - * Font used for the controls. - */ - private Font controlFont; - /** * Font used for labels */ private Font labelFont; - /** - * Font used for the double click label. - */ - private Font dblClickLblFont; - /** * Message text field. */ @@ -268,7 +275,9 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener, */ private boolean initialized = false; - private final AlertVisualization av; + private boolean first; + + private int controlWidth; /** * Constructor. @@ -285,13 +294,12 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener, * Color to be displayed at startup. */ public AlertPopupMessageDlg(Shell parent, StatusMessage statMsg, - boolean expanded, Listener listener, RGB startUpRGB, - AlertVisualization av) { + boolean expanded, Listener listener, RGB startUpRGB) { super(parent, 0); hideListener = listener; statMsgArray.add(statMsg); this.expanded = expanded; - this.av = av; + this.first = true; initShell(startUpRGB); } @@ -303,15 +311,14 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener, Shell parent = getParent(); display = parent.getDisplay(); - shell = new Shell(parent, SWT.ON_TOP); + shell = new Shell(parent, SWT.ON_TOP | SWT.RESIZE); shell.setText("Alert Visualization Popup Message Dialog"); - Rectangle prvLocation = av.getAlertPopupMsgPrvLocation(); - if (prvLocation != null) { - shell.getBounds().add(prvLocation); - } // Create the main layout for the shell. GridLayout mainLayout = new GridLayout(1, false); + mainLayout.marginWidth = 0; + mainLayout.marginHeight = 0; + mainLayout.verticalSpacing = 0; shell.setLayout(mainLayout); // initialize data, fonts, and arrays @@ -345,12 +352,13 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener, * @return True/False/null. */ public Object open() { - shell.pack(); setInitialDialogLocation(); initialized = true; + showHideLog(); + shell.open(); while (!shell.isDisposed()) { @@ -361,9 +369,7 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener, initialized = false; - controlFont.dispose(); labelFont.dispose(); - dblClickLblFont.dispose(); return null; } @@ -372,10 +378,26 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener, * Initialize font data */ private void initalizeData() { - controlFont = new Font(shell.getDisplay(), "Monospace", 10, SWT.NORMAL); - labelFont = new Font(shell.getDisplay(), "Monospace", 14, SWT.BOLD); - dblClickLblFont = new Font(shell.getDisplay(), "Monospace", 10, - SWT.BOLD); + FontData fontData = display.getSystemFont().getFontData()[0]; + labelFont = new Font(shell.getDisplay(), fontData.getName(), + (int) (fontData.getHeight() * 1.4), SWT.BOLD); + + /* + * compute preferred height to display entire message. + */ + int screenWidth = display.getPrimaryMonitor().getBounds().width; + + /* + * compute width of controls as the lesser of WIDTH_IN_CHARS or + * PERCENT_OF_SCREEN_WIDTH + */ + GC gc = new GC(display); + gc.setFont(display.getSystemFont()); + int charWidth = gc.getFontMetrics().getAverageCharWidth(); + gc.dispose(); + + controlWidth = Math.min(charWidth * WIDTH_IN_CHARS, + (int) (screenWidth * PERCENT_OF_SCREEN_WIDTH)); } /** @@ -399,7 +421,7 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener, private void createTitleBarLabel() { GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); gd.horizontalSpan = 3; - moveLabel = new Label(shell, SWT.CENTER | SWT.BORDER); + moveLabel = new Label(shell, SWT.CENTER); moveLabel.setText("Alert Visualization Popup Message Dialog"); moveLabel.setLayoutData(gd); moveLabel.setFont(labelFont); @@ -415,97 +437,90 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener, * Create the labels at the top of the dialog. */ private void createTopLabels() { - GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); topLabelComp = new Composite(shell, SWT.NONE); GridLayout gl = new GridLayout(3, false); gl.horizontalSpacing = 35; topLabelComp.setLayout(gl); + GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); topLabelComp.setLayoutData(gd); topLabelComp.setBackground(display.getSystemColor(SWT.COLOR_RED)); + sourceLbl = new Label(topLabelComp, SWT.BORDER); + sourceLbl.setText(sourceStr + statMsgArray.get(0).getSourceKey()); gd = new GridData(200, SWT.DEFAULT); gd.verticalIndent = 10; - sourceLbl = new Label(topLabelComp, SWT.NONE); - sourceLbl.setText(sourceStr + statMsgArray.get(0).getSourceKey()); sourceLbl.setLayoutData(gd); - gd = new GridData(200, SWT.DEFAULT); - gd.verticalIndent = 10; - priorityLbl = new Label(topLabelComp, SWT.NONE); + priorityLbl = new Label(topLabelComp, SWT.BORDER); priorityLbl.setText(priorityStr + statMsgArray.get(0).getPriority().ordinal()); - priorityLbl.setLayoutData(gd); - gd = new GridData(200, SWT.DEFAULT); gd.verticalIndent = 10; - categoryLbl = new Label(topLabelComp, SWT.NONE); - categoryLbl.setText(categoryStr + statMsgArray.get(0).getCategory()); - categoryLbl.setLayoutData(gd); + priorityLbl.setLayoutData(gd); - /* - * If the expanded flag is false then hide the labels that display the - * Category/Source/Priority information. - */ - if (expanded == false) { - // Hide the message labels - ((GridData) topLabelComp.getLayoutData()).exclude = true; - topLabelComp.setVisible(false); - shell.layout(); - shell.pack(); - } + categoryLbl = new Label(topLabelComp, SWT.BORDER); + categoryLbl.setText(categoryStr + statMsgArray.get(0).getCategory()); + gd = new GridData(200, SWT.DEFAULT); + gd.verticalIndent = 10; + categoryLbl.setLayoutData(gd); } /** * Create the message text control. */ private void createMessageControl() { - GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); messageComp = new Composite(shell, SWT.NONE); messageComp.setLayout(new GridLayout(1, false)); messageComp.setLayoutData(gd); messageComp.setBackground(display.getSystemColor(SWT.COLOR_RED)); - gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); - gd.heightHint = 20; - gd.widthHint = 920; messageTF = new Text(messageComp, SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL); - messageTF.setLayoutData(gd); - messageTF.setText(statMsgArray.get(0).getMessage()); messageTF.setEditable(false); + messageTF.setText(statMsgArray.get(0).getMessage()); + + int preferredHeight = messageTF.computeSize(controlWidth, SWT.DEFAULT).y; + + /* + * compute size to display only max initial lines + */ + int height = messageTF.getLineHeight() * MAX_INITIAL_LINES; + Rectangle initialSize = messageTF.computeTrim(0, 0, controlWidth, + height); + + gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.widthHint = initialSize.width; + + gd.heightHint = Math.min(preferredHeight, initialSize.height); + gd.minimumHeight = gd.heightHint; + messageTF.setLayoutData(gd); } /** * Create the action buttons for the dialog. */ private void createActionButtons() { - GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); actionComp = new Composite(shell, SWT.NONE); actionComp.setLayout(new GridLayout(7, false)); + GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); actionComp.setLayoutData(gd); actionComp.setBackground(display.getSystemColor(SWT.COLOR_RED)); - gd = new GridData(200, SWT.DEFAULT); - timeLbl = new Label(actionComp, SWT.NONE); + timeLbl = new Label(actionComp, SWT.BORDER); timeLbl.setText(dateFormat.format(statMsgArray.get(0).getEventTime())); + gd = new GridData(200, SWT.DEFAULT); timeLbl.setLayoutData(gd); - gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); fillerLbl = new Label(actionComp, SWT.NONE); fillerLbl.setText(""); fillerLbl.setBackground(display.getSystemColor(SWT.COLOR_RED)); + gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); fillerLbl.setLayoutData(gd); - gd = new GridData(100, SWT.DEFAULT); hideShowLogBtn = new Button(actionComp, SWT.PUSH); - hideShowLogBtn.setLayoutData(gd); - - if (expanded == true) { - hideShowLogBtn.setText("Hide Log"); - } else { - hideShowLogBtn.setText("Show Log"); - } - + hideShowLogBtn.setLayoutData(new GridData()); + hideShowLogBtn.setText("Hide Log"); hideShowLogBtn.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { @@ -547,90 +562,69 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener, hideDialogBtn.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { - Rectangle prevLocation = Display.getCurrent().getBounds(); - av.setAlertPopupMsgPrvLocation(prevLocation); shell.setVisible(false); } }); - - /* - * If the expanded flag is false then hide the Acknowledge Selected - * button. - */ - if (expanded == false) { - // Hide the Acknowledge Selected button - ((GridData) ackSelectedBtn.getLayoutData()).exclude = true; - ackSelectedBtn.setVisible(false); - actionComp.layout(); - actionComp.pack(); - } } /** * Create the message log list control. */ private void createMessageLogControl() { - GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); logComp = new Composite(shell, SWT.NONE); logComp.setLayout(new GridLayout(1, false)); + GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); logComp.setLayoutData(gd); gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); Label dblClickLBl = new Label(logComp, SWT.BORDER | SWT.CENTER); dblClickLBl .setText("Double-click message to display more information:"); - dblClickLBl.setFont(dblClickLblFont); + dblClickLBl.setFont(labelFont); dblClickLBl.setForeground(display.getSystemColor(SWT.COLOR_DARK_BLUE)); dblClickLBl.setLayoutData(gd); - gd = new GridData(SWT.FILL, SWT.FILL, true, true); - gd.widthHint = 900; - gd.heightHint = 250; msgLogList = new List(logComp, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); - msgLogList.setFont(controlFont); + gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + Rectangle size = msgLogList.computeTrim(0, 0, controlWidth, + msgLogList.getItemHeight() * NUM_LIST_ITEMS); + gd.widthHint = size.width; + gd.heightHint = size.height; + gd.heightHint = (msgLogList.getItemHeight() * 10) + + (msgLogList.getBorderWidth() * 2); msgLogList.setLayoutData(gd); msgLogList.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { showSelectedListData(); } - }); - detailsComp = new SimpleDetailsComp(logComp, SWT.NONE); - - msgLogList.addMouseListener(new MouseListener() { @Override - public void mouseDoubleClick(MouseEvent e) { - - if (detailsComp.isVisible() == false) { + public void widgetDefaultSelected(SelectionEvent e) { + int delta = 0; + if (detailsComp.isVisible()) { + ((GridData) detailsComp.getLayoutData()).exclude = true; + detailsComp.setVisible(false); + delta -= detailsComp.getSize().y; + } else { int idx = msgLogList.getSelectionIndex(); if (idx < 0) { return; } StatusMessage sm = statMsgArray.get(idx); detailsComp.displayDetails(sm); + ((GridData) detailsComp.getLayoutData()).exclude = false; detailsComp.setVisible(true); - } else { - detailsComp.setVisible(false); + delta += detailsComp.getSize().y; } - } - @Override - public void mouseDown(MouseEvent e) { + adjustHeight(delta); } - - @Override - public void mouseUp(MouseEvent e) { - } - }); - if (expanded == false) { - ((GridData) logComp.getLayoutData()).exclude = true; - logComp.setVisible(false); - shell.layout(); - shell.pack(); - } + detailsComp = new SimpleDetailsComp(shell, SWT.NONE); + gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + detailsComp.setLayoutData(gd); msgLogList.add(getFormattedMessage(statMsgArray.get(0))); msgLogList.select(0); @@ -641,46 +635,59 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener, * Show/Hide the message log list. */ private void showHideLog() { + int delta = 0; if (expanded == true) { // Show the message labels ((GridData) topLabelComp.getLayoutData()).exclude = false; topLabelComp.setVisible(true); - shell.layout(); - shell.pack(); + delta += topLabelComp.getSize().y; // Show the Acknowledge Selected button ((GridData) ackSelectedBtn.getLayoutData()).exclude = false; ackSelectedBtn.setVisible(true); - actionComp.layout(); - actionComp.pack(); + hideShowLogBtn.setText("Hide Log"); // Show the message log ((GridData) logComp.getLayoutData()).exclude = false; logComp.setVisible(true); - shell.layout(); - shell.pack(); - hideShowLogBtn.setText("Hide Log"); + delta += logComp.getSize().y; } else { // Hide the message labels ((GridData) topLabelComp.getLayoutData()).exclude = true; topLabelComp.setVisible(false); - shell.layout(); - shell.pack(); + delta -= topLabelComp.getSize().y; // Hide the Acknowledge Selected button ((GridData) ackSelectedBtn.getLayoutData()).exclude = true; ackSelectedBtn.setVisible(false); - actionComp.layout(); - actionComp.pack(); + hideShowLogBtn.setText("Show Log"); // Hide the message log - detailsComp.setVisible(false); + if (this.first || detailsComp.isVisible()) { + ((GridData) detailsComp.getLayoutData()).exclude = true; + detailsComp.setVisible(false); + delta -= detailsComp.getSize().y; + this.first = false; + } + ((GridData) logComp.getLayoutData()).exclude = true; logComp.setVisible(false); - shell.layout(); - shell.pack(); - hideShowLogBtn.setText("Show Log"); + delta -= logComp.getSize().y; } + actionComp.layout(); + + adjustHeight(delta); + } + + private void adjustHeight(int delta) { + Point minSize = shell.getMinimumSize(); + minSize.y += delta; + shell.setMinimumSize(minSize); + + Point size = shell.getSize(); + size.x += SWT_BUG_FACTOR; + size.y += delta + SWT_BUG_FACTOR; + shell.setSize(size); } /** @@ -701,10 +708,19 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener, sourceLbl.setText(sourceStr + sm.getSourceKey()); timeLbl.setText(dateFormat.format(sm.getEventTime())); messageTF.setText(sm.getMessage()); + int desiredHeight = Math.min(MAX_INITIAL_LINES, + messageTF.getLineCount()) + * messageTF.getLineHeight(); + Rectangle clientArea = messageTF.getClientArea(); + if (clientArea.height < desiredHeight) { + Rectangle trim = messageTF.computeTrim(clientArea.x, clientArea.y, + clientArea.width, desiredHeight); + Point oldSize = messageTF.getSize(); + messageTF.setSize(oldSize.x, trim.height); + adjustHeight(trim.height - oldSize.y); + } detailsComp.displayDetails(sm); - - this.shell.pack(); } /** @@ -747,7 +763,7 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener, } // Check if a message is not selected. - if (currentIndex < 0 || !expanded) { + if ((currentIndex < 0) || !expanded) { if (msgLogList.getItemCount() > 0) { msgLogList.select(0); showSelectedListData(); @@ -759,7 +775,7 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener, // Check if the current index will go outside the array // (it should never do this but check anyway...) - if (currentIndex > 0 && currentIndex == statMsgArray.size()) { + if ((currentIndex > 0) && (currentIndex == statMsgArray.size())) { msgLogList.select(0); showSelectedListData(); return; @@ -877,6 +893,8 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener, messageComp.setBackground(bgColor); actionComp.setBackground(bgColor); fillerLbl.setBackground(bgColor); + logComp.setBackground(bgColor); + detailsComp.setBackground(bgColor); } /** @@ -890,18 +908,18 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener, return; } - boolean expandedForPromp = false; + boolean expandedForPrompt = false; if (!expanded) { - expandedForPromp = expanded = true; + expandedForPrompt = expanded = true; + showHideLog(); } - showHideLog(); if (confirmPrompt) { ConfirmationDlg cd = new ConfirmationDlg(shell, "Are you sure you want to acknowledge all popup messages?", SWT.ICON_QUESTION); - if (msgLogList != null && !msgLogList.isDisposed()) { + if ((msgLogList != null) && !msgLogList.isDisposed()) { Rectangle logBounds = msgLogList.getBounds(); Point logDisplayOrigin = msgLogList.toDisplay(0, 0); logBounds.x = logDisplayOrigin.x; @@ -912,7 +930,7 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener, result = cd.open(); if (result != SWT.YES) { - if (result == SWT.CANCEL && expandedForPromp) { + if ((result == SWT.CANCEL) && expandedForPrompt) { expanded = false; showHideLog(); } @@ -951,17 +969,18 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener, private void setInitialDialogLocation() { if (dialogXY == null) { + Point minSize = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT); + shell.setMinimumSize(minSize); int screenHeight = display.getBounds().height; int screenWidth = display.getPrimaryMonitor().getBounds().width; - int newX = screenWidth / 2 - - (shell.getChildren())[0].getBounds().width / 2; - int newY = (screenHeight / 2 - (shell.getChildren())[0].getBounds().height / 2) - 200; + Point size = minSize; + shell.setSize(size); - shell.setLocation(newX, newY); - - dialogXY = new Point(newX, newY); + dialogXY = new Point((screenWidth - size.x) / 2, + (screenHeight - size.y) / 4); + shell.setLocation(dialogXY); } else { shell.setLocation(dialogXY); } @@ -997,7 +1016,7 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener, * @return True if open, false if not. */ public boolean dialogIsOpen() { - return (shell != null && !shell.isDisposed() && shell.isVisible()); + return ((shell != null) && !shell.isDisposed() && shell.isVisible()); } /** @@ -1042,7 +1061,7 @@ public class AlertPopupMessageDlg extends Dialog implements MouseMoveListener, */ @Override public void mouseMove(MouseEvent e) { - if (origin != null && moveDialog == true) { + if ((origin != null) && (moveDialog == true)) { // Move the dialog. dialogLoc = display.map(shell, null, e.x, e.y); dialogXY.x = dialogLoc.x - origin.x; diff --git a/cave/com.raytheon.uf.viz.alertviz.ui/src/com/raytheon/uf/viz/alertviz/ui/dialogs/AlertVisualization.java b/cave/com.raytheon.uf.viz.alertviz.ui/src/com/raytheon/uf/viz/alertviz/ui/dialogs/AlertVisualization.java index ac9ecff405..1e7246af99 100644 --- a/cave/com.raytheon.uf.viz.alertviz.ui/src/com/raytheon/uf/viz/alertviz/ui/dialogs/AlertVisualization.java +++ b/cave/com.raytheon.uf.viz.alertviz.ui/src/com/raytheon/uf/viz/alertviz/ui/dialogs/AlertVisualization.java @@ -95,6 +95,7 @@ import com.raytheon.uf.viz.core.VizApp; * then set the icon to the default image. * 18 Mar 2015 4234 njensen Remove reference to non-working python * 03 Jun 2015 4473 njensen Updated for new AlertvizJob API + * 29 Jun 2015 4311 randerso Reworking AlertViz dialogs to be resizable. * * * @@ -377,8 +378,8 @@ public class AlertVisualization implements ITimerAction, IAudioAction, @Override public void widgetSelected(SelectionEvent e) { - if (alertPopupDlg != null - && alertPopupDlg.getNumberOfMessages() > 0) { + if ((alertPopupDlg != null) + && (alertPopupDlg.getNumberOfMessages() > 0)) { cancelTimer(); openAlertPopupDialog(); } @@ -437,20 +438,15 @@ public class AlertVisualization implements ITimerAction, IAudioAction, MenuItem viewLogMI = new MenuItem(trayItemMenu, SWT.NONE); viewLogMI.setText("System Log..."); viewLogMI.addSelectionListener(new SelectionAdapter() { - boolean open = false; - SimpleLogViewer slv = null; @Override public void widgetSelected(SelectionEvent event) { - if (open) { - open = slv.focus(); // Do Nothing! It's open - } else { - open = true; + if ((slv == null) || slv.isDisposed()) { slv = new SimpleLogViewer(shell); - slv.setText("System Log"); slv.open(); - open = false; + } else { + slv.bringToTop(); } } }); @@ -597,7 +593,7 @@ public class AlertVisualization implements ITimerAction, IAudioAction, * Show the Alert Visualization Configuration dialog. */ private void showConfigDialog() { - if (configDlg != null && !configDlg.isDisposed()) { + if ((configDlg != null) && !configDlg.isDisposed()) { configDlg.close(); } configDlg = new AlertVisConfigDlg(shell, alertMessageDlg, configData, @@ -640,7 +636,7 @@ public class AlertVisualization implements ITimerAction, IAudioAction, .hasMissing(statMsg))) { Source source = configData.lookupSource("GDN_ADMIN"); RGB backgroundRBG = null; - if (source == null || source.getConfigurationItem() == null) { + if ((source == null) || (source.getConfigurationItem() == null)) { backgroundRBG = ColorUtil.getColorValue("COLOR_YELLOW"); } else { AlertMetadata am = source.getConfigurationItem().lookup( @@ -663,7 +659,7 @@ public class AlertVisualization implements ITimerAction, IAudioAction, } } else { if (cat.getCategoryName().equals(Constants.MONITOR) - || amd.isText() == true) { + || (amd.isText() == true)) { alertMessageDlg.messageHandler(statMsg, amd, cat, gConfig); } @@ -689,8 +685,8 @@ public class AlertVisualization implements ITimerAction, IAudioAction, audioFile = getFullAudioFilePath(audioFile); } else { audioFile = statMsg.getAudioFile(); - if (audioFile != null - && (audioFile.trim().length() == 0 || audioFile + if ((audioFile != null) + && ((audioFile.trim().length() == 0) || audioFile .equals("NONE"))) { audioFile = null; } @@ -703,10 +699,9 @@ public class AlertVisualization implements ITimerAction, IAudioAction, // Pop-up message if (amd.isPopup() == true) { - if (alertPopupDlg == null || alertPopupDlg.isDisposed() == true) { + if ((alertPopupDlg == null) || (alertPopupDlg.isDisposed() == true)) { alertPopupDlg = new AlertPopupMessageDlg(shell, statMsg, - gConfig.isExpandedPopup(), this, amd.getBackground(), - this); + gConfig.isExpandedPopup(), this, amd.getBackground()); } else { alertPopupDlg.addNewMessage(statMsg, amd); } @@ -739,7 +734,7 @@ public class AlertVisualization implements ITimerAction, IAudioAction, if (!file.exists()) { file = PathManagerFactory.getPathManager().getStaticFile( "alertVizAudio/" + file.getName()); - if (file == null || !file.exists()) { + if ((file == null) || !file.exists()) { filename = null; } else { filename = file.getPath(); @@ -752,7 +747,7 @@ public class AlertVisualization implements ITimerAction, IAudioAction, * Opens the alert pop-up dialog */ public void openAlertPopupDialog() { - if (alertPopupDlg != null && alertPopupDlg.dialogIsOpen() == true) { + if ((alertPopupDlg != null) && (alertPopupDlg.dialogIsOpen() == true)) { alertPopupDlg.showDialog(true); } else { alertPopupDlg.open(); @@ -849,7 +844,7 @@ public class AlertVisualization implements ITimerAction, IAudioAction, configData = ConfigurationManager.getInstance() .getCurrentConfiguration(); configContext = ConfigurationManager.getInstance().getCurrentContext(); - if (alertMessageDlg != null && showAlertDialogMI != null) { + if ((alertMessageDlg != null) && (showAlertDialogMI != null)) { alertMessageDlg.setConfigData(configData); if (configData.isMonitorLayoutChanged(prevConfigFile)) { if (alertMessageDlg.reLayout()) { @@ -864,21 +859,6 @@ public class AlertVisualization implements ITimerAction, IAudioAction, // } } - /** - * Set the Alert Popup Message previous location. - */ - public void setAlertPopupMsgPrvLocation(Rectangle prevLocation) { - this.prevLocation = prevLocation; - } - - /** - * Get the Alert Popup Message to restore the window to its previous - * location. - */ - public Rectangle getAlertPopupMsgPrvLocation() { - return this.prevLocation; - } - /** * Get the number of text control composites. * diff --git a/cave/com.raytheon.uf.viz.alertviz.ui/src/com/raytheon/uf/viz/alertviz/ui/dialogs/SimpleDetailsComp.java b/cave/com.raytheon.uf.viz.alertviz.ui/src/com/raytheon/uf/viz/alertviz/ui/dialogs/SimpleDetailsComp.java index 13d2637745..a02369e79a 100644 --- a/cave/com.raytheon.uf.viz.alertviz.ui/src/com/raytheon/uf/viz/alertviz/ui/dialogs/SimpleDetailsComp.java +++ b/cave/com.raytheon.uf.viz.alertviz.ui/src/com/raytheon/uf/viz/alertviz/ui/dialogs/SimpleDetailsComp.java @@ -29,7 +29,6 @@ import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; -import org.eclipse.swt.widgets.Shell; import com.raytheon.uf.common.message.StatusMessage; @@ -40,7 +39,8 @@ import com.raytheon.uf.common.message.StatusMessage; * SOFTWARE HISTORY * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Oct 9, 2008 chammack Initial creation + * Oct 09, 2008 chammack Initial creation + * Jun 29, 2015 4311 randerso Reworking AlertViz dialogs to be resizable. * * * @author chammack @@ -49,10 +49,7 @@ import com.raytheon.uf.common.message.StatusMessage; public class SimpleDetailsComp extends Composite { - /** - * Shell of the parent composite - */ - private Shell shell = null; + private static final int NUM_DETAIL_LINES = 13; /** * Actually contains text of details message, lives in textBox @@ -66,25 +63,22 @@ public class SimpleDetailsComp extends Composite { */ public SimpleDetailsComp(Composite parent, int style) { super(parent, style); - this.shell = parent.getShell(); - initComponents(); - setVisible(false); } /** * Lay out composite with StyledText */ private void initComponents() { - GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); - setLayout(new GridLayout(1, false)); - setLayoutData(gd); + GridLayout layout = new GridLayout(1, false); + setLayout(layout); - gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); - gd.heightHint = 250; - st = new StyledText(this, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER); + st = new StyledText(this, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER + | SWT.WRAP); st.setEditable(false); - + GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + gd.heightHint = (st.getLineHeight() * NUM_DETAIL_LINES) + + (st.getBorderWidth() * 2); st.setLayoutData(gd); Menu popupMenu = new Menu(st); @@ -121,43 +115,10 @@ public class SimpleDetailsComp extends Composite { if (sm == null) { st.setText(""); } else { - StringBuilder sb = new StringBuilder(); - // sb.append(sm.getMessage()).append("\n"); - - String details = sm.getDetails(); - String[] lines = details.split("[\n]"); - - for (String line : lines) { - if (line.length() > 500) { - sb.append(line.substring(0, 500)).append( - "...text truncated\n"); - - } else { - sb.append(line).append("\n"); - } - } - st.setText(sb.toString()); + st.setText(sm.getDetails()); } } - /** - * Override so we can exclude this composite from the layout when hidden - */ - @Override - public void setVisible(boolean visible) { - ((GridData) this.getLayoutData()).exclude = !visible; - - if (visible == true) { - ((GridData) st.getLayoutData()).widthHint = getParent().getBounds().width - 46; - } - - super.setVisible(visible); - - shell.layout(); - shell.pack(); - - } - /** * */ diff --git a/cave/com.raytheon.uf.viz.alertviz.ui/src/com/raytheon/uf/viz/alertviz/ui/dialogs/SimpleLogViewer.java b/cave/com.raytheon.uf.viz.alertviz.ui/src/com/raytheon/uf/viz/alertviz/ui/dialogs/SimpleLogViewer.java index 666f4da9a1..e050c65880 100644 --- a/cave/com.raytheon.uf.viz.alertviz.ui/src/com/raytheon/uf/viz/alertviz/ui/dialogs/SimpleLogViewer.java +++ b/cave/com.raytheon.uf.viz.alertviz.ui/src/com/raytheon/uf/viz/alertviz/ui/dialogs/SimpleLogViewer.java @@ -26,12 +26,11 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.swt.SWT; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; @@ -51,10 +50,15 @@ import com.raytheon.uf.common.message.StatusMessage; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.viz.alertviz.Activator; import com.raytheon.uf.viz.alertviz.AlertvizException; +import com.raytheon.uf.viz.alertviz.AlertvizJob; import com.raytheon.uf.viz.alertviz.Container; +import com.raytheon.uf.viz.alertviz.IAlertArrivedCallback; import com.raytheon.uf.viz.alertviz.LogUtil; import com.raytheon.uf.viz.alertviz.LogUtil.Order; import com.raytheon.uf.viz.alertviz.SystemStatusHandler; +import com.raytheon.uf.viz.alertviz.config.AlertMetadata; +import com.raytheon.uf.viz.alertviz.config.Category; +import com.raytheon.uf.viz.alertviz.config.TrayConfiguration; /** * Implements a basic log viewer capability @@ -65,6 +69,8 @@ import com.raytheon.uf.viz.alertviz.SystemStatusHandler; * ------------ ---------- ----------- -------------------------- * Sep 30, 2008 1433 chammack Initial creation * Jun 02, 2015 4473 njensen Cleaned up warnings + * Jul 01, 2015 4473 njensen Fix update of table on alert arrival + * Jun 29, 2015 4311 randerso Reworking AlertViz dialogs to be resizable. * * * @@ -72,69 +78,67 @@ import com.raytheon.uf.viz.alertviz.SystemStatusHandler; * @version 1.0 */ -public class SimpleLogViewer extends Dialog { +public class SimpleLogViewer extends Dialog implements IAlertArrivedCallback { + + private Display display; - /** - * - */ private Shell shell; - /** - * - */ - private SimpleDetailsComp sdb; + private SimpleDetailsComp detailsComp; - /** - * - */ private Button showLog; - /** - * - */ - private Table reference; - - /** - * - */ int[] range; + private Table table; + + private Color yellow; + + private Color red; + + private Color orange; + + private Color black; + + boolean first; + /** * * @param parent */ public SimpleLogViewer(Shell parent) { super(parent, SWT.NONE); + first = true; + + display = parent.getDisplay(); + + // Create a new shell object and set the text for the dialog. + shell = new Shell(display, SWT.DIALOG_TRIM | SWT.MIN | SWT.TITLE + | SWT.RESIZE); + shell.setText("System Log"); + + initializeComponents(); } /** - * set focus to the dialog - * - * @return false if not open or disposed, true otherwise + * @return true if shell is null or disposed; */ - public boolean focus() { - if (shell == null || shell.isDisposed()) { - return false; - } else { + public boolean isDisposed() { + return ((shell != null) && shell.isDisposed()); + } + + /** + * Bring dialog to the top + */ + public void bringToTop() { + if ((shell != null) && !shell.isDisposed()) { + shell.setVisible(true); shell.forceFocus(); - return true; + shell.forceActive(); } } - /** - * Opens the dialog (makes visible). - * - * @return Null - */ - public Object open() { - // Create a new shell object and set the text for the dialog. - Shell parent = getParent(); - // shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.MIN | SWT.RESIZE); - shell = new Shell(parent.getDisplay(), SWT.DIALOG_TRIM | SWT.MIN - | SWT.TITLE | SWT.RESIZE); - shell.setText(getText()); - - /* TODO: Max Code: */ + private void initializeComponents() { GridLayout mainLayout = new GridLayout(1, true); mainLayout.marginHeight = 0; mainLayout.marginWidth = 0; @@ -143,15 +147,7 @@ public class SimpleLogViewer extends Dialog { GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, true); shell.setLayoutData(gd); - // shell.setLayout(new GridLayout(1, false)); - - // shell.setSize(800, 400); - // shell.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL - // | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL - // | GridData.VERTICAL_ALIGN_FILL)); - - final Table table = new Table(shell, SWT.BORDER | SWT.VIRTUAL); - reference = table; + table = new Table(shell, SWT.BORDER | SWT.VIRTUAL); final TableColumn[] columns = new TableColumn[] { new TableColumn(table, SWT.NONE), new TableColumn(table, SWT.NONE), @@ -159,10 +155,6 @@ public class SimpleLogViewer extends Dialog { new TableColumn(table, SWT.NONE), new TableColumn(table, SWT.NONE) }; - // table.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL - // | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL - // | GridData.VERTICAL_ALIGN_FILL)); - gd = new GridData(SWT.FILL, SWT.FILL, true, true); gd.widthHint = 800; gd.heightHint = 400; @@ -179,47 +171,39 @@ public class SimpleLogViewer extends Dialog { columns[3].setWidth(100); columns[4].setText("Message"); columns[4].setWidth(100); - final int[] range; - final int sz; + int sz = 0; try { range = SystemStatusHandler.getCurrentRange(); - this.range = range; - sz = range[1] - range[0]; + if ((range[0] == 0) && (range[1] == 0)) { + // database is empty + sz = 0; + } else { + sz = (range[1] - range[0]) + 1; + } } catch (AlertvizException e2) { Container .logInternal( Priority.ERROR, "SimpleLogViewer: exception getting current range from SystemStatusHandler.", e2); - return null; } table.setSortColumn(columns[0]); table.setSortDirection(SWT.UP); - final Color red = new Color(Display.getCurrent(), new RGB(255, 0, 0)); - final Color yellow = new Color(Display.getCurrent(), new RGB(255, 255, - 0)); - final Color orange = new Color(Display.getCurrent(), new RGB(255, 128, - 0)); - final Color black = new Color(Display.getCurrent(), new RGB(0, 0, 0)); - - table.addMouseListener(new MouseAdapter() { - @Override - public void mouseDoubleClick(MouseEvent e) { - showHideLog(); - } - }); + red = new Color(display, new RGB(255, 0, 0)); + yellow = new Color(Display.getCurrent(), new RGB(255, 255, 0)); + orange = new Color(display, new RGB(255, 128, 0)); + black = new Color(display, new RGB(0, 0, 0)); table.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { int idx = table.getSelectionIndex(); + StatusMessage sm = null; try { - StatusMessage sm = SystemStatusHandler.retrieveByPk(idx - + range[0]); - sdb.displayDetails(sm); + sm = SystemStatusHandler.retrieveByPk(idx + range[0]); } catch (Exception e1) { Container .logInternal( @@ -227,6 +211,12 @@ public class SimpleLogViewer extends Dialog { "SimpleLogViewer: exception retrieving StatusMessage by key from SystemStatusHandler: " + (idx + range[0]), e1); } + detailsComp.displayDetails(sm); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + showHideLog(); } }); @@ -332,19 +322,52 @@ public class SimpleLogViewer extends Dialog { } }); - sdb = new SimpleDetailsComp(shell, SWT.NONE); + detailsComp = new SimpleDetailsComp(shell, SWT.NONE); + gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + detailsComp.setLayoutData(gd); + + } + + @Override + public void alertArrived(StatusMessage statusMessage, + AlertMetadata alertMetadata, Category category, + TrayConfiguration globalConfiguration) { + + if (!table.isDisposed()) { + int count = table.getItemCount(); + table.setItemCount(count + 1); + } + } + + /** + * Opens the dialog (makes visible). + * + * @return null + */ + public Object open() { + Point minSize = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT); + shell.setMinimumSize(minSize); + + Point size = minSize; + shell.setSize(size); + + showHideLog(); + + AlertvizJob.getInstance().addAlertArrivedCallback(this); - shell.pack(); shell.open(); + table.showItem(table.getItem(table.getItemCount() - 1)); + table.select(table.getItemCount() - 1); // Wait until the shell is disposed. - Display display = parent.getDisplay(); + Display display = shell.getDisplay(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } + AlertvizJob.getInstance().removeAlertArrivedCallback(this); table.dispose(); red.dispose(); yellow.dispose(); @@ -358,26 +381,27 @@ public class SimpleLogViewer extends Dialog { * */ private void showHideLog() { - int idx = reference.getSelectionIndex(); - if (idx < 0) { - return; - } - try { - StatusMessage sm = SystemStatusHandler.retrieveByPk(idx + range[0]); - if (sdb.isVisible() == false) { - sdb.setVisible(true); - sdb.displayDetails(sm); - showLog.setText("Hide Log..."); - } else { - sdb.setVisible(false); - showLog.setText("Show Log..."); - } - } catch (AlertvizException e1) { - Container - .logInternal( - Priority.ERROR, - "SimpleLogViewer: exception retrieving StatusMessage by key from SystemStatusHandler: " - + (idx + range[0]), e1); + int delta = 0; + if (first || detailsComp.isVisible()) { + showLog.setText("Show Log..."); + + ((GridData) detailsComp.getLayoutData()).exclude = true; + detailsComp.setVisible(false); + delta -= detailsComp.getSize().y; + first = false; + } else { + showLog.setText("Hide Log..."); + ((GridData) detailsComp.getLayoutData()).exclude = false; + detailsComp.setVisible(true); + delta += detailsComp.getSize().y; } + + Point minSize = shell.getMinimumSize(); + minSize.y += delta; + shell.setMinimumSize(minSize); + + Point size = shell.getSize(); + size.y += delta; + shell.setSize(size); } } diff --git a/cave/com.raytheon.uf.viz.alertviz/logback-alertviz.xml b/cave/com.raytheon.uf.viz.alertviz/logback-alertviz.xml index 12023382ed..76b5dc4bee 100644 --- a/cave/com.raytheon.uf.viz.alertviz/logback-alertviz.xml +++ b/cave/com.raytheon.uf.viz.alertviz/logback-alertviz.xml @@ -2,9 +2,20 @@ + + + ${LOGDIR} + alertviz_${startTime}_admin.log + + + ${LOGDIR} + alertviz_${startTime}_console.log + + + INFO @@ -18,20 +29,16 @@ - - - alertviz-admin.log - LOGFILE_ALERTVIZ - - alertviz-admin.log%i - LOGFILE_ALERTVIZ - 1 - 5 - - - 2GB - - true + + + ${consoleLogFile} + + INFO + + + + + ${adminLogFile} @@ -71,5 +78,6 @@ + diff --git a/cave/com.raytheon.uf.viz.alertviz/src/com/raytheon/uf/viz/alertviz/AlertvizJob.java b/cave/com.raytheon.uf.viz.alertviz/src/com/raytheon/uf/viz/alertviz/AlertvizJob.java index da834b9206..0cb7a6b616 100644 --- a/cave/com.raytheon.uf.viz.alertviz/src/com/raytheon/uf/viz/alertviz/AlertvizJob.java +++ b/cave/com.raytheon.uf.viz.alertviz/src/com/raytheon/uf/viz/alertviz/AlertvizJob.java @@ -75,10 +75,11 @@ import com.raytheon.uf.viz.core.VizApp; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Sep 4, 2008 1433 chammack Initial creation - * Jun 3, 2013 2026 randerso Improve error handling - * May 5, 2015 4473 mschenke Major refactor - * Jun 1, 2015 4473 njensen Major refactor, removed send ability + * Sep 04, 2008 1433 chammack Initial creation + * Jun 03, 2013 2026 randerso Improve error handling + * May 05, 2015 4473 mschenke Major refactor + * Jun 01, 2015 4473 njensen Major refactor, removed send ability + * Jun 29, 2015 4473 njensen Register notification observer on start * * * @@ -178,6 +179,7 @@ public class AlertvizJob extends Job implements AlertService { this.broker.setPersistent(false); this.broker.setUseJmx(false); this.port = port; + AlertVizNotificationObserver.registerAlertVizNotificationObserver(); String localIP = "localhost"; try { diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UsersTreeLabelProvider.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UsersTreeLabelProvider.java index 61a5abfce7..d637c05bd7 100644 --- a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UsersTreeLabelProvider.java +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UsersTreeLabelProvider.java @@ -28,6 +28,7 @@ import java.util.Map; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; @@ -66,6 +67,7 @@ import com.raytheon.uf.viz.collaboration.ui.data.TreeObjectContainer; * Mar 06, 2014 2848 bclement get venueName directly from session * Jun 12, 2014 3267 bclement fixed missing null-check for outdated UI info * Oct 08, 2014 3705 bclement replaced checks for SessionGroupContainer with TreeObjectContainer + * Jun 23, 2015 4563 mapeters bold/color users in contacts list if logged-in * * * @@ -86,6 +88,7 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider { return connection.getContactsManager().getPresence(user); } + @Override protected String getDisplayName(UserId user) { return getLocalAlias(user); } @@ -136,7 +139,6 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider { } return rval; } - }; private List listeners; @@ -159,7 +161,7 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider { if (element instanceof UserId) { return userLabelProvider.getImage(element); } else if (element instanceof RosterEntry) { - return userLabelProvider.getImage((RosterEntry) element); + return userLabelProvider.getImage(element); } else if (element instanceof RosterGroup) { key = "roster_group"; } else if (element instanceof SharedGroup) { @@ -168,7 +170,7 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider { // key = "session_group"; } else if (element instanceof TreeObjectContainer) { key = ((TreeObjectContainer) element).getIcon(); - } + } if (imageMap.get(key) == null && !key.equals("")) { imageMap.put(key, CollaborationUtils.getNodeImage(key)); @@ -183,7 +185,7 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider { } else if (element instanceof SharedGroup) { return ((SharedGroup) element).getName(); } else if (element instanceof RosterEntry) { - return userLabelProvider.getText((RosterEntry) element); + return userLabelProvider.getText(element); } else if (element instanceof TreeObjectContainer) { return ((TreeObjectContainer) element).getLabel(); } else if (element instanceof UserId) { @@ -211,10 +213,13 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider { @Override public Font getFont(Object element) { - if (element instanceof RosterGroup || element instanceof SharedGroup - || element instanceof TreeObjectContainer) { - // for this case do nothing, as it is not the top level of - // session groups + boolean isGroupTitle = element instanceof RosterGroup + || element instanceof SharedGroup + || element instanceof TreeObjectContainer; + boolean isAvailableUser = element instanceof RosterEntry + && userLabelProvider.getPresence( + userLabelProvider.convertObject(element)).isAvailable(); + if (isGroupTitle || isAvailableUser) { if (boldFont == null) { Font currFont = Display.getCurrent().getSystemFont(); boldFont = new Font(Display.getCurrent(), currFont.toString(), @@ -225,6 +230,17 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider { return null; } + @Override + public Color getForeground(Object element) { + if (element instanceof RosterEntry) { + UserId user = userLabelProvider.convertObject(element); + if (userLabelProvider.getPresence(user).isAvailable()) { + return Display.getCurrent().getSystemColor(SWT.COLOR_BLUE); + } + } + return null; + } + /** * Gets the tooltip text on the tree that this is a label provider for */ @@ -234,7 +250,7 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider { if (element instanceof UserId) { return userLabelProvider.getToolTipText(element); } else if (element instanceof RosterEntry) { - return userLabelProvider.getToolTipText((RosterEntry) element); + return userLabelProvider.getToolTipText(element); } // builds the tooltip text for the session group // portion of the view @@ -242,10 +258,8 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider { IVenueSession sessGroup = (IVenueSession) element; IVenue venue = sessGroup.getVenue(); builder.append("ID: ").append(venue.getId()); - builder.append("\nName: ").append(venue.getName()) - .append("\n"); - builder.append("Subject: ").append(venue.getSubject()) - .append("\n"); + builder.append("\nName: ").append(venue.getName()).append("\n"); + builder.append("Subject: ").append(venue.getSubject()).append("\n"); builder.append("Participants: ") .append(venue.getParticipantCount()); return builder.toString(); diff --git a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/DeleteAWIPSProcedure.java b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/DeleteAWIPSProcedure.java index 19841d1b85..403923ecf8 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/DeleteAWIPSProcedure.java +++ b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/DeleteAWIPSProcedure.java @@ -24,6 +24,7 @@ import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.ui.handlers.HandlerUtil; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; import com.raytheon.uf.common.localization.LocalizationFile; import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException; import com.raytheon.uf.common.status.IUFStatusHandler; @@ -49,6 +50,8 @@ import com.raytheon.viz.ui.dialogs.localization.VizLocalizationFileListDlg.Mode; * Jul 8, 2008 #1183 chammack Migrate to new localization * Oct 16, 2012 #1229 rferrel Changes for non-blocking VizLocalizationFileListDlg. * Jun 02, 2015 #4401 bkowal Updated to use {@link VizLocalizationFileListDlg}. + * Jun 30, 2015 #4401 bkowal Specify the localization type when constructing a + * {@link VizLocalizationFileListDlg}. * * * @@ -74,7 +77,8 @@ public class DeleteAWIPSProcedure extends AbstractHandler { || listDlg.isDisposed()) { listDlg = new VizLocalizationFileListDlg("Delete Procedure", HandlerUtil.getActiveShell(event), Mode.DELETE, - ProcedureDlg.PROCEDURES_DIR, "procedures"); + ProcedureDlg.PROCEDURES_DIR, "procedures", + LocalizationType.CAVE_STATIC); listDlg.setCloseCallback(new ICloseCallback() { @Override diff --git a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/OpenAWIPSProcedure.java b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/OpenAWIPSProcedure.java index 0f7fb9026f..01a6fbf939 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/OpenAWIPSProcedure.java +++ b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/OpenAWIPSProcedure.java @@ -26,6 +26,7 @@ import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.ui.handlers.HandlerUtil; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; import com.raytheon.uf.common.localization.LocalizationFile; import com.raytheon.uf.common.localization.LocalizationUtil; import com.raytheon.uf.common.status.IUFStatusHandler; @@ -35,6 +36,7 @@ import com.raytheon.uf.viz.d2d.ui.dialogs.procedures.ProcedureDlg; import com.raytheon.viz.ui.VizWorkbenchManager; import com.raytheon.viz.ui.actions.LoadPerspectiveHandler; import com.raytheon.viz.ui.dialogs.ICloseCallback; +import com.raytheon.viz.ui.dialogs.localization.VizLocalizationFileListDlg; import com.raytheon.viz.ui.dialogs.localization.VizOpenLocalizationFileListDlg; /** @@ -52,6 +54,8 @@ import com.raytheon.viz.ui.dialogs.localization.VizOpenLocalizationFileListDlg; * Jun 07, 2013 2074 mnash Don't open the dialog if no procedures are deserialized * Aug 11, 2014 3480 bclement added logging * Jun 02, 2015 #4401 bkowal Updated to use {@link VizOpenLocalizationFileListDlg}. + * Jun 30, 2015 #4401 bkowal Specify the localization type when constructing a + * {@link VizOpenLocalizationFileListDlg}. * * * @author chammack @@ -76,7 +80,8 @@ public class OpenAWIPSProcedure extends AbstractHandler { if (dialog == null || dialog.getShell() == null || dialog.isDisposed()) { dialog = new VizOpenLocalizationFileListDlg("Open Procedure", HandlerUtil.getActiveShell(event), - ProcedureDlg.PROCEDURES_DIR, "procedures"); + ProcedureDlg.PROCEDURES_DIR, "procedures", + LocalizationType.CAVE_STATIC); dialog.setCloseCallback(new ICloseCallback() { @Override diff --git a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureListFileDlg.java b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureListFileDlg.java index 147aef5d68..e4f847b43b 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureListFileDlg.java +++ b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureListFileDlg.java @@ -28,6 +28,7 @@ import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Shell; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; import com.raytheon.viz.ui.dialogs.localization.VizLocalizationFileListDlg; /** @@ -43,6 +44,7 @@ import com.raytheon.viz.ui.dialogs.localization.VizLocalizationFileListDlg; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Jun 2, 2015 4401 bkowal Initial creation + * Jun 30, 2015 4401 bkowal Specify the localization level during construction. * * * @@ -67,7 +69,8 @@ public class ProcedureListFileDlg extends VizLocalizationFileListDlg { */ public ProcedureListFileDlg(String title, Shell parent, Mode mode, String localizationDirectory) { - super(title, parent, mode, localizationDirectory, "procedures"); + super(title, parent, mode, localizationDirectory, "procedures", + LocalizationType.CAVE_STATIC); } @Override diff --git a/cave/com.raytheon.uf.viz.damagepath/plugin.xml b/cave/com.raytheon.uf.viz.damagepath/plugin.xml index d79db21098..0400ef47d4 100644 --- a/cave/com.raytheon.uf.viz.damagepath/plugin.xml +++ b/cave/com.raytheon.uf.viz.damagepath/plugin.xml @@ -4,9 +4,9 @@ * @@ -175,7 +176,7 @@ public class DamagePathLayer extends Polygon polygon = PolygonUtil.makeDefaultPolygon(getResourceContainer() .getActiveDisplayPane().getRenderableDisplay()); DrawablePolygon drawablePolygon = new DamagePathPolygon(polygon, this); - polygons.add(0, drawablePolygon); + super.resetPolygons(Arrays.asList(drawablePolygon)); } @Override diff --git a/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/DamagePathLoader.java b/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/DamagePathLoader.java index 9c90cbbe8e..54409d5f96 100644 --- a/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/DamagePathLoader.java +++ b/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/DamagePathLoader.java @@ -26,7 +26,6 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; @@ -38,7 +37,6 @@ import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.Name; import com.raytheon.uf.common.json.JsonException; -import com.raytheon.uf.common.json.geo.BasicJsonService; import com.raytheon.uf.common.json.geo.GeoJsonMapUtil; import com.raytheon.uf.common.json.geo.IGeoJsonService; import com.raytheon.uf.common.json.geo.SimpleGeoJsonService; @@ -47,7 +45,6 @@ import com.raytheon.uf.common.localization.exception.LocalizationException; import com.raytheon.uf.common.util.Pair; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.Polygon; -import com.vividsolutions.jts.operation.valid.IsValidOp; /** * Loads a damage path GeoJSON-formatted file from either local disk or the @@ -62,6 +59,10 @@ import com.vividsolutions.jts.operation.valid.IsValidOp; * Jun 05, 2015 #4375 dgilling Initial creation * Jun 18, 2015 #4354 dgilling Support FeatureCollections so each polygon * can have its own properties. + * Jun 30, 2015 #4354 dgilling Remove unnecessary back compat code for + * 15.1 version of damage path tool. + * Jul 01, 2015 #4375 dgilling Remove isValid check to imported + * polygons. * * * @@ -71,12 +72,8 @@ import com.vividsolutions.jts.operation.valid.IsValidOp; public final class DamagePathLoader { - private static final String UNSUPPORTED_GEOJSON_TYPE = "Damage path file is unsupported GeoJSON object type %s. This tool only supports Feature and Geometry objects."; - private static final String UNSUPPORTED_GEOM_TYPE = "Damage path file contains invalid geometry type %s at geometry index %d. Must only contain Polygons."; - private static final String INVALID_POLYGON = "Damage path file contains an invalid Polyon at index %d: %s"; - private final Collection>> damagePathData; public DamagePathLoader(LocalizationFile locFile) @@ -119,85 +116,6 @@ public final class DamagePathLoader { } private void loadFromInputStream(final InputStream is) throws JsonException { - Geometry deserializedGeom = null; - Map deserializedProps = Collections.emptyMap(); - GeoJsonMapUtil geoJsonUtil = new GeoJsonMapUtil(); - - /* - * For compatibility with any users that may have an autosaved damage - * path file from previous builds, we'll support deserializing Geometry, - * Feature and FeatureCollection GeoJSON types. - * - * TODO: remove this code for code that just expects the file to always - * be a FeatureCollection. - */ - Map jsonObject = (Map) new BasicJsonService() - .deserialize(is, LinkedHashMap.class); - String geoJsonType = jsonObject.get(GeoJsonMapUtil.TYPE_KEY).toString(); - if (geoJsonType.equals(GeoJsonMapUtil.FEATURE_COLL_TYPE)) { - FeatureCollection featureCollection = geoJsonUtil - .populateFeatureCollection(jsonObject); - populateDataFromFeatureCollection(featureCollection); - return; - } else if (geoJsonType.equals(GeoJsonMapUtil.FEATURE_TYPE)) { - SimpleFeature feature = geoJsonUtil.populateFeature(jsonObject); - deserializedGeom = (Geometry) feature.getDefaultGeometry(); - - Name defaultGeomAttrib = feature.getDefaultGeometryProperty() - .getName(); - deserializedProps = new LinkedHashMap<>(); - deserializedProps.put(GeoJsonMapUtil.ID_KEY, feature.getID()); - for (Property p : feature.getProperties()) { - if (!defaultGeomAttrib.equals(p.getName())) { - deserializedProps.put(p.getName().toString(), p.getValue() - .toString()); - } - } - } else if (isGeometryType(geoJsonType)) { - deserializedGeom = geoJsonUtil.populateGeometry(jsonObject); - } else { - throw new JsonException(String.format(UNSUPPORTED_GEOJSON_TYPE, - geoJsonType)); - } - - int numGeometries = deserializedGeom.getNumGeometries(); - for (int i = 0; i < numGeometries; i++) { - Geometry geomN = deserializedGeom.getGeometryN(i); - if (geomN instanceof Polygon) { - Polygon newPolygon = (Polygon) geomN; - IsValidOp validator = new IsValidOp(newPolygon); - if (validator.isValid()) { - Pair> polygonAndProps = new Pair<>( - newPolygon, deserializedProps); - damagePathData.add(polygonAndProps); - } else { - throw new JsonException(String.format(INVALID_POLYGON, i, - validator.getValidationError())); - } - } else { - throw new JsonException(String.format(UNSUPPORTED_GEOM_TYPE, - geomN.getGeometryType(), i)); - } - } - } - - private boolean isGeometryType(String geoJsonType) { - return ((GeoJsonMapUtil.GEOM_COLL_TYPE.equals(geoJsonType)) - || (GeoJsonMapUtil.LINE_STR_TYPE.equals(geoJsonType)) - || (GeoJsonMapUtil.MULT_LINE_STR_TYPE.equals(geoJsonType)) - || (GeoJsonMapUtil.MULT_POINT_TYPE.equals(geoJsonType)) - || (GeoJsonMapUtil.MULT_POLY_TYPE.equals(geoJsonType)) - || (GeoJsonMapUtil.POINT_TYPE.equals(geoJsonType)) || (GeoJsonMapUtil.POLY_TYPE - .equals(geoJsonType))); - } - - /* - * TODO: Replace loadFromInputStream with this method when we no longer - * desire supporting the version 15.1 GeoJSON formatted damage path files. - */ - @SuppressWarnings("unused") - private void loadFromInputStreamFuture(final InputStream is) - throws JsonException { IGeoJsonService json = new SimpleGeoJsonService(); FeatureCollection featureCollection = json .deserializeFeatureCollection(is); @@ -215,12 +133,6 @@ public final class DamagePathLoader { Geometry geom = (Geometry) feature.getDefaultGeometry(); if (geom instanceof Polygon) { Polygon newPolygon = (Polygon) geom; - IsValidOp validator = new IsValidOp(newPolygon); - if (!validator.isValid()) { - throw new JsonException(String.format(INVALID_POLYGON, - featureIdx, validator.getValidationError())); - } - Map properties = new LinkedHashMap<>(); Name defaultGeomAttrib = feature .getDefaultGeometryProperty().getName(); diff --git a/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/DamagePathPolygon.java b/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/DamagePathPolygon.java index 4f40f2d835..51eb99bc96 100644 --- a/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/DamagePathPolygon.java +++ b/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/DamagePathPolygon.java @@ -23,7 +23,6 @@ import java.util.Collections; import java.util.Map; import com.raytheon.uf.viz.drawing.polygon.DrawablePolygon; -import com.raytheon.uf.viz.drawing.polygon.PolygonLayer; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Polygon; @@ -37,6 +36,7 @@ import com.vividsolutions.jts.geom.Polygon; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Jun 18, 2015 #4354 dgilling Initial creation + * Jun 30, 2015 #4354 dgilling Force setProperties to trigger a save. * * * @@ -51,23 +51,23 @@ public class DamagePathPolygon extends DrawablePolygon { private Map properties; - public DamagePathPolygon(PolygonLayer polygonLayer) { - super(polygonLayer); + public DamagePathPolygon(DamagePathLayer layer) { + super(layer); this.properties = DEFAULT_PROPS; } - public DamagePathPolygon(Polygon polygon, PolygonLayer polygonLayer) { - this(polygon, DEFAULT_PROPS, polygonLayer); + public DamagePathPolygon(Polygon polygon, DamagePathLayer layer) { + this(polygon, DEFAULT_PROPS, layer); } public DamagePathPolygon(Polygon polygon, Map properties, - PolygonLayer polygonLayer) { - super(polygon, polygonLayer); + DamagePathLayer layer) { + super(polygon, layer); this.properties = properties; } - public DamagePathPolygon(Coordinate[] coords, PolygonLayer polygonLayer) { - super(coords, polygonLayer); + public DamagePathPolygon(Coordinate[] coords, DamagePathLayer layer) { + super(coords, layer); this.properties = DEFAULT_PROPS; } @@ -87,5 +87,6 @@ public class DamagePathPolygon extends DrawablePolygon { public void setProperties(Map properties) { this.properties = properties; + ((DamagePathLayer) polygonLayer).scheduleSaveJob(); } } diff --git a/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/DamagePathUtils.java b/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/DamagePathUtils.java index e59ebebef3..2ccd6398c1 100644 --- a/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/DamagePathUtils.java +++ b/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/DamagePathUtils.java @@ -19,67 +19,89 @@ **/ package com.raytheon.uf.viz.damagepath; +import java.awt.geom.Point2D; +import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Deque; import java.util.List; import javax.measure.converter.UnitConverter; -import javax.measure.quantity.Length; import javax.measure.unit.NonSI; import javax.measure.unit.SI; -import javax.measure.unit.Unit; import org.geotools.referencing.GeodeticCalculator; import com.raytheon.uf.common.dataplugin.radar.RadarStation; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; -import com.raytheon.viz.awipstools.common.stormtrack.AbstractStormTrackResource; -import com.raytheon.viz.awipstools.common.stormtrack.StormTrackState; -import com.raytheon.viz.awipstools.common.stormtrack.StormTrackState.StormCoord; +import com.raytheon.viz.awipstools.ui.layer.InteractiveBaselinesLayer.Baseline; import com.raytheon.viz.radar.util.StationUtils; import com.vividsolutions.jts.geom.Coordinate; -import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; -import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Polygon; /** * Utility class for Damage Paths. - * + * *
- * 
+ *
  * SOFTWARE HISTORY
- * 
+ *
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
  * Mar 23, 2015 3977       nabowle     Initial creation
  * Mar 26, 2015 3977       nabowle     Limit distance to avoid polar errors. Log
  *                                     skipped points.
  * Apr 01, 2015 3977       nabowle     rename the status handler.
- * 
+ * Jun 18, 2015 3977       nabowle     Fix buffering. Renamed mehtods to
+ *                                     specify that they're for Tornados.
+ * Jun 25, 2015 3977       nabowle     Redo inner-point buffering for use with
+ *                                     Interactive Baselines.
+ *
  * 
- * + * * @author nabowle * @version 1.0 */ public class DamagePathUtils { + /** + * The number of degrees between points at the ends of a Tornado Damage Path + * Buffer. + */ + private static final double END_DEGREE_DIFF = 30.0D; + + /** Upper degree boundary to define a sharp angle. */ + private static final double SHARP_ANGLE = 100; + + /** Lower degree boundary when a sharp angle straddles 0 degrees. */ + private static final double SHARP_ANGLE_INV = 360 - SHARP_ANGLE; + private static final IUFStatusHandler statusHandler = UFStatus .getHandler(DamagePathUtils.class); - /** The unit for the uncertainty algorithm. */ - private static Unit TARGET_UNIT = NonSI.MILE; + /** Convert miles for the algorithm to meters. */ + private static UnitConverter TO_METERS = NonSI.MILE + .getConverterTo(SI.METER); - /** Convert meters returned the GeodeticCalculator to the desired unit. */ - private static UnitConverter METERS_TO = SI.METER - .getConverterTo(TARGET_UNIT); + /* + * Pre-convert algorithm constants to meters to prevent having to convert + * back and forth. + */ + private static final double ONE_TENTH_MILE = TO_METERS.convert(0.1); + + private static final double THREE_TENTHS_MILE = TO_METERS.convert(0.3); + + private static final double FORTY_MILES = TO_METERS.convert(40.0); + + private static final double EIGHTY_MILES = TO_METERS.convert(80.0); /** * Maximum distance of a point to the radar station to use when estimating a - * damage path polygon. Any farther point will be ignored. + * damage path polygon. Any farther point will be ignored. Based on radar + * max extent */ - private static final double MAX_DISTANCE = NonSI.MILE.getConverterTo( - TARGET_UNIT).convert(300.0); // Based on radar max extent + private static final double MAX_DISTANCE = TO_METERS.convert(300.0); private DamagePathUtils() { super(); @@ -87,129 +109,405 @@ public class DamagePathUtils { /** - * Estimates the damage path polygon for a storm track. + * Estimates a Tornado damage path polygon for a baseline. * - * @param stormTrack - * The storm track to create a damage path for. - * @return The estimated damage path polygon for a storm track. + * @param baseline + * The baseline to create a tornado damage path for. + * @return The estimated tornado damage path polygon for a baseline. */ - public static Polygon estimateDamagePath( - AbstractStormTrackResource stormTrack) { - - StormTrackState stState = stormTrack.getStormTrackState(); + public static Polygon estimateTornadoDamagePath(Baseline baseline) { + Coordinate[] coords = baseline.line.getCoordinates(); RadarStation station = StationUtils.getInstance().getHomeRadarStation(); GeometryFactory gf = new GeometryFactory(); - List skippedCoords = new ArrayList<>(); - Geometry damagePathBuffer = createBuffer(stState.timePoints, station, - gf, null, skippedCoords); - damagePathBuffer = createBuffer(stState.futurePoints, station, gf, - damagePathBuffer, skippedCoords); + List skippedCoords = new ArrayList<>(); + List validCoords = new ArrayList<>(); + GeodeticCalculator gc = new GeodeticCalculator(); + filterCoords(coords, station, skippedCoords, validCoords, + gc); if (!skippedCoords.isEmpty()) { StringBuilder sb = new StringBuilder(); - sb.append("Skipped the following Storm Coordinates because they ") + sb.append( + "Skipped the following Coordinates for Baseline " + + baseline.name + " because they ") .append("are out of range of the radar station. "); - for (StormTrackState.StormCoord coord : skippedCoords) { - sb.append("(").append(coord.time.toString()).append(", ") - .append(coord.coord.x).append(", ") - .append(coord.coord.y).append(") "); + for (Coordinate coord : skippedCoords) { + sb.append("(").append(coord.x).append(", ").append(coord.y) + .append(") "); } statusHandler.info(sb.toString()); } - /* - * user likely tried to import before creating track or entire track is - * outside of the max range. - */ - if (damagePathBuffer == null) { + if (validCoords.isEmpty()) { String suggestion; if (skippedCoords.isEmpty()) { - suggestion = "Make sure the storm track is initialized."; + suggestion = "Make sure the baseline is initialized."; } else { - suggestion = "Make sure the storm track is within range of the radar station."; + suggestion = "Make sure the baseline is within range of the radar station."; } statusHandler - .warn("Could not create a Damage Path polygon for the storm track. " - + suggestion); + .warn("Could not create a Damage Path polygon for Baseline " + + baseline.name + ". " + suggestion); return null; } - Polygon polygon = gf.createPolygon(damagePathBuffer.convexHull() - .getCoordinates()); + Coordinate[] damagePathCoords = createTornadoBuffer(validCoords, station, gc, + gf); + + Polygon polygon = gf.createPolygon(damagePathCoords); return polygon; } /** - * Creates a buffers a buffer around the storm coordinates. If - * damagePathBuffer is non null, the created buffer will be the union of the - * two buffers. + * Filter the coordinates based on their range to the given radar station. * * @param stormCoords - * The storm track coordinates. + * The coordinates. * @param station - * The station to base distance on. - * @param gf - * The geometry factory. - * @param damagePathBuffer - * The current damage path buffer. May be null. - * @param farCoords - * The list to add any skipped coordinates to. - * @return The created buffer. If damagePathBuffer is not null, the created - * buffer will included damagePathBuffer. + * The radar station. + * @param skippedCoords + * A list where coordinates that are out of range of the station + * will be added to. + * @param validCoords + * A list where coordinates that are in range of the station will + * be added to. + * @param gc + * A GeodeticCalculator. */ - private static Geometry createBuffer( - StormTrackState.StormCoord[] stormCoords, RadarStation station, - GeometryFactory gf, Geometry damagePathBuffer, - List farCoords) { - if (stormCoords == null || stormCoords.length == 0) { - return damagePathBuffer; - } + private static void filterCoords(Coordinate[] stormCoords, + RadarStation station, List skippedCoords, + List validCoords, GeodeticCalculator gc) { + Coordinate stormCoord; + double distance; + if (stormCoords != null) { + for (int i = 0; i < stormCoords.length; i++) { + stormCoord = stormCoords[i]; + gc.setStartingGeographicPoint(stormCoord.x, stormCoord.y); + gc.setDestinationGeographicPoint(station.getLon(), + station.getLat()); + distance = gc.getOrthodromicDistance(); - GeodeticCalculator gc = new GeodeticCalculator(); - Point point; - Geometry buffer; - double distanceMeters; // distance in meters - double distance; // distance in the desired unit + if (distance > MAX_DISTANCE) { + skippedCoords.add(stormCoords[i]); + } else { + validCoords.add(stormCoords[i]); + } + } + } + } + + /** + * Creates a buffer around the line defined by the storm coordinates using + * Doug Speheger's tornado damage path algorithm. + * + * @param stormCoords + * The storm coordinates to create a damage path around. + * @param station + * The radar station to use. + * @param gc + * A GeodeticCalculator. + * @param gf + * A GeometryFactory. + * @return A Geometry representing an estimated Tornado Damage Path for the + * given storm coordinates. If the no coordinates are provided, null + * is returned. + */ + private static Coordinate[] createTornadoBuffer(List stormCoords, + RadarStation station, GeodeticCalculator gc, GeometryFactory gf) { + // left hand side points + List lhsPoints = new ArrayList<>(); + // right hand side points + Deque rhsPoints = new ArrayDeque<>(); double uncertainty; Coordinate stormCoord; - for (int i = 0; i < stormCoords.length; i++) { - stormCoord = stormCoords[i].coord; - gc.setStartingGeographicPoint(stormCoord.x, stormCoord.y); - gc.setDestinationGeographicPoint(station.getLon(), station.getLat()); - distanceMeters = gc.getOrthodromicDistance(); - distance = METERS_TO.convert(distanceMeters); + /* Create a concave hull for a linear set of coordinates. */ + for (int i = 0; i < stormCoords.size(); i++) { + stormCoord = stormCoords.get(i); + uncertainty = calculateUncertainty(station, gc, stormCoord); - if (distance > MAX_DISTANCE) { - farCoords.add(stormCoords[i]); - continue; + if (stormCoords.size() == 1) { + /* + * In the case that there's only one coordinate, draw a circle + * around the point and break out. + */ + for (double d = -180; d < 180; d += END_DEGREE_DIFF) { + gc.setDirection(d, uncertainty); + lhsPoints.add(gc.getDestinationGeographicPoint()); + } + break; } - /* - * Based off of research done by Doug Speheger comparing surveyed - * tornado paths to manually identified radar tornadic vortex - * signatures in 2008-2012. In the initial dataset, 87% of tornadoes - * were within this range of uncertainty. - */ - if (distance < 40.0) { - uncertainty = 0.3 + distance * 0.005; - } else if (distance < 80.0) { - uncertainty = 0.1 + distance * 0.01; + if (i == 0) { + createStartCap(stormCoords, gc, lhsPoints, uncertainty, i); + } else if (i < stormCoords.size() - 1) { + bufferInnerPoint(stormCoord, stormCoords, gc, lhsPoints, + rhsPoints, uncertainty, i, station); } else { - uncertainty = distance * 0.015 - 0.3; + createEndCap(stormCoords, gc, rhsPoints, uncertainty, i); } - point = gf.createPoint(stormCoord); - buffer = point.buffer(uncertainty); - if (damagePathBuffer == null) { - damagePathBuffer = buffer; - } else { - damagePathBuffer = damagePathBuffer.union(buffer); - } } - return damagePathBuffer; + lhsPoints.addAll(rhsPoints); + + Coordinate[] coordinates = new Coordinate[lhsPoints.size() + 1]; + Point2D point; + for (int i = 0; i < lhsPoints.size(); i++) { + point = lhsPoints.get(i); + coordinates[i] = new Coordinate(point.getX(), point.getY()); + } + coordinates[coordinates.length - 1] = coordinates[0]; + + return coordinates; + } + + + /** + * Based off of research done by Doug Speheger comparing surveyed tornado + * paths to manually identified radar tornadic vortex signatures in + * 2008-2012. In the initial dataset, 87% of tornadoes were within this + * range of uncertainty. + * + * Note: All units are in meters. Constants have been pre-converted from + * miles to meters. + * + * @param station + * @param gc + * @param coord + * @return + */ + private static double calculateUncertainty(RadarStation station, + GeodeticCalculator gc, Coordinate coord) { + gc.setStartingGeographicPoint(coord.x, coord.y); + gc.setDestinationGeographicPoint(station.getLon(), station.getLat()); + double distance = gc.getOrthodromicDistance(); + + double uncertainty; + if (distance < FORTY_MILES) { + uncertainty = THREE_TENTHS_MILE + distance * 0.005; + } else if (distance < EIGHTY_MILES) { + uncertainty = ONE_TENTH_MILE + distance * 0.01; + } else { + uncertainty = distance * 0.015 - THREE_TENTHS_MILE; + } + return uncertainty; + } + + /** + * Creates a buffer around a non-end point. If the path is on a generally + * straight path, just create two points on opposite sides of the path + * point. If the path coordinate is the vertex of an angle is sharp, create + * a couple points around the outside of the angle and create a single point + * on the inside that's uncertainty-meters from the point and both lines + * creating the angle. + * + * @param stormCoord + * @param stormCoords + * @param gc + * @param lhsPoints + * @param rhsPoints + * @param uncertainty + * @param i + * @param station + */ + private static void bufferInnerPoint(Coordinate stormCoord, + List stormCoords, GeodeticCalculator gc, + List lhsPoints, Deque rhsPoints, + double uncertainty, int i, RadarStation station) { + gc.setStartingGeographicPoint(stormCoord.x, stormCoord.y); + + Coordinate nextCoord = stormCoords.get(i + 1); + gc.setDestinationGeographicPoint(nextCoord.x, nextCoord.y); + double azimuthToNext = nonNegativeAzimuth(gc.getAzimuth()); + + Coordinate prevCoord = stormCoords.get(i - 1); + gc.setDestinationGeographicPoint(prevCoord.x, prevCoord.y); + double azimuthToPrev = nonNegativeAzimuth(gc.getAzimuth()); + + double angle = Math.abs(azimuthToPrev - azimuthToNext); + boolean sharpAngle = (angle <= SHARP_ANGLE && angle > 0) + || (angle >= SHARP_ANGLE_INV && angle < 360); + + if (sharpAngle) { + boolean rhsOnInside = angle <= SHARP_ANGLE ? azimuthToNext < azimuthToPrev + : azimuthToPrev < azimuthToNext; + double bisectionAngle = Math + .toRadians(angle >= SHARP_ANGLE_INV ? (360.0 - angle) / 2 + : angle / 2); + + gc.setDirection(geodeticAzimuth(azimuthToNext + 180), uncertainty); + if (rhsOnInside) { + lhsPoints.add(gc.getDestinationGeographicPoint()); + + createOpposingPoints(stormCoord, gc, lhsPoints, + new ArrayDeque(), uncertainty, azimuthToNext, + azimuthToPrev); + double innerUncertainty = Math.abs(uncertainty + / Math.sin(bisectionAngle)); + if (innerUncertainty < uncertainty) { + innerUncertainty = uncertainty; + } + createOpposingPoints(stormCoord, gc, new ArrayList(), + rhsPoints, innerUncertainty, azimuthToNext, + azimuthToPrev); + + gc.setDirection(geodeticAzimuth(azimuthToPrev + 180), + uncertainty); + lhsPoints.add(gc.getDestinationGeographicPoint()); + + } else { + rhsPoints.push(gc.getDestinationGeographicPoint()); + + createOpposingPoints(stormCoord, gc, new ArrayList(), + rhsPoints, uncertainty, azimuthToNext, azimuthToPrev); + double innerUncertainty = Math.abs(uncertainty + / Math.sin(bisectionAngle)); + if (innerUncertainty < uncertainty) { + innerUncertainty = uncertainty; + } + createOpposingPoints(stormCoord, gc, lhsPoints, + new ArrayDeque(), innerUncertainty, + azimuthToNext, azimuthToPrev); + + gc.setDirection(geodeticAzimuth(azimuthToPrev + 180), + uncertainty); + rhsPoints.push(gc.getDestinationGeographicPoint()); + } + } else { + createOpposingPoints(stormCoord, gc, lhsPoints, rhsPoints, uncertainty, + azimuthToNext, azimuthToPrev); + } + } + + /** + * Create two points at 180 degrees from each other on the imaginary line + * that bisects the angle created at this point. + * + * @param coord + * @param gc + * @param lhsPoints + * @param rhsPoints + * @param uncertainty + * @param azimuthToNext + * @param azimuthToPrev + */ + private static void createOpposingPoints(Coordinate coord, + GeodeticCalculator gc, + List lhsPoints, Deque rhsPoints, + double uncertainty, double azimuthToNext, double azimuthToPrev) { + gc.setStartingGeographicPoint(coord.x, coord.y); + double pointAzimuth = geodeticAzimuth(Math.min(azimuthToNext, + azimuthToPrev) + + Math.abs(azimuthToPrev - azimuthToNext) / 2); + + if (azimuthToNext <= azimuthToPrev) { + pointAzimuth = geodeticAzimuth(pointAzimuth + 180); + } + + gc.setDirection(pointAzimuth, uncertainty); + lhsPoints.add(gc.getDestinationGeographicPoint()); + + pointAzimuth = geodeticAzimuth(pointAzimuth + 180); + + gc.setDirection(pointAzimuth, uncertainty); + rhsPoints.push(gc.getDestinationGeographicPoint()); + } + + + /** + * Create's a curved half-circle buffer around the starting coordinate. + * + * @param stormCoords + * @param gc + * @param lhsPoints + * @param uncertainty + * @param i + */ + private static void createStartCap(List stormCoords, + GeodeticCalculator gc, List lhsPoints, double uncertainty, + int i) { + Coordinate nextCoord = stormCoords.get(i + 1); + gc.setDestinationGeographicPoint(nextCoord.x, nextCoord.y); + double azimuthToNext = gc.getAzimuth(); + + double pointAzimuth = geodeticAzimuth(azimuthToNext + 90); + gc.setDirection(pointAzimuth, uncertainty); + lhsPoints.add(gc.getDestinationGeographicPoint()); + + for (double d = END_DEGREE_DIFF; d <= 180; d += END_DEGREE_DIFF) { + pointAzimuth = geodeticAzimuth(pointAzimuth + END_DEGREE_DIFF); + gc.setDirection(pointAzimuth, uncertainty); + lhsPoints.add(gc.getDestinationGeographicPoint()); + } + } + + /** + * Create's a curved half-circle buffer around the ending coordinate. + * + * @param stormCoords + * @param gc + * @param rhsPoints + * @param uncertainty + * @param i + */ + private static void createEndCap(List stormCoords, + GeodeticCalculator gc, Deque rhsPoints, + double uncertainty, int i) { + Coordinate prevCoord = stormCoords.get(i - 1); + gc.setDestinationGeographicPoint(prevCoord.x, prevCoord.y); + double azimuthToPrev = gc.getAzimuth(); + + double pointAzimuth = geodeticAzimuth(azimuthToPrev - 90); + gc.setDirection(pointAzimuth, uncertainty); + rhsPoints.push(gc.getDestinationGeographicPoint()); + + for (double d = END_DEGREE_DIFF; d <= 180; d += END_DEGREE_DIFF) { + pointAzimuth = geodeticAzimuth(pointAzimuth - END_DEGREE_DIFF); + gc.setDirection(pointAzimuth, uncertainty); + rhsPoints.push(gc.getDestinationGeographicPoint()); + } + } + + /** + * Clamps the azimuth to [-180, 180] for use with the GeodeticCalculator. + * + * @param azimuth + * The azimuth. + * @return An equivalent azimuth in [-180, 180]. + */ + private static double geodeticAzimuth(double azimuth) { + double az = azimuth; + while (az < -180.0) { + az += 360.0; + } + + while (az > 180.0) { + az -= 360.0; + } + + return az; + } + + /** + * Clamps the azimuth to [0, 360] to simplify the azimath. + * + * @param azimuth + * The azimuth. + * @return An equivalent azimuth in [0, 360]. + */ + private static double nonNegativeAzimuth(double azimuth) { + double az = azimuth; + while (az < 0) { + az += 360.0; + } + + while (az > 360.0) { + az -= 360.0; + } + + return az; } } diff --git a/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/ImportFromDistanceSpeedAction.java b/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/ImportFromDistanceSpeedAction.java deleted file mode 100644 index e026096497..0000000000 --- a/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/ImportFromDistanceSpeedAction.java +++ /dev/null @@ -1,118 +0,0 @@ -/** - * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA - * This software product contains export-restricted data whose - * export/transfer/disclosure is restricted by U.S. law. Dissemination - * to non-U.S. persons whether in the United States or abroad requires - * an export license or other authorization. - * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * - * See the AWIPS II Master Rights File ("Master Rights File.pdf") for - * further licensing information. - **/ -package com.raytheon.uf.viz.damagepath; - -import com.raytheon.uf.common.status.IUFStatusHandler; -import com.raytheon.uf.common.status.UFStatus; -import com.raytheon.uf.viz.core.VizApp; -import com.raytheon.uf.viz.core.drawables.ResourcePair; -import com.raytheon.uf.viz.core.rsc.AbstractVizResource; -import com.raytheon.uf.viz.core.rsc.ResourceList; -import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability; -import com.raytheon.viz.awipstools.ui.layer.DistanceSpeedLayer; -import com.raytheon.viz.ui.cmenu.AbstractRightClickAction; -import com.vividsolutions.jts.geom.Polygon; - -/** - * Action to create a damage path from a DistanceSpeedLayer. - * - *
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Mar 23, 2015 3977       nabowle     Initial creation
- * Jun 01, 2015 3975       dgilling    Update for DamageLayer changes for 
- *                                     multiple polygon support.
- * Jun 18, 2015 4354       dgilling    Update isEnabled to consider editable
- *                                     capability.
- * 
- * 
- * - * @author nabowle - * @version 1.0 - */ - -public class ImportFromDistanceSpeedAction extends AbstractRightClickAction { - - protected static final transient IUFStatusHandler statusHandler = UFStatus - .getHandler(ImportFromDistanceSpeedAction.class); - - public ImportFromDistanceSpeedAction() { - super("New from Distance Speed Tool"); - } - - @Override - public void run() { - VizApp.runSync(new Runnable() { - @Override - public void run() { - DamagePathLayer layer = (DamagePathLayer) getSelectedRsc(); - DistanceSpeedLayer dsLayer = findImportLayer(layer); - - // The Distance Speed tool has not been loaded. - if (dsLayer == null) { - return; - } - - Polygon polygon = DamagePathUtils.estimateDamagePath(dsLayer); - - if (polygon != null) { - layer.addPolygon(polygon.getExteriorRing().getCoordinates()); - } - } - }); - } - - /** - * Returns true iff super.isEnabled() is true and the DistanceSpeed tool is - * loaded, false otherwise. - */ - @Override - public boolean isEnabled() { - AbstractVizResource rsc = getSelectedRsc(); - boolean enabled = rsc.getCapability(EditableCapability.class) - .isEditable(); - if (enabled) { - if (rsc != null) { - enabled = findImportLayer(rsc) != null; - } - } - return enabled; - } - - /** - * Finds the DistanceSpeedLayer. - * - * @param rsc - * The current resource - * @return The found DistanceSpeedLayer, or null if the tool is not loaded. - */ - private DistanceSpeedLayer findImportLayer(AbstractVizResource rsc) { - ResourceList resources = rsc.getDescriptor().getResourceList(); - for (ResourcePair rp : resources) { - if (rp.getResource() instanceof DistanceSpeedLayer) { - return (DistanceSpeedLayer) rp.getResource(); - } - } - return null; - } -} diff --git a/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/NewTornadoDamagePathAction.java b/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/NewTornadoDamagePathAction.java new file mode 100644 index 0000000000..6d66f7b9c8 --- /dev/null +++ b/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/NewTornadoDamagePathAction.java @@ -0,0 +1,220 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.damagepath; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IMenuCreator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Menu; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.viz.core.VizApp; +import com.raytheon.uf.viz.core.drawables.ResourcePair; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.ResourceList; +import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability; +import com.raytheon.viz.awipstools.ui.layer.InteractiveBaselinesLayer; +import com.raytheon.viz.awipstools.ui.layer.InteractiveBaselinesLayer.Baseline; +import com.raytheon.viz.ui.cmenu.AbstractRightClickAction; +import com.vividsolutions.jts.geom.Polygon; + +/** + * Action to create a tornado damage path from an InteractiveBaselineLayer. + * + * Adds a menu item to the DamagePath's legend right-click menu which has a + * submenu to select one of the available baselines. + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 23, 2015 3977       nabowle     Initial creation
+ * Jun 01, 2015 3975       dgilling    Update for DamageLayer changes for
+ *                                     multiple polygon support.
+ * Jun 18, 2015 4354       dgilling    Update isEnabled to consider editable
+ *                                     capability.
+ * Jun 19, 2015 3977       nabowle     Specify Tornado Path.
+ * Jun 23, 2015 3977       nabowle     Switch to InteractiveBaselineLayer.
+ *                                     Renamed from ImportFromDistanceSpeedAction.
+ * 
+ * + * @author nabowle + * @version 1.0 + */ + +public class NewTornadoDamagePathAction extends AbstractRightClickAction + implements IMenuCreator { + + protected static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(NewTornadoDamagePathAction.class); + + private Menu menu; + + public NewTornadoDamagePathAction() { + super("New Tornado Path from Baseline", SWT.DROP_DOWN); + } + + @Override + public Menu getMenu(Control parent) { + if (menu != null) { + menu.dispose(); + } + + menu = new Menu(parent); + createMenu(menu); + + return menu; + } + + @Override + public void dispose() { + if (menu != null) { + menu.dispose(); + } + } + + @Override + public Menu getMenu(Menu parent) { + if (menu != null) { + menu.dispose(); + } + + createMenu(parent); + + return menu; + } + + @Override + public IMenuCreator getMenuCreator() { + return this; + } + + /** + * Creates a submenu with every displayed baseline, listed in alphabetical + * order. + * + * @param parent + */ + private void createMenu(Menu parent) { + menu = new Menu(parent); + InteractiveBaselinesLayer ibl = findImportLayer(getSelectedRsc()); + if (ibl == null || ibl.getCurrentBaselines() == null) { + return; + } + List baselines = new ArrayList<>(Arrays.asList(ibl + .getCurrentBaselines())); + Collections.sort(baselines, new Comparator() { + @Override + public int compare(Baseline b1, Baseline b2) { + return b1.name.compareTo(b2.name); + } + }); + + for (Baseline baseline : baselines) { + ActionContributionItem aci = new ActionContributionItem( + new ImportFromBaselineInternalAction(baseline)); + aci.fill(menu, -1); + } + } + + + @Override + public boolean isEnabled() { + AbstractVizResource rsc = getSelectedRsc(); + boolean enabled = rsc.getCapability(EditableCapability.class) + .isEditable(); + if (enabled) { + if (rsc != null) { + enabled = findImportLayer(rsc) != null; + } + } + return enabled; + } + + /** + * Finds the import layer. + * + * @param rsc + * The current resource + * @return The found import layer, or null if the tool is not loaded. + */ + private InteractiveBaselinesLayer findImportLayer( + AbstractVizResource rsc) { + ResourceList resources = rsc.getDescriptor().getResourceList(); + for (ResourcePair rp : resources) { + if (rp.getResource() instanceof InteractiveBaselinesLayer) { + return (InteractiveBaselinesLayer) rp.getResource(); + } + } + return null; + } + + /** + * Submenu actions for each available baseline. + * + * Each action is created with one of the available baselines, which when + * run will generate a Tornado damage path for that baseline. + */ + private class ImportFromBaselineInternalAction extends Action { + final Baseline baseline; + + public ImportFromBaselineInternalAction(Baseline line) { + super(line.name, Action.AS_PUSH_BUTTON); + this.baseline = line; + } + + @Override + public void run() { + VizApp.runSync(new Runnable() { + @Override + public void run() { + DamagePathLayer layer = (DamagePathLayer) getSelectedRsc(); + + Polygon polygon = DamagePathUtils + .estimateTornadoDamagePath(baseline); + + if (polygon != null) { + layer.addPolygon(polygon.getExteriorRing() + .getCoordinates()); + } + } + }); + + getContainer().refresh(); + } + + @Override + public String getText() { + return baseline.name; + } + + } +} diff --git a/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/OpenGeoJsonPropertiesDlgAction.java b/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/OpenGeoJsonPropertiesDlgAction.java index e74b260faf..ddfdf7bfbc 100644 --- a/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/OpenGeoJsonPropertiesDlgAction.java +++ b/cave/com.raytheon.uf.viz.damagepath/src/com/raytheon/uf/viz/damagepath/OpenGeoJsonPropertiesDlgAction.java @@ -41,6 +41,7 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback; * Jun 09, 2015 #4355 dgilling Rename action for UI. * Jun 18, 2015 #4354 dgilling Allow individual properties object for * each polygon. + * Jun 30, 2015 #4354 dgilling Fix NullPointerException. * * * @@ -65,7 +66,6 @@ public class OpenGeoJsonPropertiesDlgAction extends AbstractRightClickAction { Shell shell = VizWorkbenchManager.getInstance() .getCurrentWindow().getShell(); - final DamagePathLayer layer = (DamagePathLayer) getSelectedRsc(); final Map geoJsonProps = damagePath .getProperties(); EditGeoJsonPropertiesDlg dlg = new EditGeoJsonPropertiesDlg( @@ -78,7 +78,6 @@ public class OpenGeoJsonPropertiesDlgAction extends AbstractRightClickAction { && (!geoJsonProps.equals(returnValue))) { Map updatedProperties = (Map) returnValue; damagePath.setProperties(updatedProperties); - layer.scheduleSaveJob(); } } }); diff --git a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/DIRC.xml b/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/DIRC.xml deleted file mode 100644 index ee280da415..0000000000 --- a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/DIRC.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - diff --git a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/LTNG.xml b/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/LTNG.xml deleted file mode 100644 index 688297a9d2..0000000000 --- a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/LTNG.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - diff --git a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/MXDVV.xml b/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/MXDVV.xml deleted file mode 100644 index be8fa65f36..0000000000 --- a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/MXDVV.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - diff --git a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/MXREF.xml b/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/MXREF.xml deleted file mode 100644 index b0d7bcd510..0000000000 --- a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/MXREF.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - diff --git a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/MXUPHL.xml b/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/MXUPHL.xml deleted file mode 100644 index fc076df656..0000000000 --- a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/MXUPHL.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - diff --git a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/MXUVV.xml b/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/MXUVV.xml deleted file mode 100644 index a102178086..0000000000 --- a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/MXUVV.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - diff --git a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/OGRD.xml b/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/OGRD.xml deleted file mode 100644 index 76c03bf1af..0000000000 --- a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/OGRD.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - diff --git a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/SPC.xml b/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/SPC.xml deleted file mode 100644 index b1062e53fc..0000000000 --- a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/SPC.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - diff --git a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/WGS1hr.xml b/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/WGS1hr.xml deleted file mode 100644 index c86c8edbb4..0000000000 --- a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/WGS1hr.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/cave/com.raytheon.uf.viz.drawing/src/com/raytheon/uf/viz/drawing/polygon/DrawablePolygon.java b/cave/com.raytheon.uf.viz.drawing/src/com/raytheon/uf/viz/drawing/polygon/DrawablePolygon.java index 24520599c4..9c90266772 100644 --- a/cave/com.raytheon.uf.viz.drawing/src/com/raytheon/uf/viz/drawing/polygon/DrawablePolygon.java +++ b/cave/com.raytheon.uf.viz.drawing/src/com/raytheon/uf/viz/drawing/polygon/DrawablePolygon.java @@ -51,6 +51,8 @@ import com.vividsolutions.jts.geom.Polygon; * ------------ ---------- ----------- -------------------------- * May 27, 2015 #4375 dgilling Initial creation * Jun 18, 2015 #4354 dgilling Correct behavior of project. + * Jun 30, 2015 #4354 dgilling Make PolygonLayer visible to + * subclasses. * * * @@ -69,7 +71,10 @@ public class DrawablePolygon implements IRenderable2 { private final Object lock; - private final PolygonLayer polygonLayer; + /** + * The PolygonLayer this polygon is attached to. + */ + protected final PolygonLayer polygonLayer; public DrawablePolygon(PolygonLayer polygonLayer) { this.lock = new Object(); diff --git a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/DeleteAction.java b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/DeleteAction.java index 52bfc0fb4a..70f69dc755 100644 --- a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/DeleteAction.java +++ b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/DeleteAction.java @@ -54,6 +54,7 @@ import com.raytheon.uf.viz.localization.perspective.editor.LocalizationEditorInp * ------------ ---------- ----------- -------------------------- * Nov 3, 2010 mschenke Initial creation * Feb 18, 2015 4132 mapeters Fixed issue with deleting overrides. + * Jun 29, 2015 946 rferrel Do not allow delete of a protected level file. * * * @@ -216,6 +217,10 @@ public class DeleteAction extends Action { canDelete = false; break; } + if (file.isProtected() && file.getProtectedLevel().equals(level)) { + canDelete = false; + break; + } } return canDelete; } diff --git a/cave/com.raytheon.uf.viz.product.alertviz/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.product.alertviz/META-INF/MANIFEST.MF index 8bd0f1d0e2..d6c3567ca3 100644 --- a/cave/com.raytheon.uf.viz.product.alertviz/META-INF/MANIFEST.MF +++ b/cave/com.raytheon.uf.viz.product.alertviz/META-INF/MANIFEST.MF @@ -14,3 +14,4 @@ Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Import-Package: com.raytheon.uf.common.message Export-Package: com.raytheon.uf.viz.product.alertviz +Bundle-Localization: plugin diff --git a/cave/com.raytheon.uf.viz.product.alertviz/build.properties b/cave/com.raytheon.uf.viz.product.alertviz/build.properties index e9863e281e..0dc34f7833 100644 --- a/cave/com.raytheon.uf.viz.product.alertviz/build.properties +++ b/cave/com.raytheon.uf.viz.product.alertviz/build.properties @@ -2,4 +2,5 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ - plugin.xml + plugin.xml,\ + plugin.properties diff --git a/cave/com.raytheon.uf.viz.product.alertviz/plugin.properties b/cave/com.raytheon.uf.viz.product.alertviz/plugin.properties new file mode 100644 index 0000000000..7c11021eec --- /dev/null +++ b/cave/com.raytheon.uf.viz.product.alertviz/plugin.properties @@ -0,0 +1 @@ +caveVersion=DEVELOPMENT \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.product.alertviz/plugin.xml b/cave/com.raytheon.uf.viz.product.alertviz/plugin.xml index 93d10fa41a..9184b6109b 100644 --- a/cave/com.raytheon.uf.viz.product.alertviz/plugin.xml +++ b/cave/com.raytheon.uf.viz.product.alertviz/plugin.xml @@ -42,6 +42,9 @@ name="appName" value="alertviz">
+ diff --git a/cave/com.raytheon.uf.viz.thinclient.cave/build.properties b/cave/com.raytheon.uf.viz.thinclient.cave/build.properties index 43d52e27ca..aae76abb0a 100644 --- a/cave/com.raytheon.uf.viz.thinclient.cave/build.properties +++ b/cave/com.raytheon.uf.viz.thinclient.cave/build.properties @@ -2,5 +2,6 @@ output.com.raytheon.uf.viz.thinclient.cave.jar = bin/ bin.includes = META-INF/,\ plugin.xml,\ ThinClientPluginBlacklist.txt,\ - com.raytheon.uf.viz.thinclient.cave.jar + com.raytheon.uf.viz.thinclient.cave.jar,\ + logback-viz-thinclient.xml source.com.raytheon.uf.viz.thinclient.cave.jar = src/ diff --git a/cave/com.raytheon.uf.viz.thinclient.cave/src/com/raytheon/uf/viz/thinclient/cave/ThinClientComponent.java b/cave/com.raytheon.uf.viz.thinclient.cave/src/com/raytheon/uf/viz/thinclient/cave/ThinClientComponent.java index 82472b50b8..98d6a39fd9 100644 --- a/cave/com.raytheon.uf.viz.thinclient.cave/src/com/raytheon/uf/viz/thinclient/cave/ThinClientComponent.java +++ b/cave/com.raytheon.uf.viz.thinclient.cave/src/com/raytheon/uf/viz/thinclient/cave/ThinClientComponent.java @@ -27,9 +27,11 @@ import java.util.List; import org.eclipse.jface.preference.IPreferenceStore; import org.osgi.framework.Bundle; +import org.osgi.framework.FrameworkUtil; import com.raytheon.uf.common.comm.HttpClient; import com.raytheon.uf.common.datastorage.DataStoreFactory; +import com.raytheon.uf.common.localization.IPathManager; import com.raytheon.uf.common.localization.PathManagerFactory; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; @@ -72,6 +74,7 @@ import com.raytheon.viz.ui.personalities.awips.CAVE; * Nov 06, 2014 3356 njensen Always initialize ILocalizationAdapter * in case cache preference is not enabled * Feb 23, 2015 4164 dlovely Call AlertViz initialize. + * Jun 26, 2015 4474 bsteffen Register the PathManager as an OSGi service. * * * @@ -185,6 +188,11 @@ public class ThinClientComponent extends CAVE implements IThinClientComponent { statusHandler.handle(Priority.CRITICAL, "Error setting up localization", e1); } + FrameworkUtil + .getBundle(getClass()) + .getBundleContext() + .registerService(IPathManager.class, + PathManagerFactory.getPathManager(), null); } /* diff --git a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/EditorTafTabComp.java b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/EditorTafTabComp.java index 7382bed6d4..bdd975ed7d 100644 --- a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/EditorTafTabComp.java +++ b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/EditorTafTabComp.java @@ -25,7 +25,6 @@ import java.util.HashMap; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ExtendedModifyEvent; import org.eclipse.swt.custom.ExtendedModifyListener; -import org.eclipse.swt.custom.ST; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.custom.VerifyKeyListener; import org.eclipse.swt.events.DisposeEvent; @@ -75,6 +74,7 @@ import com.raytheon.viz.aviation.resource.ResourceConfigMgr.ResourceTag; * 1/17/2011 7782 rferrel Added qcSkipCheck to mimic A1. * 3/18/2011 7888 rferrel Added getLargeTF method. * 02/19/2014 16980 zhao added getter and setter for the Alt flag + * 06/27/2015 4588 skorolev Removed unnecessary insert toggle. * * * @@ -380,22 +380,6 @@ public class EditorTafTabComp extends Composite { createCaretImage(insertWidth, size.y); caret.setImage(caretImage); tafEditorTxt.setCaret(caret); - - /* - * NOTE: - * - * The following code sets the TOGGLE_OVERWRITE for the text editor in - * the editor tabs. In the TafViewerEditorDlg, after the controls are - * initialized it is also set (if insert is false). Removing this code - * or the code in the TafViewerEditorDlg will cause the text editor - * control to not insert/overwrite properly. I do not understand why - * this is but that is why I am documenting this. This may be fixed in - * the future. --- L. Venable - */ - if (configMgr.getResourceAsBoolean(ResourceTag.Insert) == false) { - tafEditorTxt.invokeAction(ST.TOGGLE_OVERWRITE); - } - tafEditorTxt.addMouseListener(new MouseAdapter() { @Override @@ -1370,11 +1354,11 @@ public class EditorTafTabComp extends Composite { corRdo.setEnabled(editable); } - public boolean getAlt() { - return alt; - } + public boolean getAlt() { + return alt; + } - public void setAlt(boolean b) { - alt = b; - } + public void setAlt(boolean b) { + alt = b; + } } diff --git a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/TafViewerEditorDlg.java b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/TafViewerEditorDlg.java index 4db3ec5928..9ff076bcd1 100644 --- a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/TafViewerEditorDlg.java +++ b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/editor/TafViewerEditorDlg.java @@ -52,7 +52,6 @@ import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.custom.StyleRange; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.dnd.Clipboard; -import org.eclipse.swt.dnd.TextTransfer; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.MouseAdapter; @@ -241,7 +240,9 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback; * May 15, 2014 3002 bgonzale Moved common taf code to com.raytheon.uf.common.dataplugin.taf. * 08/13/2014 3497 njensen Refactored syntax checking to prevent potential infinite loop * 12/02/2014 #15007 zhao Added restoreFrom() for the "Restore From..." menu option - * 04/07/2015 17332 zhao Added code to handle case of "Cancel" in "Restore From..." + * 04/07/2015 17332 zhao Added code to handle case of "Cancel" in "Restore From..." + * 06/23/2015 2282 skorolev Corrected "CLEAR" case in updateSettings. + * 06/26/2015 4588 skorolev Fixed Insert/Overwrite issue. * * * @@ -427,11 +428,6 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, */ private Color fltCatFontColor; - /** - * Flag indicating if the editor is in overwrite mode. - */ - private boolean overwriteMode = false; - /** * Indicator of viewer tab selected. */ @@ -450,7 +446,7 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, /** * The list of Viewer tabs configured for display. */ - private List modelsTabs = new ArrayList(); + private final List modelsTabs = new ArrayList(); /** * Current active Viewer tab. @@ -505,7 +501,7 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, /** * The station list. */ - private List stationList; + private final List stationList; /** * Saved state of the QC check items @@ -580,12 +576,6 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, return; } - // If the disposeOnExit is true then return since this dialog - // will be modal and we can't prevent the dialog from disposing. - // if (disposeOnExit == true) { - // return; - // } - // Block the disposal of this dialog. hideDialog(); event.doit = false; @@ -631,27 +621,6 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, // Initialize all of the controls and layouts initializeComponents(); - /* - * NOTE: - * - * The following code sets the TOGGLE_OVERWRITE for the text editors in - * the editor tabs. In the EditorTafTabComp, when the text controls are - * created it is also set (if insert is false). Removing this code or - * the code in the EditorTafTabComp will cause the text editor control - * to not insert/overwrite properly. I do not understand why this is but - * that is why I am documenting this. This may be fixed in the future. - * --- L. Venable - */ - - if (configMgr.getResourceAsBoolean(ResourceTag.Insert) == false) { - for (TabItem editTafTabItem : editorTafTabs) { - EditorTafTabComp tafTabComp = (EditorTafTabComp) editTafTabItem - .getControl(); - tafTabComp.getTextEditorControl().invokeAction( - ST.TOGGLE_OVERWRITE); - } - } - confirmSend = configMgr.getDataAsBoolean(ResourceTag.ConfirmSend); disallowSend = configMgr.getDataAsString(ResourceTag.DisallowSend); } @@ -756,7 +725,7 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, editorTafTabComp.setWmoIdLbl(""); editorTafTabComp.setWmoSiteLbl(""); editorTafTabComp.setLargeTF(""); - editorTafTabComp.setSmallTF(""); + // editorTafTabComp.setSmallTF(""); editorTafTabComp.getTextEditorControl().setText(""); if (editorTafTabComp.isTafSent()) { editorTafTabComp.updateTafSent(false); @@ -1116,8 +1085,6 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, printMI.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { - // PrintDialog pd = new PrintDialog(shell); - // pd.open(); printAllText(); } }); @@ -2096,7 +2063,7 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, return editorComp; } - /** + /** * Check if there is an extra '=' sign in a TAF * * @param doLogMessage @@ -2113,7 +2080,7 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, st = editorTafTabComp.getTextEditorControl(); in = in.toUpperCase().replaceAll("TAF", "\n\nTAF").trim(); - while ( in.contains("\n\n\n") ) { + while (in.contains("\n\n\n")) { in = in.replace("\n\n\n", "\n\n"); } @@ -2153,29 +2120,33 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, String msg = "Syntax error: There is an extra '=' sign or 'TAF' is missing at beginning of TAF"; String[] tafs = in.split("\n\n"); int tafStartIndex = 0; - for ( String taf : tafs ) { + for (String taf : tafs) { int firstEqualSignIndex = taf.indexOf('='); - if ( firstEqualSignIndex == -1 ) { + if (firstEqualSignIndex == -1) { tafStartIndex += taf.length() + 2; continue; } - int secondEqualSignIndex = taf.indexOf('=', firstEqualSignIndex+1); - if ( secondEqualSignIndex == -1 ) { + int secondEqualSignIndex = taf + .indexOf('=', firstEqualSignIndex + 1); + if (secondEqualSignIndex == -1) { tafStartIndex += taf.length() + 2; continue; } - while ( secondEqualSignIndex > -1 ) { - int secondEqualSignIndexInEditorText = tafStartIndex + secondEqualSignIndex; - StyleRange sr = new StyleRange(secondEqualSignIndexInEditorText, 1, null, qcColors[3]); + while (secondEqualSignIndex > -1) { + int secondEqualSignIndexInEditorText = tafStartIndex + + secondEqualSignIndex; + StyleRange sr = new StyleRange( + secondEqualSignIndexInEditorText, 1, null, qcColors[3]); syntaxMap.put(sr, msg); st.setStyleRange(sr); - secondEqualSignIndex = taf.indexOf('=', secondEqualSignIndex+1); + secondEqualSignIndex = taf.indexOf('=', + secondEqualSignIndex + 1); } errorFound = true; tafStartIndex += taf.length() + 2; } - if ( doLogMessage ) { + if (doLogMessage) { msgStatComp.setMessageText(msg, qcColors[3].getRGB()); } @@ -2344,7 +2315,7 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, gd = new GridData(SWT.FILL, SWT.FILL, true, true); guidanceViewerFolder = new TabFolder(guidanceViewerComp, SWT.NONE); guidanceViewerFolder.setLayoutData(gd); - guidanceViewerFolder.addSelectionListener(new SelectionListener() { + guidanceViewerFolder.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { @@ -2366,12 +2337,6 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, currentTab.markTextAsUpdating(); } } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - // TODO Auto-generated method stub - System.out.println("default selection listener event: " + e); - } }); configMgr.setDefaultColors(guidanceViewerFolder); @@ -2503,24 +2468,25 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, } } } - + /** * restore from a file a user selects */ private void restoreFrom() { - - if ( tabFolder.getSelectionIndex() == VIEWER_TAB_SELECTED ) { + + if (tabFolder.getSelectionIndex() == VIEWER_TAB_SELECTED) { tabFolder.setSelection(editorTab); } - + String tempTafPath = "aviation/tmp/"; IPathManager pm = PathManagerFactory.getPathManager(); - LocalizationContext context = pm.getContext(LocalizationType.CAVE_STATIC, LocalizationLevel.SITE); + LocalizationContext context = pm.getContext( + LocalizationType.CAVE_STATIC, LocalizationLevel.SITE); String path = pm.getFile(context, tempTafPath).getAbsolutePath(); FileDialog dlg = new FileDialog(shell, SWT.OPEN); dlg.setFilterPath(path); String filepath = dlg.open(); - if ( filepath == null ) { // if "Cancel"; do nothing + if (filepath == null) { // if "Cancel"; do nothing return; } @@ -2582,7 +2548,8 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, } catch (FileNotFoundException e) { setMessageStatusError("File " + filepath + " not found."); } catch (IOException e) { - setMessageStatusError("An IOException occured while opening file " + filepath); + setMessageStatusError("An IOException occured while opening file " + + filepath); } finally { if (errorMsg != null) { setMessageStatusError("File " + filepath + ": " + errorMsg); @@ -2864,30 +2831,7 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, public void pasteText() { if (tabFolder.getSelectionIndex() != VIEWER_TAB_SELECTED) { // Assume editorTafTabComp is for the active tab. - if (overwriteMode == false) { - editorTafTabComp.getTextEditorControl().paste(); - } else if (overwriteMode == true - && editorTafTabComp.getTextEditorControl().getCaretOffset() < editorTafTabComp - .getTextEditorControl().getCharCount()) { - - editorTafTabComp.getTextEditorControl().replaceTextRange( - editorTafTabComp.getTextEditorControl() - .getCaretOffset(), - ((String) (clipboard).getContents(TextTransfer - .getInstance())).length(), - (String) (clipboard).getContents(TextTransfer - .getInstance())); - - editorTafTabComp.getTextEditorControl() - .setCaretOffset( - editorTafTabComp.getTextEditorControl() - .getCaretOffset() - + ((String) (clipboard) - .getContents(TextTransfer - .getInstance())) - .length()); - - } + editorTafTabComp.getTextEditorControl().paste(); } } @@ -3026,7 +2970,6 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, st.setStyleRange(null); syntaxMap.clear(); - /* * TODO Refactor all of this to be smarter. Right now it's kind of dumb * in that the python syntax check can potentially alter the datetime of @@ -3529,7 +3472,6 @@ public class TafViewerEditorDlg extends CaveSWTDialog implements ITafSettable, // Change the state of the insert check insertChk.setSelection(!(insertChk.getSelection())); } - // Loop and set all of the editors to the update insert state for (TabItem editTafTabItem : editorTafTabs) { EditorTafTabComp tafTabComp = (EditorTafTabComp) editTafTabItem diff --git a/cave/com.raytheon.viz.feature.awips.developer/feature.xml b/cave/com.raytheon.viz.feature.awips.developer/feature.xml index 364a60621d..0fe75c167d 100644 --- a/cave/com.raytheon.viz.feature.awips.developer/feature.xml +++ b/cave/com.raytheon.viz.feature.awips.developer/feature.xml @@ -201,6 +201,10 @@ id="gov.noaa.gsd.viz.hazards.feature" version="0.0.0"/> + + diff --git a/cave/com.raytheon.viz.gfe/localization/gfe/itool/TextProductTest.py b/cave/com.raytheon.viz.gfe/localization/gfe/itool/TextProductTest.py index 66ad88ac64..cb4e199ad1 100644 --- a/cave/com.raytheon.viz.gfe/localization/gfe/itool/TextProductTest.py +++ b/cave/com.raytheon.viz.gfe/localization/gfe/itool/TextProductTest.py @@ -277,7 +277,8 @@ import ProcessVariableList from com.raytheon.viz.gfe.textformatter import TextProductFinishWaiter, FormatterUtil, TextProductManager from com.raytheon.viz.gfe.smarttool import TextFileUtil -from com.raytheon.viz.gfe.dialogs.formatterlauncher import ConfigData_ProductStateEnum as ProductStateEnum +from com.raytheon.viz.gfe.dialogs.formatterlauncher import ConfigData +ProductStateEnum = ConfigData.ProductStateEnum class ProcessInfo: def __init__(self, entry, name, pid, script): diff --git a/cave/com.raytheon.viz.gfe/localization/gfe/userPython/gfeConfig/gfeConfig.py b/cave/com.raytheon.viz.gfe/localization/gfe/userPython/gfeConfig/gfeConfig.py index ed9fe2aa95..efd064b248 100644 --- a/cave/com.raytheon.viz.gfe/localization/gfe/userPython/gfeConfig/gfeConfig.py +++ b/cave/com.raytheon.viz.gfe/localization/gfe/userPython/gfeConfig/gfeConfig.py @@ -33,9 +33,6 @@ # 05/28/2014 2841 randerso Added separate configurable limits for # text formatter and product script tasks # 02/04/2015 17039 ryu Removed HighlightFramingCodes setting. -# 06/15/2015 4422 dgilling Add default color-mappings for -# simulated satellite parms. -# GFESUITE_HOME = "/awips2/GFESuite" GFESUITE_PRDDIR = "/tmp/products" @@ -1182,10 +1179,6 @@ ir11West_defaultColorTable = "Sat/IR/CIRA (IR Default)" ir13West_defaultColorTable = "Sat/IR/CIRA (IR Default)" ir39West_defaultColorTable = "Sat/IR/CIRA (IR Default)" waterVaporWest_defaultColorTable = "Sat/WV/Gray Scale Water Vapor" -SBT124_defaultColorTable = "Sat/IR/CIRA (IR Default)" -SBT125_defaultColorTable = "Sat/IR/CIRA (IR Default)" -SBT122_defaultColorTable = "Sat/IR/CIRA (IR Default)" -SBT123_defaultColorTable = "Sat/WV/Gray Scale Water Vapor" VisibleE_defaultColorTable = "Sat/VIS/ZA (Vis Default)" IR11E_defaultColorTable = "Sat/IR/CIRA (IR Default)" @@ -1208,12 +1201,6 @@ IR39W_defaultColorTable = "Sat/IR/CIRA (IR Default)" WaterVaporW_defaultColorTable = "Sat/WV/Gray Scale Water Vapor" FogW_defaultColorTable = "Sat/WV/Gray Scale Water Vapor" -IR11_defaultColorTable = "Sat/IR/CIRA (IR Default)" -IR13_defaultColorTable = "Sat/IR/CIRA (IR Default)" -IR39_defaultColorTable = "Sat/IR/CIRA (IR Default)" -WaterVapor_defaultColorTable = "Sat/WV/Gray Scale Water Vapor" -Fog_defaultColorTable = "Sat/WV/Gray Scale Water Vapor" - Hazards_defaultColorTable = "GFE/Hazards" # Start HTI entries diff --git a/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/resource/MultiPointResource.java b/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/resource/MultiPointResource.java index 46ebf55e00..19e2728ddc 100644 --- a/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/resource/MultiPointResource.java +++ b/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/resource/MultiPointResource.java @@ -131,6 +131,7 @@ import com.vividsolutions.jts.index.strtree.STRtree; * Feb 02, 2015 4075 ccody Added getSelectedGage for HS issue #3961 * Mar 09, 2015 13998 lbousaidi changed the dur display when it is null to match A1. * Apr 09, 2015 4215 mpduff Check strTree before removing items. + * Jul 06, 2015 4215 mpduff Correct the fact that user's cannot click and view time series. * * * @@ -344,21 +345,21 @@ public class MultiPointResource extends */ private synchronized void addPoint(GageData gage) { String lid = gage.getLid(); - GageData existingGage = dataMap.get(lid); - Coordinate xy = new Coordinate(gage.getLon(), gage.getLat()); - gage.setCoordinate(xy); + GageData existing = dataMap.get(lid); + if (gage != existing) { + Coordinate xy = new Coordinate(gage.getLon(), gage.getLat()); + gage.setCoordinate(xy); - if (existingGage != null && existingGage != gage) { - PixelExtent pe = getPixelExtent(existingGage, - getShiftWidth(existingGage), getShiftHeight(existingGage)); - Envelope oldEnv = descriptor.pixelToWorld(pe); - List list = strTree.query(oldEnv); - if (list != null && !list.isEmpty()) { - strTree.remove(oldEnv, existingGage); + if (existing != null) { + PixelExtent pe = getPixelExtent(existing, + getShiftWidth(existing), getShiftHeight(existing)); + Envelope oldEnv = descriptor.pixelToWorld(pe); + strTree.remove(oldEnv, existing); } /* Create a small envelope around the point */ - pe = getPixelExtent(gage, getShiftWidth(gage), getShiftHeight(gage)); + PixelExtent pe = getPixelExtent(gage, getShiftWidth(gage), + getShiftHeight(gage)); Envelope newEnv = descriptor.pixelToWorld(pe); strTree.insert(newEnv, gage); diff --git a/cave/com.raytheon.viz.product.awips/developer.product b/cave/com.raytheon.viz.product.awips/developer.product index 0cdd2eedf0..00214d6a9f 100644 --- a/cave/com.raytheon.viz.product.awips/developer.product +++ b/cave/com.raytheon.viz.product.awips/developer.product @@ -65,10 +65,10 @@ + + - - diff --git a/cave/com.raytheon.viz.product.awips/plugin.properties b/cave/com.raytheon.viz.product.awips/plugin.properties index 28543fe0bc..949156c811 100644 --- a/cave/com.raytheon.viz.product.awips/plugin.properties +++ b/cave/com.raytheon.viz.product.awips/plugin.properties @@ -2,3 +2,4 @@ caveAboutText=Common AWIPS Visualization Environment (CAVE)\n\ \n\ Developed on the Raytheon Visualization Environment (viz)\n\ \t~ DEVELOPMENT ~ +caveVersion=DEVELOPMENT \ No newline at end of file diff --git a/cave/com.raytheon.viz.product.awips/plugin.xml b/cave/com.raytheon.viz.product.awips/plugin.xml index 82db54a5e1..b7674ad6d7 100644 --- a/cave/com.raytheon.viz.product.awips/plugin.xml +++ b/cave/com.raytheon.viz.product.awips/plugin.xml @@ -31,6 +31,9 @@ + diff --git a/cave/com.raytheon.viz.product.awips/thinclient.product b/cave/com.raytheon.viz.product.awips/thinclient.product new file mode 100644 index 0000000000..f2b9610876 --- /dev/null +++ b/cave/com.raytheon.viz.product.awips/thinclient.product @@ -0,0 +1,120 @@ + + + + + + + + + %caveAboutText + + + + + + + + -data @user.home/caveData -user @user.home/caveData -alertviz + -consoleLog + -XX:+UseG1GC +-Dosgi.instance.area.readOnly=true +-Dorg.eclipse.update.reconcile=false +-XX:MaxPermSize=128m +-Dorg.eclipse.ui/KEY_CONFIGURATION_ID=com.raytheon.viz.ui.awips.scheme +-Dqpid.dest_syntax=BURL +-Dlogback.configurationFile=logback-viz-alertview.xml +-Dlogback.statusListenerClass=com.raytheon.uf.common.logback.UFLogbackInternalStatusListener +-Dthrift.stream.maxsize=200 +-Dviz.memory.warn.threshold=98 +-Dhttps.certificate.check=false +-XX:+UnlockExperimentalVMOptions +-XX:G1HeapRegionSize=4M +-XX:InitiatingHeapOccupancyPercent=25 +-XX:G1MixedGCCountTarget=16 +-XX:G1MixedGCLiveThresholdPercent=25 +-XX:G1OldCSetRegionThresholdPercent=25 +-XX:G1HeapWastePercent=5 + -Dfile.encoding=UTF-8 -Xmx2560M + + + + + + + + + + + + + + jdk1.6.0 + jdk1.6.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cave/com.raytheon.viz.redbook/src/com/raytheon/viz/redbook/rsc/RedbookFrame.java b/cave/com.raytheon.viz.redbook/src/com/raytheon/viz/redbook/rsc/RedbookFrame.java index 493b2097c2..7569724fed 100644 --- a/cave/com.raytheon.viz.redbook/src/com/raytheon/viz/redbook/rsc/RedbookFrame.java +++ b/cave/com.raytheon.viz.redbook/src/com/raytheon/viz/redbook/rsc/RedbookFrame.java @@ -36,6 +36,7 @@ import org.opengis.referencing.datum.PixelInCell; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.TransformException; +import com.raytheon.uf.common.dataplugin.redbook.RedbookWMOMap; import com.raytheon.uf.common.dataplugin.redbook.blocks.Block_004_016; import com.raytheon.uf.common.dataplugin.redbook.blocks.DefaultBlock; import com.raytheon.uf.common.dataplugin.redbook.blocks.RedbookBlockBuilder; @@ -65,7 +66,6 @@ import com.raytheon.uf.viz.core.map.IMapDescriptor; import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability; import com.raytheon.uf.viz.core.rsc.capabilities.OutlineCapability; import com.raytheon.viz.core.rsc.jts.JTSCompiler; -import com.raytheon.viz.redbook.RedbookWMOMap; import com.raytheon.viz.redbook.blocks.AbstractTextBlock; import com.raytheon.viz.redbook.blocks.AlphaNumBlock; import com.raytheon.viz.redbook.blocks.PlotDataBlock; @@ -95,6 +95,7 @@ import com.vividsolutions.jts.geom.Coordinate; * Mar 13, 2014 2907 njensen split edex.redbook plugin into common * and edex redbook plugins * Apr 10, 2014 1803 njensen Fix dispose() for collaboration + * Jun 26, 2015 4512 mapeters Updated for RedbookWMOMap API changes * * * @@ -209,12 +210,11 @@ public class RedbookFrame implements IRenderable { .getResourceData().getMetadataMap() .get("wmoTTAAii"); if (wmo != null) { - RedbookWMOMap.Info info = RedbookWMOMap.load().mapping - .get(wmo.getConstraintValue()); + RedbookWMOMap.Info info = RedbookWMOMap.load() + .getValue(wmo.getConstraintValue()); if (info != null) { - customProjection = info.projection; // may - // be - // null + // projection may be null + customProjection = info.projection; } } } catch (Exception e) { diff --git a/cave/com.raytheon.viz.redbook/src/com/raytheon/viz/redbook/rsc/RedbookProductBrowserDataDefinition.java b/cave/com.raytheon.viz.redbook/src/com/raytheon/viz/redbook/rsc/RedbookProductBrowserDataDefinition.java index b578eec134..821ab36b71 100644 --- a/cave/com.raytheon.viz.redbook/src/com/raytheon/viz/redbook/rsc/RedbookProductBrowserDataDefinition.java +++ b/cave/com.raytheon.viz.redbook/src/com/raytheon/viz/redbook/rsc/RedbookProductBrowserDataDefinition.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import com.raytheon.uf.common.dataplugin.redbook.RedbookWMOMap; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; @@ -32,7 +33,6 @@ import com.raytheon.uf.viz.productbrowser.AbstractRequestableProductBrowserDataD import com.raytheon.uf.viz.productbrowser.ProductBrowserLabel; import com.raytheon.uf.viz.productbrowser.ProductBrowserPreference; import com.raytheon.uf.viz.productbrowser.ProductBrowserPreference.PreferenceType; -import com.raytheon.viz.redbook.RedbookWMOMap; import com.raytheon.viz.redbookua.rsc.RedbookUpperAirResourceData; /** @@ -43,7 +43,8 @@ import com.raytheon.viz.redbookua.rsc.RedbookUpperAirResourceData; * SOFTWARE HISTORY * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * May 17, 2010 mnash Initial creation + * May 17, 2010 mnash Initial creation + * Jun 26, 2015 4512 mapeters Updated for RedbookWMOMap API changes * * * @@ -92,7 +93,7 @@ public class RedbookProductBrowserDataDefinition extends List labels = new ArrayList(); if ("wmoTTAAii".equals(param)) { for (int i = 0; i < parameters.length; i++) { - RedbookWMOMap.Info info = mapping.mapping.get(parameters[i]); + RedbookWMOMap.Info info = mapping.getValue(parameters[i]); if (info != null) { labels.add(new ProductBrowserLabel(info.name + " (" + parameters[i] + ")", parameters[i])); diff --git a/cave/com.raytheon.viz.redbook/src/com/raytheon/viz/redbook/rsc/RedbookResource.java b/cave/com.raytheon.viz.redbook/src/com/raytheon/viz/redbook/rsc/RedbookResource.java index b44d2b6ca1..d9d3913095 100644 --- a/cave/com.raytheon.viz.redbook/src/com/raytheon/viz/redbook/rsc/RedbookResource.java +++ b/cave/com.raytheon.viz.redbook/src/com/raytheon/viz/redbook/rsc/RedbookResource.java @@ -31,6 +31,7 @@ import org.opengis.referencing.crs.CoordinateReferenceSystem; import com.raytheon.uf.common.dataplugin.HDF5Util; import com.raytheon.uf.common.dataplugin.PluginDataObject; import com.raytheon.uf.common.dataplugin.redbook.RedbookRecord; +import com.raytheon.uf.common.dataplugin.redbook.RedbookWMOMap; import com.raytheon.uf.common.dataquery.requests.RequestConstraint; import com.raytheon.uf.common.datastorage.DataStoreFactory; import com.raytheon.uf.common.datastorage.IDataStore; @@ -50,7 +51,6 @@ import com.raytheon.uf.viz.core.rsc.AbstractVizResource; import com.raytheon.uf.viz.core.rsc.IResourceDataChanged; import com.raytheon.uf.viz.core.rsc.LoadProperties; import com.raytheon.uf.viz.core.rsc.capabilities.MagnificationCapability; -import com.raytheon.viz.redbook.RedbookWMOMap; import com.raytheon.viz.redbook.rsc.RedbookFrame.RedbookStatus; /** @@ -68,6 +68,7 @@ import com.raytheon.viz.redbook.rsc.RedbookFrame.RedbookStatus; * May 21, 2013 2001 njensen Fixed display of messages * Mar 13, 2014 2907 njensen split edex.redbook plugin into common * and edex redbook plugins + * Jun 26, 2015 4512 mapeters Updated for RedbookWMOMap API changes * * * @@ -155,7 +156,7 @@ public class RedbookResource extends if (wmoStr.isEmpty()) { continue; } - RedbookWMOMap.Info info = map.mapping.get(wmoStr); + RedbookWMOMap.Info info = map.getValue(wmoStr); if (info != null && info.name != null) { this.humanReadableName = info.name; break; diff --git a/cave/com.raytheon.viz.redbook/src/com/raytheon/viz/redbookua/rsc/RedbookUpperAirResource.java b/cave/com.raytheon.viz.redbook/src/com/raytheon/viz/redbookua/rsc/RedbookUpperAirResource.java index d6b59793ad..d4aa9b209d 100644 --- a/cave/com.raytheon.viz.redbook/src/com/raytheon/viz/redbookua/rsc/RedbookUpperAirResource.java +++ b/cave/com.raytheon.viz.redbook/src/com/raytheon/viz/redbookua/rsc/RedbookUpperAirResource.java @@ -37,6 +37,7 @@ import org.opengis.referencing.crs.CoordinateReferenceSystem; import com.raytheon.uf.common.dataplugin.HDF5Util; import com.raytheon.uf.common.dataplugin.PluginDataObject; import com.raytheon.uf.common.dataplugin.redbook.RedbookRecord; +import com.raytheon.uf.common.dataplugin.redbook.RedbookWMOMap; import com.raytheon.uf.common.dataquery.requests.RequestConstraint; import com.raytheon.uf.common.datastorage.DataStoreFactory; import com.raytheon.uf.common.datastorage.IDataStore; @@ -71,7 +72,6 @@ import com.raytheon.uf.viz.core.rsc.capabilities.MagnificationCapability; import com.raytheon.viz.pointdata.PlotData; import com.raytheon.viz.pointdata.PlotModelFactory; import com.raytheon.viz.redbook.Activator; -import com.raytheon.viz.redbook.RedbookWMOMap; import com.raytheon.viz.redbookua.RedbookUpperAirDecoder; import com.vividsolutions.jts.geom.Coordinate; @@ -90,6 +90,7 @@ import com.vividsolutions.jts.geom.Coordinate; * Jul 29, 2014 3465 mapeters Updated deprecated drawString() calls. * Aug 11, 2014 3504 mapeters Replaced deprecated IODataPreparer * instances with IRenderedImageCallback. + * Jun 26, 2015 4512 mapeters Updated for RedbookWMOMap API changes. * * * @@ -179,7 +180,7 @@ public class RedbookUpperAirResource extends Activator.getDefault(), Activator.PLUGIN_ID); return; } - RedbookWMOMap.Info info = map.mapping.get(wmo.getConstraintValue()); + RedbookWMOMap.Info info = map.getValue(wmo.getConstraintValue()); if (info != null && info.name != null) this.humanReadableName = info.name; } diff --git a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/dialogs/TextEditorDialog.java b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/dialogs/TextEditorDialog.java index 0a2780723b..f8f5ae1fcc 100644 --- a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/dialogs/TextEditorDialog.java +++ b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/dialogs/TextEditorDialog.java @@ -347,7 +347,8 @@ import com.raytheon.viz.ui.dialogs.SWTMessageBox; * 15Feb2015 4001 dgilling Ensure all fields are set in SendPracticeProductRequest. * 05Mar2015 RM 15025 kshrestha Fix to maintain the headers that they are saved with * 10Mar2015 RM 14866 kshrestha Disable QC GUI pop up for TextWS - * 6Apr2015 RM14968 mgamazaychikov Fix formatting for pathcast section + * 06Apr2015 RM14968 mgamazaychikov Fix formatting for pathcast section + * 15Jun2015 4441 randerso Unconditionally convert text to upper case for QC * * * @@ -4909,8 +4910,7 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, if (warnGenFlag) { QCConfirmationMsg qcMsg = new QCConfirmationMsg(); if (!qcMsg.checkWarningInfo(headerTF.getText().toUpperCase(), - MixedCaseProductSupport.conditionalToUpper(prod.getNnnid(), - textEditor.getText()), prod.getNnnid())) { + textEditor.getText().toUpperCase(), prod.getNnnid())) { WarnGenConfirmationDlg wgcd = new WarnGenConfirmationDlg(shell, qcMsg.getTitle(), qcMsg.getProductMessage(), qcMsg.getModeMessage()); @@ -4964,11 +4964,11 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, return; } - if (isWarnGenDlg == true){ + if (isWarnGenDlg == true) { StdTextProduct prod = getStdTextProduct(); String afosId = prod.getCccid() + prod.getNnnid() + prod.getXxxid(); - SendConfirmationMsg sendMsg = new SendConfirmationMsg(resend, afosId, - prod.getNnnid()); + SendConfirmationMsg sendMsg = new SendConfirmationMsg(resend, + afosId, prod.getNnnid()); WarnGenConfirmationDlg wgcd = new WarnGenConfirmationDlg(shell, sendMsg.getTitle(), sendMsg.getProductMessage(), @@ -5748,140 +5748,154 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, int afosXxxLimit = 5; // second three characters is AFOS XXX String prodText = textEditor.getText(); - if (!prodText.startsWith("ZCZC")) { - /* - * DR15610 - Make sure that if the first line of the text product is not - * a WMO heading it is treated as part of the text body. - */ - String[] pieces = textEditor.getText().split("\r*\n", 2); - if (pieces.length > 1) { - pieces[0] += "\n"; // WMOHeader expects this - } - WMOHeader header = new WMOHeader(pieces[0].getBytes(), null); - if (!header.isValid()) { - headerTF.setText(""); - try { - textEditor.setText(originalText); - textEditor.setEditable(true); - textEditor.setEditable(false); - } catch (IllegalArgumentException e) { - // There is no text product body, so set it to the empty string. - textEditor.setText(""); + if (!prodText.startsWith("ZCZC")) { + /* + * DR15610 - Make sure that if the first line of the text product is + * not a WMO heading it is treated as part of the text body. + */ + String[] pieces = textEditor.getText().split("\r*\n", 2); + if (pieces.length > 1) { + pieces[0] += "\n"; // WMOHeader expects this } - } else { - // TODO FIX PARSING - - // First, set the current header by assuming that it usually - // consists of the first two lines of text in the text product, - // though there will be exceptions to that "rule" as handled below. - // So, obtain the AFOS NNNxxx. If it's where it is supposed to be - // in the new format, then the existing header is already an AWIPS - // text product identifier. Otherwise it is a legacy AFOS - // identifier. - if (TextDisplayModel.getInstance().hasStdTextProduct(token)) { - StdTextProduct textProd = TextDisplayModel.getInstance() - .getStdTextProduct(token); - StdTextProductId prodId = textProd.getProdId(); + WMOHeader header = new WMOHeader(pieces[0].getBytes(), null); + if (!header.isValid()) { + headerTF.setText(""); try { - // start of second line of text - start = textEditor.getOffsetAtLine(thisLine + 1); - if ((textEditor.getText(start, start + afosNnnLimit) - .equals(prodId.getNnnid())) - && (textEditor.getText(start + afosNnnLimit + 1, - start + afosXxxLimit).equals(prodId - .getXxxid()))) { - // Text matches the products nnnid and xxxid - numberOfLinesOfHeaderText = 2; - } else if (textEditor.getText(start, - start + afosNnnLimit + 2).equals( - AFOSParser.DRAFT_PIL) - || textEditor.getText(start, - start + afosNnnLimit + 2).equals("TTAA0")) { - // Text matches temporary WRKWG# - numberOfLinesOfHeaderText = 2; - } else { + textEditor.setText(originalText); + textEditor.setEditable(true); + textEditor.setEditable(false); + } catch (IllegalArgumentException e) { + // There is no text product body, so set it to the empty + // string. + textEditor.setText(""); + } + } else { + // TODO FIX PARSING + + // First, set the current header by assuming that it usually + // consists of the first two lines of text in the text product, + // though there will be exceptions to that "rule" as handled + // below. + // So, obtain the AFOS NNNxxx. If it's where it is supposed to + // be + // in the new format, then the existing header is already an + // AWIPS + // text product identifier. Otherwise it is a legacy AFOS + // identifier. + if (TextDisplayModel.getInstance().hasStdTextProduct(token)) { + StdTextProduct textProd = TextDisplayModel.getInstance() + .getStdTextProduct(token); + StdTextProductId prodId = textProd.getProdId(); + try { + // start of second line of text + start = textEditor.getOffsetAtLine(thisLine + 1); + if ((textEditor.getText(start, start + afosNnnLimit) + .equals(prodId.getNnnid())) + && (textEditor.getText( + start + afosNnnLimit + 1, start + + afosXxxLimit).equals(prodId + .getXxxid()))) { + // Text matches the products nnnid and xxxid + numberOfLinesOfHeaderText = 2; + } else if (textEditor.getText(start, + start + afosNnnLimit + 2).equals( + AFOSParser.DRAFT_PIL) + || textEditor.getText(start, + start + afosNnnLimit + 2).equals( + "TTAA0")) { + // Text matches temporary WRKWG# + numberOfLinesOfHeaderText = 2; + } else { + // Assume this header block is a legacy AFOS + // identifier. + numberOfLinesOfHeaderText = 1; + } + } catch (IllegalArgumentException e) { // Assume this header block is a legacy AFOS identifier. numberOfLinesOfHeaderText = 1; } + } + + try { + start = 0; + finish = textEditor.getOffsetAtLine(thisLine + + numberOfLinesOfHeaderText) - 1; } catch (IllegalArgumentException e) { - // Assume this header block is a legacy AFOS identifier. - numberOfLinesOfHeaderText = 1; + // The text does not span enough lines so use the full + // extent + // of the product. + finish = textEditor.getCharCount() - 1; + } + + // Set the content of the header block to consist of just the + // header + // of + // the text product... it will get reunited with the body when + // it is + // saved. + if (finish > start) { + headerTF.setText(textEditor.getText(start, finish)); + } else { + headerTF.setText(""); + } + + // Next, set the current body by assuming that it always + // consists of the rest of the text product beyond the line(s) + // of text in the header. + try { + int numberOfBlankLines = -1; + String line = null; + do { + numberOfBlankLines++; + line = textEditor.getLine(thisLine + + numberOfLinesOfHeaderText + + numberOfBlankLines); + } while ((line.length() == 0) || line.equals("")); + // Note: 'st' is a reference to 'textEditor'... + // delelete the header from the text in 'textEditor' + finish = textEditor.getOffsetAtLine(thisLine + + numberOfLinesOfHeaderText + numberOfBlankLines); + textEditor.setSelection(start, finish); + textEditor.setEditable(true); + textEditor.invokeAction(SWT.DEL); + textEditor.setEditable(false); + } catch (IllegalArgumentException e) { + // There is no text product body, so set it to the empty + // string. + textEditor.setText(""); } } + } else { + /** + * If the first word begins with "ZCZC", it is a two-line header at + * least, it is + * "ZCZC CCNNNXXX adr\r\r\nTTAA00 KCCC DDHHMM bbb\r\r\n" + */ + int newLineIndex = prodText.indexOf("\n\n"); + String first = prodText.substring(0, newLineIndex); - try { - start = 0; - finish = textEditor.getOffsetAtLine(thisLine - + numberOfLinesOfHeaderText) - 1; - } catch (IllegalArgumentException e) { - // The text does not span enough lines so use the full extent - // of the product. - finish = textEditor.getCharCount() - 1; - } + if (first.length() > 10) { + String rest = prodText.substring(newLineIndex + 1); - // Set the content of the header block to consist of just the header - // of - // the text product... it will get reunited with the body when it is - // saved. - if (finish > start) { - headerTF.setText(textEditor.getText(start, finish)); - } else { - headerTF.setText(""); - } + headerTF.setText(first); + String cccnnnxxx = first.substring(5, 14); + setCurrentSiteId(""); + setCurrentWmoId(""); + setCurrentWsfoId(cccnnnxxx.substring(0, 3)); + setCurrentProdCategory(cccnnnxxx.substring(3, 6)); + setCurrentProdDesignator(cccnnnxxx.substring(6, 9)); - // Next, set the current body by assuming that it always - // consists of the rest of the text product beyond the line(s) - // of text in the header. - try { - int numberOfBlankLines = -1; - String line = null; - do { - numberOfBlankLines++; - line = textEditor.getLine(thisLine - + numberOfLinesOfHeaderText + numberOfBlankLines); - } while ((line.length() == 0) || line.equals("")); - // Note: 'st' is a reference to 'textEditor'... - // delelete the header from the text in 'textEditor' - finish = textEditor.getOffsetAtLine(thisLine - + numberOfLinesOfHeaderText + numberOfBlankLines); - textEditor.setSelection(start, finish); - textEditor.setEditable(true); - textEditor.invokeAction(SWT.DEL); - textEditor.setEditable(false); - } catch (IllegalArgumentException e) { - // There is no text product body, so set it to the empty string. - textEditor.setText(""); + try { + textEditor.setText(rest.trim()); + textEditor.setEditable(true); + textEditor.setEditable(false); + } catch (IllegalArgumentException e) { + // There is no text product body, so set it to the empty + // string. + textEditor.setText(""); + } } } - } else { - /** - * If the first word begins with "ZCZC", it is a two-line header at least, - * it is "ZCZC CCNNNXXX adr\r\r\nTTAA00 KCCC DDHHMM bbb\r\r\n" - */ - int newLineIndex = prodText.indexOf("\n\n"); - String first = prodText.substring(0, newLineIndex); - - if (first.length() > 10 ) { - String rest = prodText.substring(newLineIndex+1); - - headerTF.setText(first); - String cccnnnxxx = first.substring(5, 14); - setCurrentSiteId(""); - setCurrentWmoId(""); - setCurrentWsfoId(cccnnnxxx.substring(0, 3)); - setCurrentProdCategory(cccnnnxxx.substring(3, 6)); - setCurrentProdDesignator(cccnnnxxx.substring(6, 9)); - - try { - textEditor.setText(rest.trim()); - textEditor.setEditable(true); - textEditor.setEditable(false); - } catch (IllegalArgumentException e) { - // There is no text product body, so set it to the empty string. - textEditor.setText(""); - } - } - } } /** @@ -7951,7 +7965,8 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, } // is this the pathcast paragragh? - if (paragraphStart.startsWith("* THIS") && paragraphStart.endsWith("WILL BE NEAR...")) { + if (paragraphStart.startsWith("* THIS") + && paragraphStart.endsWith("WILL BE NEAR...")) { inPathcast = true; } @@ -7964,8 +7979,10 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, padding = " "; } - if ((inLocations || inPathcast) && (paragraphStartLineNumber == lineNumber)) { - // Keep LOCATIONS and PATHCAST first line short & don't paste more to it. + if ((inLocations || inPathcast) + && (paragraphStartLineNumber == lineNumber)) { + // Keep LOCATIONS and PATHCAST first line short & don't paste more + // to it. if (line.indexOf("...") == line.lastIndexOf("...")) { return; } @@ -8045,11 +8062,11 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, && (allText.charAt(eol + 1) == '\n')) { deleteLen = 2; } else if (allText.charAt(eol) == '\n') { - if (allText.charAt(eol-1) == '.' && allText.charAt(eol-2) != '.') { + if ((allText.charAt(eol - 1) == '.') + && (allText.charAt(eol - 2) != '.')) { // do not extend this line. return; - } - else { + } else { deleteLen = 1; } } else { @@ -8197,8 +8214,8 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, } textEditor.replaceTextRange(position, 0, replacement.toString()); // remove and extra space - if (textEditor.getText(position -1, position - 1).equals(" ")) { - textEditor.replaceTextRange(position-1, 1, ""); + if (textEditor.getText(position - 1, position - 1).equals(" ")) { + textEditor.replaceTextRange(position - 1, 1, ""); } ++endWrapLine; } diff --git a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/qc/IQCCheck.java b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/qc/IQCCheck.java index 783c02841c..01aa45427a 100644 --- a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/qc/IQCCheck.java +++ b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/qc/IQCCheck.java @@ -64,15 +64,15 @@ public interface IQCCheck { public static final Pattern firstBulletPtrn = Pattern.compile( "^\\*\\s(.*)\\s(WARNING|ADVISORY)(\\sFOR(.*)|...)", - Pattern.CASE_INSENSITIVE); + Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); public static final Pattern secondBulletPtrn = Pattern.compile( "^\\*\\sUNTIL\\s(\\d{1,2})(\\d{2})\\s(AM|PM)\\s(\\w{3,4})", - Pattern.CASE_INSENSITIVE); + Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); public static final Pattern thirdBulletPtrn = Pattern.compile( "^\\*\\sAT\\s(\\d{1,2})(\\d{2})\\s(AM|PM)\\s(\\w{3,4})(.*)", - Pattern.CASE_INSENSITIVE); + Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); public static final Pattern latLonPtrn = Pattern .compile("LAT...LON+(\\s\\d{3,4}\\s\\d{3,5}){1,}"); diff --git a/cave/com.raytheon.viz.textworkstation/localization/textws/gui/QualityControlCfg.xml b/cave/com.raytheon.viz.textworkstation/localization/textws/gui/QualityControlCfg.xml index 26023ea61c..6a6264696e 100644 --- a/cave/com.raytheon.viz.textworkstation/localization/textws/gui/QualityControlCfg.xml +++ b/cave/com.raytheon.viz.textworkstation/localization/textws/gui/QualityControlCfg.xml @@ -20,12 +20,12 @@ --> ER \ RAIN - SM \ SNOW MELT + SM \ SNOWMELT SM \ MELTING SNOW - SM \ VOLCANIC SNOW MELT + SM \ VOLCANIC SNOWMELT IJ \ ICE JAM IC \ ICE JAM AND RAIN - IC \ ICE JAM AND SNOW MELT + IC \ ICE JAM AND SNOWMELT GO \ GLACIER GO \ GLACIER-DAMMED LAKE DM \ DAM @@ -34,7 +34,7 @@ DM \ LEVEE FAILURE DM \ DAM FAILURE DM \ DAM BREAK - RS \ RAIN AND SNOW MELT + RS \ RAIN AND SNOWMELT RS \ RAIN AND MELTING SNOW diff --git a/cave/com.raytheon.viz.ui.personalities.awips/src/com/raytheon/viz/ui/personalities/awips/AbstractAWIPSComponent.java b/cave/com.raytheon.viz.ui.personalities.awips/src/com/raytheon/viz/ui/personalities/awips/AbstractAWIPSComponent.java index b12042358f..d2a10a70a1 100644 --- a/cave/com.raytheon.viz.ui.personalities.awips/src/com/raytheon/viz/ui/personalities/awips/AbstractAWIPSComponent.java +++ b/cave/com.raytheon.viz.ui.personalities.awips/src/com/raytheon/viz/ui/personalities/awips/AbstractAWIPSComponent.java @@ -66,6 +66,7 @@ import com.raytheon.uf.viz.personalities.cave.component.CAVEApplication; * Feb 23, 2015 4164 dlovely Extracted AlertViz initialize. * Jun 03, 2015 4473 njensen If running with AlertViz, start a job to * continuously check AlertViz status. + * Jun 22, 2015 4474 njensen Don't check for alertviz if alertview is enabled * * * @@ -212,7 +213,8 @@ public abstract class AbstractAWIPSComponent extends CAVEApplication { // Setup AlertViz observer if ((getRuntimeModes() & ALERT_VIZ) != 0) { // Set up alertviz - if (LocalizationManager.internalAlertServer && !isNonUIComponent()) { + if (LocalizationManager.internalAlertServer && !isNonUIComponent() + && !Boolean.getBoolean("alertview.enabled")) { /* * Potentially run alertviz inside viz. Will repeatedly schedule * a check to verify it's running. If not found, it will try and diff --git a/cave/com.raytheon.viz.volumebrowser/localization/menus/volumebrowser/fields/planview-timeseries/misc.xml b/cave/com.raytheon.viz.volumebrowser/localization/menus/volumebrowser/fields/planview-timeseries/misc.xml index fba2764353..3e8be73eda 100644 --- a/cave/com.raytheon.viz.volumebrowser/localization/menus/volumebrowser/fields/planview-timeseries/misc.xml +++ b/cave/com.raytheon.viz.volumebrowser/localization/menus/volumebrowser/fields/planview-timeseries/misc.xml @@ -83,12 +83,7 @@ - - - - - + diff --git a/cave/com.raytheon.viz.volumebrowser/localization/menus/volumebrowser/fields/planview-timeseries/sfc2d/simulated-satellite.xml b/cave/com.raytheon.viz.volumebrowser/localization/menus/volumebrowser/fields/planview-timeseries/sfc2d/simulated-satellite.xml deleted file mode 100644 index 0972d35098..0000000000 --- a/cave/com.raytheon.viz.volumebrowser/localization/menus/volumebrowser/fields/planview-timeseries/sfc2d/simulated-satellite.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/cave/com.raytheon.viz.volumebrowser/localization/menus/volumebrowser/planes/planviewtime-timeseries/misc.xml b/cave/com.raytheon.viz.volumebrowser/localization/menus/volumebrowser/planes/planviewtime-timeseries/misc.xml index 3aa076e935..5e5155567b 100644 --- a/cave/com.raytheon.viz.volumebrowser/localization/menus/volumebrowser/planes/planviewtime-timeseries/misc.xml +++ b/cave/com.raytheon.viz.volumebrowser/localization/menus/volumebrowser/planes/planviewtime-timeseries/misc.xml @@ -112,6 +112,5 @@ indentText="false" /> - + \ No newline at end of file diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/text/AbstractLockingBehavior.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/text/AbstractLockingBehavior.java index 27ff83aa64..49942b82c4 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/text/AbstractLockingBehavior.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/text/AbstractLockingBehavior.java @@ -82,8 +82,9 @@ abstract public class AbstractLockingBehavior { Pattern.MULTILINE | Pattern.CASE_INSENSITIVE); private static Pattern startMND = Pattern - .compile("(BULLETIN - IMMEDIATE BROADCAST REQUESTED)|(BULLETIN - EAS ACTIVATION REQUESTED)|" - + warningType); + .compile( + "(BULLETIN - IMMEDIATE BROADCAST REQUESTED)|(BULLETIN - EAS ACTIVATION REQUESTED)|" + + warningType, Pattern.CASE_INSENSITIVE); private static Pattern stateAbbrevPtrn = Pattern.compile( WarnGenPatterns.listOfAreaName + WarnGenPatterns.NEWLINE, diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/database/D2DGridDatabase.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/database/D2DGridDatabase.java index 45ea0a3d9f..8a30834049 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/database/D2DGridDatabase.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/database/D2DGridDatabase.java @@ -118,6 +118,7 @@ import com.raytheon.uf.edex.database.DataAccessLayerException; * should be purged. * 09/09/2014 #3356 njensen Remove CommunicationException * 03/05/2015 #4169 randerso Fix error handling in getDatabase + * 06/29/2015 #4537 rferrel Allow for durations less then 1 hour. * * * @@ -1097,8 +1098,12 @@ public class D2DGridDatabase extends VGridDatabase { TimeUtil.SECONDS_PER_HOUR, 0); } } - return new TimeConstraints(TimeUtil.SECONDS_PER_HOUR, (int) repeat, - (int) start); + + int duration = TimeUtil.SECONDS_PER_HOUR; + if (duration > repeat) { + duration = (int) repeat; + } + return new TimeConstraints(duration, (int) repeat, (int) start); } private int calcPrecision(float minV, float maxV) { diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/common_static/base/notification/gfe-watch.xml b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/common_static/base/notification/gfe-watch.xml index 086cbadb25..93f427665d 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/common_static/base/notification/gfe-watch.xml +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/common_static/base/notification/gfe-watch.xml @@ -5,7 +5,7 @@ VM - + diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/common_static/base/parameter/alias/gfeParamName.xml b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/common_static/base/parameter/alias/gfeParamName.xml index 7b363efca5..b4b8b57c26 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/common_static/base/parameter/alias/gfeParamName.xml +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/common_static/base/parameter/alias/gfeParamName.xml @@ -10,6 +10,7 @@ Dec 15, 2014 DR 14024 jwatson Added parameters for 2.5km GFSLAMPGrid Feb 24, 2015 DR 16671 byin Added HPBL for RUC13 May 21, 2015 DR 17515 bhunder Added parameters for URMA25 + Jun 29, 2015 #4537 rferrel Added parameters for HRRR. --> av @@ -27,7 +28,8 @@ dirsw dpd dpt - dpterranl + dpterranl + dswrf ELEV emsp ept @@ -60,6 +62,7 @@ prsigsv pvv pw + retop rh scp shf @@ -97,6 +100,7 @@ wd wderranl weasd + weasd1hr wgh wgs windprob diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/config/gfe/serverConfig.py b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/config/gfe/serverConfig.py index 1514f8d9ad..d44aa41c00 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/config/gfe/serverConfig.py +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/config/gfe/serverConfig.py @@ -66,8 +66,8 @@ # 04/20/2015 #4414 dgilling Add missing NWPSTrkngCG0 weather elements. # 05/12/2015 #17144 bhunder Added RTMA model # 05/29/2015 17496 ryu Changed parm definitions for Wave1-10 and Period1-10. -# 05/29/2015 #17144 bhunder Added weather Params for URMA25 and OCONUS RTMA -# 06/15/2015 #4422 dgilling Added parms for NAM12 simulated satellite. +# +# 05/29/2015 #17144 bhunder Added weather Params for URMA25 and OCONUS RTMA #################################################################################################### #---------------------------------------------------------------------------- @@ -391,16 +391,7 @@ FloodingRainThreat = ("FloodingRainThreat", DISCRETE, "Cat", "Flooding Rain Thre StormSurgeThreat = ("StormSurgeThreat", DISCRETE, "Cat", "Storm Surge Threat", NO, Threat4Keys,2) WindThreat = ("WindThreat", DISCRETE, "Cat", "Wind Threat", NO, Threat4Keys,2) TornadoThreat = ("TornadoThreat", DISCRETE, "Cat", "Tornado Threat", NO, Threat4Keys,2) -QPFtoFFGRatio = ("QPFtoFFGRatio", SCALAR, "1", "QPF to FFG Ratio", 8.0, 0.0, 0, NO) - -# Parms for Simulated Satellite -SatIR11 = ("IR11", SCALAR, "C", "11 micron temperature", 58.0, -111.0, 0, NO) -SatIR13 = ("IR13", SCALAR, "C", "13 micron temperature", 50.0, -111.0, 0, NO) -SatIR39 = ("IR39", SCALAR, "C", "3.9 micron temperature", 50.0, - -111.0, 0, NO) -SatWV = ("WaterVapor", SCALAR, "C", "water vapor temperature", - -62.0, -111.0, 0, NO) -SatFog = ("Fog", SCALAR, "C", "ir11 - ir39", 50.0, -111.0, 0, NO) +QPFtoFFGRatio = ("QPFtoFFGRatio", SCALAR, "1", "QPF to FFG Ratio", 8.0, 0.0, 0, NO) # Hazards HazardKeys = [] @@ -2143,9 +2134,6 @@ ENPwave_parms = [([WindWaveHeight, WaveHeight, SurfHeight, Wind], TC6), # GFSLAMPGrid GFSLAMPGridPARMS=[([Temp, Td, Vis, CigHgt],TC1)] -# NAM12 Simulated Satellite -NAM12SATSIMPARMS=[([SatIR39, SatIR11, SatIR13, SatWV, SatFog],TC3)] - #--------------------------------------------------------------------------- # Databases for a site. # list of (Database, [parms]) @@ -2165,7 +2153,7 @@ DATABASES = [(Official, OFFICIALDBS + localParms), (GFS75, STD6_MODEL + localGFS75Parms), (GFS190, STD6_MODEL + localGFS190Parms), (NAM40, STD3_MODEL + localNAM40Parms), - (NAM12, STD3_MODEL + NAM12SATSIMPARMS + localNAM12Parms), + (NAM12, STD3_MODEL + localNAM12Parms), (gfsLR, STD12_MODEL + localgfsLRParms), (GWW, WAVEPARMS + localGWWParms), (WNAWAVE, WAVEPARMS + localWNAWAVEParms), diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/grid/gfeLevelMappingFile.xml b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/grid/gfeLevelMappingFile.xml index fd37bda8c9..51684e58aa 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/grid/gfeLevelMappingFile.xml +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/grid/gfeLevelMappingFile.xml @@ -1,12 +1,16 @@ - + + + + @@ -249,6 +253,9 @@ + + + @@ -489,7 +496,4 @@ - - - diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/grid/parameterInfo/HRRR.xml b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/grid/parameterInfo/HRRR.xml index 31de299811..040a4cfe77 100755 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/grid/parameterInfo/HRRR.xml +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/grid/parameterInfo/HRRR.xml @@ -1,21 +1,67 @@ + 0 + 900 + 1800 + 2700 3600 + 4500 + 5400 + 6300 7200 + 8100 + 9000 + 9900 10800 + 11700 + 12600 + 13500 14400 + 15300 + 16200 + 17100 18000 + 18900 + 19800 + 20700 21600 + 22500 + 23400 + 24300 25200 + 26100 + 27000 + 27900 28800 + 29700 + 30600 + 31500 32400 + 33300 + 34200 + 35100 36000 + 36900 + 37800 + 38700 39600 + 40500 + 41400 + 42300 43200 + 44100 + 45000 + 45900 46800 + 47700 + 48600 + 49500 50400 + 51300 + 52200 + 53100 54000 @@ -43,10 +89,28 @@ 100000.0 -99999.0 0 - FHAG 1000 HYB 1 + FHAG 1000 4000 HYB 1 NTAT 0 FHAG1000 + FHAG4000 HYB1 + NTAT + + + + + retop + Echo top height of 18dBZ surface + m + meters + echoTop + 0.0 + 100000.0 + -99999.0 + 0 + CTL + + CTL @@ -74,9 +138,10 @@ 6000.0 -99999.0 0 - SFC BL 0>180 0>255 + SFC BL 0>90 0>180 0>255 SFC + BL090 BL0180 BL0255 @@ -89,8 +154,8 @@ 0 - tp - total precipitation + tp1hr + total precipitation (1 hr) mm millimeter totPrecip @@ -104,8 +169,8 @@ - weasd - water equivalent of accumulated snow depth + weasd1hr + water equivalent of accumulated snow depth (1 hr) ml mil waterEqvAccSnowDepth @@ -193,21 +258,6 @@ HCL - - crain - Categorical rain - yes=1, no=0 - - CategoricalRain - 0.0 - 1.0 - -99999.0 - 0 - SFC - - SFC - - uw u wind component @@ -218,9 +268,15 @@ 150.0 -99999.0 0 - 10 FHAG + FHAG 10 FHAG 80 MB 1000 925 850 700 500 FHAG10 + FHAG80 + MB1000 + MB925 + MB850 + MB700 + MB500 @@ -233,9 +289,10 @@ 1000.0 -99999.0 0 - SFC BL 0>255 + SFC BL 0>90 0>255 SFC + BL090 BL0255 @@ -270,25 +327,54 @@ - csnow - Categorical snow + cicep + Categorical ice pellets yes=1, no=0 - CategoricalSnow + CategoricalIcePlt 0.0 1.0 -99999.0 + 0 SFC SFC - cicep - Categorical ice pellets + cpofp + Probability of frozen precip + % + percent + FrznPcpProb + -99999.0 + 0 + SFC + + SFC + + + + crain + Categorical rain yes=1, no=0 - CategoricalIcePlt + CategoricalRain + 0.0 + 1.0 + -99999.0 + 0 + SFC + + SFC + + + + csnow + Categorical snow + yn + + CategoricalSnow 0.0 1.0 -99999.0 @@ -329,9 +415,9 @@ 150.0 -99999.0 1 - 10 FHAG + SFC - FHAG10 + SFC @@ -359,9 +445,24 @@ 330.0 -99999.0 1 - FHAG 2 + FHAG 2 MB 1000 0925 700 500 FHAG2 + MB1000 + MB925 + MB700 + MB500 + + + + dswrf + Downward shortwave radiation flux + W/m2 + watts/meter2 + 0 + SFC + + SFC @@ -405,11 +506,34 @@ 150.0 -99999.0 0 + FHAG 10 FHAG 80 MB 1000 925 850 700 500 + + FHAG10 + FHAG80 + MB1000 + MB925 + MB850 + MB700 + MB500 + + + + + ws1hr + Wind Speed + m/s + meter/sec + windSpeed + 0 + 150 + -99999.0 + 0 10 FHAG FHAG10 + t Temperature @@ -420,9 +544,14 @@ 330.0 -99999.0 0 - 2 FHAG + 2 FHAG MB 1000 925 850 700 500 FHAG2 + MB1000 + MB925 + MB850 + MB700 + MB500 @@ -441,10 +570,15 @@ 20000.0 -99999.0 0 - CBL CTL + SFC ADCL CBL CTL CLG MB 1000 500 + SFC + ADCL CBL CTL + CLG + MB1000 + MB500 @@ -462,6 +596,19 @@ SFC + + pr + precipitation rate + Kg/m**2 / s + 0.0 + 0.10000000149 + -99999.0 + 0 + SFC + + SFC + + pw precipitable water @@ -508,11 +655,11 @@ - mwind - Maximum Wind Speed + ws + Wind Speed m/s meter/sec - maxWindSpeed + windSpeed 0 150 -99999.0 @@ -522,4 +669,29 @@ FHAG10 + + + + + + + + + + + + + + + + + + + + + + + diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/grid/parameterInfo/eta218.xml b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/grid/parameterInfo/eta218.xml index 92dea9a519..db3e04e1f6 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/grid/parameterInfo/eta218.xml +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/grid/parameterInfo/eta218.xml @@ -829,64 +829,4 @@ SFC - - SBT122 - Simulated Brightness Temp 3.9u - K - degree_Kelvin - SBT122 - 180.0 - 330.0 - -99999.0 - 0 - NTAT - - NTAT - - - - SBT123 - Simulated Brightness Temp WV - K - degree_Kelvin - SBT123 - 180.0 - 330.0 - -99999.0 - 0 - NTAT - - NTAT - - - - SBT124 - Simulated Brightness Temp IR - K - degree_Kelvin - SBT124 - 180.0 - 330.0 - -99999.0 - 0 - NTAT - - NTAT - - - - SBT125 - Simulated Brightness Temp 13u - K - degree_Kelvin - SBT125 - 180.0 - 330.0 - -99999.0 - 0 - NTAT - - NTAT - - diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/smartinit/NAM12.py b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/smartinit/NAM12.py index 38bb60772c..5d07364d34 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/smartinit/NAM12.py +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/smartinit/NAM12.py @@ -1686,25 +1686,5 @@ class NAM12Forecaster(Forecaster): value=where(less(value,0.0),value+360,value) return value - def gvar2T(self, ir): - t = where(ir < 177, (660 - ir) / 2.0, (418 - ir)) - t = t - 273 - return t - - def calcIR11(self, SBT124_NTAT): - return self.gvar2T(SBT124_NTAT) - - def calcIR13(self, SBT125_NTAT): - return self.gvar2T(SBT125_NTAT) - - def calcIR39(self, SBT122_NTAT): - return self.gvar2T(SBT122_NTAT) - - def calcWaterVapor(self, SBT123_NTAT): - return self.gvar2T(SBT123_NTAT) - - def calcFog(self, IR11, IR39): - return IR11 - IR39 - def main(): NAM12Forecaster().run() diff --git a/edexOsgi/com.raytheon.edex.uengine/src/com/raytheon/edex/uengine/GridUtil.java b/edexOsgi/com.raytheon.edex.uengine/src/com/raytheon/edex/uengine/GridUtil.java deleted file mode 100644 index ebb7d042cf..0000000000 --- a/edexOsgi/com.raytheon.edex.uengine/src/com/raytheon/edex/uengine/GridUtil.java +++ /dev/null @@ -1,81 +0,0 @@ -/** - * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA - * This software product contains export-restricted data whose - * export/transfer/disclosure is restricted by U.S. law. Dissemination - * to non-U.S. persons whether in the United States or abroad requires - * an export license or other authorization. - * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * - * See the AWIPS II Master Rights File ("Master Rights File.pdf") for - * further licensing information. - **/ - -package com.raytheon.edex.uengine; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.HashMap; -import java.util.Map; - -/** - * Util class for grids. Extracted from original uEngine's TermQueryIndex task. - * - *
- * SOFTWARE HISTORY
- * Date             PR#             Engineer            Description
- * -----------      ----------      ------------        --------------------------
- * Mar 29, 2007                     njensen             Initial Creation
- * 
- * - */ -public class GridUtil { - - /** - * Creates a Meta-Data map from the meta-data query result object. - * - * @param result - * the query result object - * @return the Meta-Data map - * - * @throws Exception - * in the event a serious error occurs - */ - public static Map createMetaDataMap(Object result) - throws Exception { - HashMap retVal = new HashMap(); - Class aClass = Class.forName(result.getClass().getName()); - - while (aClass != null) { - for (Field aField : aClass.getDeclaredFields()) { - if (!Modifier.isStatic(aField.getModifiers())) { - String name = aField.getName(); - String getter = "get" + name.substring(0, 1).toUpperCase() - + name.substring(1); - try { - Method aMethod = aClass.getMethod(getter, - (Class[]) null); - Object value = aMethod.invoke(result, (Object[]) null); - if (value != null) { - // System.out.println(name + " : " + value); - retVal.put(name, value); - } - } catch (NoSuchMethodException e) { - // just skip it! - } - } - } - aClass = aClass.getSuperclass(); - } - return retVal; - } - -} diff --git a/edexOsgi/com.raytheon.edex.uengine/src/com/raytheon/edex/uengine/runners/IMicroEngine.java b/edexOsgi/com.raytheon.edex.uengine/src/com/raytheon/edex/uengine/runners/IMicroEngine.java index 1ee1b2ad7f..8587a3ec9a 100644 --- a/edexOsgi/com.raytheon.edex.uengine/src/com/raytheon/edex/uengine/runners/IMicroEngine.java +++ b/edexOsgi/com.raytheon.edex.uengine/src/com/raytheon/edex/uengine/runners/IMicroEngine.java @@ -25,6 +25,9 @@ import com.raytheon.edex.uengine.exception.MicroEngineException; import com.raytheon.uf.common.message.response.AbstractResponseMessage; /** + * @deprecated MicroEngine, aka uEngine, is deprecated. Use IServerRequest/IRequestHandler + * framework instead. + * * The public interface for all μEngine script runners. It provides the required * operations to run a script. These operations are {@link #initialize()}, * {@link #setScript(String)}, {@link #execute()}, {@link #getResult()}, and @@ -56,12 +59,15 @@ import com.raytheon.uf.common.message.response.AbstractResponseMessage; * ------------ ---------- ----------- -------------------------- * 12Nov2008 1709 MW Fegan Initial Creation. * 25May2011 8686 cjeanbap Add setter method. + * 25Jun2015 4495 njensen Deprecated + * * * * @author mfegan * @version 1.0 */ +@Deprecated public interface IMicroEngine { /** * Executes a previously set μEngine script. Implementations of @@ -71,6 +77,7 @@ public interface IMicroEngine { * @throws MicroEngineException if any error occurs */ public void execute() throws MicroEngineException; + /** * Executes the specified μEngine script. This is a convenience method * that includes initialization and release operations on the script runner @@ -95,7 +102,9 @@ public interface IMicroEngine { * @return the result of execution the script * @throws MicroEngineException if any error occurs */ - public List executeScript(String script) throws MicroEngineException; + public List executeScript(String script) + throws MicroEngineException; + /** * Returns the results from running a μEngine script. Classes that implement * this interface should ensure that a valid, although possibly empty, list @@ -103,6 +112,7 @@ public interface IMicroEngine { * should be obtained in this method. */ public List getResult(); + /** * Initializes the μEngine script runner. Initialization should not be * dependent on having set a script; it should only get the scripting engine @@ -111,6 +121,7 @@ public interface IMicroEngine { * @throws MicroEngineException if any error occurs */ public void initialize() throws MicroEngineException; + /** * Initializes the μEngine script runner. This version combines * {@link #setScript(String) setting the script} with @@ -120,6 +131,7 @@ public interface IMicroEngine { * @throws MicroEngineException if any error occurs */ public void initialize(String script) throws MicroEngineException; + /** * Releases any resources utilized by the μEngine script runner. Generally, * this method should release resources allocated in {@link #initialize()}. @@ -129,10 +141,11 @@ public interface IMicroEngine { * In case of failure, this method should log the failure and fail silently. */ public void release(); + /** * Provides the script to be executed. */ public void setScript(String script); - + public void setTrigger(String triggerId); } diff --git a/edexOsgi/com.raytheon.edex.uengine/src/com/raytheon/edex/uengine/tasks/response/MakeResponseAscii.java b/edexOsgi/com.raytheon.edex.uengine/src/com/raytheon/edex/uengine/tasks/response/MakeResponseAscii.java deleted file mode 100644 index 2179180bb8..0000000000 --- a/edexOsgi/com.raytheon.edex.uengine/src/com/raytheon/edex/uengine/tasks/response/MakeResponseAscii.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA - * This software product contains export-restricted data whose - * export/transfer/disclosure is restricted by U.S. law. Dissemination - * to non-U.S. persons whether in the United States or abroad requires - * an export license or other authorization. - * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * - * See the AWIPS II Master Rights File ("Master Rights File.pdf") for - * further licensing information. - **/ - -package com.raytheon.edex.uengine.tasks.response; - -import com.raytheon.edex.msg.ResponseMessageASCII; -import com.raytheon.edex.uengine.tasks.ScriptTask; -import com.raytheon.uf.common.dataplugin.PluginDataObject; - -/** - * Makes an ASCII response. - * - *
- * SOFTWARE HISTORY
- * Date             PR#             Engineer            Description
- * -----------      ----------      ------------        --------------------------
- * Mar 29, 2007                     njensen             Initial Creation
- * 
- * - */ -public class MakeResponseAscii extends ScriptTask { - - private PluginDataObject record; - - private String input; - - public MakeResponseAscii(PluginDataObject aRecord, String anInput) { - record = aRecord; - input = anInput; - } - - /* - * (non-Javadoc) - * - * @see com.raytheon.edex.uengine.js.tasks.ScriptTask#execute() - */ - @Override - public Object execute() { - String dataURI = (String) record.getIdentifier(); - String time = record.getDataTime().getValidTime().toString(); - String station = "StationID"; - String type = record.getPluginName(); - - return ResponseMessageASCII.generateASCIIResponse(null, input, type, - station, time, dataURI); - } - -} diff --git a/edexOsgi/com.raytheon.edex.uengine/src/com/raytheon/edex/uengine/tasks/response/MakeResponseInline.java b/edexOsgi/com.raytheon.edex.uengine/src/com/raytheon/edex/uengine/tasks/response/MakeResponseInline.java deleted file mode 100644 index 1b75fc00e0..0000000000 --- a/edexOsgi/com.raytheon.edex.uengine/src/com/raytheon/edex/uengine/tasks/response/MakeResponseInline.java +++ /dev/null @@ -1,225 +0,0 @@ -/** - * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA - * This software product contains export-restricted data whose - * export/transfer/disclosure is restricted by U.S. law. Dissemination - * to non-U.S. persons whether in the United States or abroad requires - * an export license or other authorization. - * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * - * See the AWIPS II Master Rights File ("Master Rights File.pdf") for - * further licensing information. - **/ - -package com.raytheon.edex.uengine.tasks.response; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.util.ArrayList; -import java.util.GregorianCalendar; -import java.util.List; -import java.util.UUID; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -import com.raytheon.edex.msg.ResponseMessageInline; -import com.raytheon.edex.uengine.ResponseUtil; -import com.raytheon.edex.uengine.exception.MicroEngineException; -import com.raytheon.edex.uengine.tasks.ScriptTask; -import com.raytheon.uf.common.util.StringUtil; - -/** - * Makes an inline response message. Derived from old uEngine - * MakeResponseInline. - * - *
- * SOFTWARE HISTORY
- * Date             PR#             Engineer            Description
- * -----------      ----------      ------------        --------------------------
- * Apr 12, 2007                     njensen             Initial Creation
- * 
- * - */ -public class MakeResponseInline extends ScriptTask { - - private Object dataItem; - - private Object validTime; - - private String format; - - private String dataUri; - - public MakeResponseInline(Object aDataItem, Object aValidTime, - String aFormat, String aDataUri) { - dataItem = aDataItem; - validTime = aValidTime; - format = aFormat; - dataUri = aDataUri; - } - - /* - * (non-Javadoc) - * - * @see com.raytheon.edex.uengine.js.tasks.ScriptTask#execute() - */ - @Override - public Object execute() { - // set up the data and uri lists - List imageData = null; - URI[] productURIs = null; - if (dataItem instanceof URI) { - productURIs = new URI[1]; - productURIs[0] = (URI) dataItem; - } else if (dataItem instanceof byte[]) { - imageData = new ArrayList(); - imageData.add(dataItem); - } else { - throw new MicroEngineException("unknown data type " - + StringUtil.printString(dataItem.getClass().getName()) - + " unable to continue."); - } - // create the return object - need to call the create method. - return generateInlineResponse(validTime, imageData, productURIs, - imageData.size(), format, dataUri); - } - - /** - * Creates an inline response message. - * - * @param metaData - * the meta data to use for the response. - * @param imageData - * the image buffers - * @param productURIs - * the image uris - * @param imageCount - * the number of images - * - * @return the response message - */ - private ResponseMessageInline generateInlineResponse(Object aTime, - List imageData, URI[] productURIs, int imageCount, - String aFormat, String aDataURI) throws MicroEngineException { - ResponseMessageInline response = new ResponseMessageInline(); - // get the valid time - GregorianCalendar validTime = null; - if (aTime == null) { - validTime = new GregorianCalendar(); - } else { - validTime = ResponseUtil.getValidTime(aTime); - } - // get the Data URI - if (aDataURI == null) { - aDataURI = ""; - } - - String[] fileNames = new String[imageCount]; - - for (int counter = 0; counter < imageCount; counter++) { - fileNames[counter] = UUID.randomUUID() + "." + aFormat; - } - - response.setFileName(fileNames); - response.setFileType(aFormat); - response.setValidTime(validTime.getTime()); - response.setDataURI(aDataURI); - - ArrayList zippedData = new ArrayList(); - - if (productURIs != null) { - - try { - for (URI productURI : productURIs) { - File file = new File(productURI.getPath()); - if (file.exists()) { - ByteArrayOutputStream fileData = new ByteArrayOutputStream(); - ZipOutputStream zipOutputStream = new ZipOutputStream( - fileData); - ResponseUtil.recursiveZip(zipOutputStream, file, ""); - zipOutputStream.close(); - zippedData.add(fileData.toByteArray()); - - fileData.close(); - } else { - throw new MicroEngineException("Invalid file passed: " - + file.toString()); - } - } - } catch (Exception e) { - throw new MicroEngineException( - "Unable to package procduct files.", e); - } - - } - // Handle images passed in as byte arrays - else if (imageData != null) { - try { - for (int i = 0; i < imageData.size(); i++) { - ByteArrayOutputStream fileData = new ByteArrayOutputStream(); - ZipOutputStream zipOutputStream = new ZipOutputStream( - fileData); - - ZipEntry entry = new ZipEntry(fileNames[i]); - zipOutputStream.putNextEntry(entry); - zipOutputStream.write((byte[]) imageData.get(i)); - zipOutputStream.closeEntry(); - - zipOutputStream.close(); - - zippedData.add(fileData.toByteArray()); - fileData.close(); - - } - } catch (IOException e) { - throw new MicroEngineException( - "Unable to package product images.", e); - } - } - - response.setZippedData(zippedData); - return response; - } - - public Object getDataItem() { - return dataItem; - } - - public void setDataItem(Object aDataItem) { - dataItem = aDataItem; - } - - public String getDataUri() { - return dataUri; - } - - public void setDataUri(String aDataUri) { - dataUri = aDataUri; - } - - public String getFormat() { - return format; - } - - public void setFormat(String aFormat) { - format = aFormat; - } - - public Object getValidTime() { - return validTime; - } - - public void setValidTime(Object aValidTime) { - validTime = aValidTime; - } - -} diff --git a/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/ArchiveConfig.java b/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/ArchiveConfig.java index 075a3e5e5e..565366b5f4 100644 --- a/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/ArchiveConfig.java +++ b/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/ArchiveConfig.java @@ -59,6 +59,8 @@ import javax.xml.bind.annotation.XmlRootElement; * May 31, 2013 1965 bgonzale Added getCategory(categoryName) * Apr 17, 2014 3045 rferrel Code cleanup to prevent null pointer. * Jan 22, 2015 3763 rferrel Change tag from minRetentionHours to defaultRetentionHours + * Jun 29, 2015 4583 rferrel Added check of retention hours to {@link #isValid()} and + * added {@link #createErrorMsg()}. * * * @@ -207,7 +209,52 @@ public class ArchiveConfig implements Comparable { * Check for required entries. */ public boolean isValid() { - return (name != null) && (rootDir != null) && (categoryList.size() > 0); + return (name != null) && (rootDir != null) && (categoryList.size() > 0) + && (retentionHours > 0); + } + + /** + * Detail information on what caused {@link #isValid()} to fail. + * + * @return message + */ + public String createErrorMsg() { + StringBuilder sb = new StringBuilder(" missing:"); + boolean firstTag = true; + if (name == null) { + sb.append(" "); + firstTag = false; + } + if (rootDir == null) { + if (firstTag) { + firstTag = false; + } else { + sb.append(","); + } + sb.append(" "); + } + if (retentionHours <= 0) { + if (firstTag) { + firstTag = false; + } else { + sb.append(","); + } + sb.append(" "); + } + if (categoryList.isEmpty()) { + if (firstTag) { + firstTag = false; + } else { + sb.append(","); + } + sb.append(" "); + sb.append(" s"); + } + + if (!firstTag) { + sb.append("."); + } + return sb.toString(); } /* diff --git a/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/ArchiveConfigManager.java b/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/ArchiveConfigManager.java index 03ea222b48..19e970a1d4 100644 --- a/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/ArchiveConfigManager.java +++ b/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/ArchiveConfigManager.java @@ -98,6 +98,7 @@ import com.raytheon.uf.common.util.FileUtil; * Apr 29, 2014 3036 rferrel Check for missing archive root directories. * May 22, 2014 3181 rferrel Add check for valid array index. * Feb 24, 2015 3978 njensen Changed to use abstract InputStream + * Jun 29, 2015 4583 rferrel Log detail error message when archive configuration is invalid. * * * @@ -354,9 +355,13 @@ public class ArchiveConfigManager { archiveConfig.getName(), lFile); archiveMap.put(archiveConfig.getName(), archiveConfig); } else { - statusHandler.handle(Priority.ERROR, - "Bad Archive configuration file: " - + lFile.getFile().getName()); + StringBuilder sb = new StringBuilder( + "Bad Archive configuration file: "); + sb.append(lFile.getFile().getName()); + if (archiveConfig != null) { + sb.append(archiveConfig.createErrorMsg()); + } + statusHandler.handle(Priority.ERROR, sb.toString()); } } catch (DataBindingException ex) { statusHandler.handle(Priority.ERROR, diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/server/notify/GfeNotification.java b/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/server/notify/GfeNotification.java index 362fde8d48..bf2dcb9bf7 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/server/notify/GfeNotification.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.gfe/src/com/raytheon/uf/common/dataplugin/gfe/server/notify/GfeNotification.java @@ -37,7 +37,8 @@ import com.raytheon.uf.common.util.SystemUtil; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Oct 7, 2014 #3684 randerso Added sourceId field + * Oct 7, 2014 #3684 randerso Added sourceId field + * Jun 25, 2015 #4573 randerso Made class abstract * * * @@ -45,7 +46,7 @@ import com.raytheon.uf.common.util.SystemUtil; * @version 1.0 */ @DynamicSerialize -public class GfeNotification implements IMessage { +public abstract class GfeNotification implements IMessage { private static final String localSourceID; static { String host = SystemUtil.getHostName(); diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/colormaps/Grid/simulated satellite temps.cmap b/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/colormaps/Grid/simulated satellite temps.cmap deleted file mode 100644 index 982d71f896..0000000000 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/colormaps/Grid/simulated satellite temps.cmap +++ /dev/null @@ -1,259 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/BLI.xml b/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/derivedParameters/definitions/BLI.xml similarity index 100% rename from cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/BLI.xml rename to edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/derivedParameters/definitions/BLI.xml diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/derivedParameters/definitions/DIRC.xml b/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/derivedParameters/definitions/DIRC.xml index e233f7ee08..6c9c244c4e 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/derivedParameters/definitions/DIRC.xml +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/derivedParameters/definitions/DIRC.xml @@ -18,7 +18,7 @@ See_the_AWIPS_II_Master_Rights_File_("Master_Rights_File.pdf")_for further_licensing_information. --> - + diff --git a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/GVV1hr.xml b/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/derivedParameters/definitions/GVV1hr.xml similarity index 100% rename from cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/GVV1hr.xml rename to edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/derivedParameters/definitions/GVV1hr.xml diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/derivedParameters/definitions/LTNG.xml b/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/derivedParameters/definitions/LTNG.xml index c5c213e0dd..44197dd88d 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/derivedParameters/definitions/LTNG.xml +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/derivedParameters/definitions/LTNG.xml @@ -18,5 +18,8 @@ See_the_AWIPS_II_Master_Rights_File_("Master_Rights_File.pdf")_for further_licensing_information. --> - + + + + diff --git a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/MAXUPHL.xml b/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/derivedParameters/definitions/MAXUPHL.xml similarity index 100% rename from cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/MAXUPHL.xml rename to edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/derivedParameters/definitions/MAXUPHL.xml diff --git a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/MaxWHRRR.xml b/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/derivedParameters/definitions/MaxWHRRR.xml similarity index 100% rename from cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/MaxWHRRR.xml rename to edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/derivedParameters/definitions/MaxWHRRR.xml diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/derivedParameters/definitions/WGS1hr.xml b/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/derivedParameters/definitions/WGS1hr.xml index f9c59fd0dd..3bc384713c 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/derivedParameters/definitions/WGS1hr.xml +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/derivedParameters/definitions/WGS1hr.xml @@ -3,7 +3,10 @@ - + + + + diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/styleRules/simsatImageryStyleRules.xml b/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/styleRules/simsatImageryStyleRules.xml deleted file mode 100644 index 6f753833dd..0000000000 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.grid/utility/common_static/base/styleRules/simsatImageryStyleRules.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - SBT122 - SBT124 - SBT125 - - - C - - -109 - 55 - - Grid/simulated satellite temps - - -80 -60 -40 -20 0 20 40 - - - - - - SBT123c - - - - 1 - 254 - - Sat/WV/SLC WV - - - diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.radar/res/spring/radar-dataplugin-common.xml b/edexOsgi/com.raytheon.uf.common.dataplugin.radar/res/spring/radar-dataplugin-common.xml index 1e16a182d0..91cbde8f6e 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.radar/res/spring/radar-dataplugin-common.xml +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.radar/res/spring/radar-dataplugin-common.xml @@ -362,5 +362,19 @@ 196 + + + + + + + + + + + + + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.redbook/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.dataplugin.redbook/META-INF/MANIFEST.MF index eb2bb480b1..81309112eb 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.redbook/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.redbook/META-INF/MANIFEST.MF @@ -2,13 +2,14 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Redbook Bundle-SymbolicName: com.raytheon.uf.common.dataplugin.redbook -Bundle-Version: 1.14.0.qualifier +Bundle-Version: 1.15.0.qualifier Bundle-Vendor: RAYTHEON -Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Export-Package: com.raytheon.uf.common.dataplugin.redbook, com.raytheon.uf.common.dataplugin.redbook.blocks Require-Bundle: com.raytheon.uf.common.serialization, javax.persistence, com.raytheon.uf.common.dataplugin, com.raytheon.uf.common.status -Import-Package: com.raytheon.uf.common.util +Import-Package: com.raytheon.uf.common.localization, + com.raytheon.uf.common.util diff --git a/cave/com.raytheon.viz.redbook/src/com/raytheon/viz/redbook/RedbookWMOMap.java b/edexOsgi/com.raytheon.uf.common.dataplugin.redbook/src/com/raytheon/uf/common/dataplugin/redbook/RedbookWMOMap.java similarity index 57% rename from cave/com.raytheon.viz.redbook/src/com/raytheon/viz/redbook/RedbookWMOMap.java rename to edexOsgi/com.raytheon.uf.common.dataplugin.redbook/src/com/raytheon/uf/common/dataplugin/redbook/RedbookWMOMap.java index 825d1f5926..a75c1bb9ef 100644 --- a/cave/com.raytheon.viz.redbook/src/com/raytheon/viz/redbook/RedbookWMOMap.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.redbook/src/com/raytheon/uf/common/dataplugin/redbook/RedbookWMOMap.java @@ -17,7 +17,7 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.viz.redbook; +package com.raytheon.uf.common.dataplugin.redbook; import java.io.File; import java.util.HashMap; @@ -35,10 +35,12 @@ import com.raytheon.uf.common.localization.PathManagerFactory; * *
  * SOFTWARE HISTORY
- * Date			Ticket#		Engineer	Description
- * ------------	----------	-----------	--------------------------
- * May 30, 2008				chammack	Initial creation
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * May 30, 2008             chammack    Initial creation
  * Nov 04, 2013 2361        njensen     Use JAXB instead of SerializationUtil
+ * Jun 25, 2015 4512        mapeters    Refactored from viz.redbook, made mapping
+ *                                      private, added getValue() and addEntry()
  * 
  * 
* @@ -57,32 +59,35 @@ public class RedbookWMOMap { public String projection; } - public HashMap mapping; + private HashMap mapping = new HashMap<>(); - public static RedbookWMOMap load() throws Exception { + public Info getValue(String key) { + return mapping.get(key); + } + + public void addEntry(String key, Info value) { + mapping.put(key, value); + } + + public static RedbookWMOMap load() { File file = PathManagerFactory.getPathManager().getStaticFile( "redbook/redbookMapping.xml"); - try { - RedbookWMOMap map = JAXB.unmarshal(file, RedbookWMOMap.class); + RedbookWMOMap map = JAXB.unmarshal(file, RedbookWMOMap.class); - // add ability for comma separated values in xml file - RedbookWMOMap secondMap = new RedbookWMOMap(); - secondMap.mapping = new HashMap(); - secondMap.mapping.putAll(map.mapping); - for (String key : map.mapping.keySet()) { - if (key.contains(",")) { - String[] keys = key.split(","); - for (String theKey : keys) { - secondMap.mapping.put(theKey.trim(), - secondMap.mapping.get(key)); - } - secondMap.mapping.remove(key); + // add ability for comma separated values in xml file + RedbookWMOMap secondMap = new RedbookWMOMap(); + secondMap.mapping = new HashMap(); + secondMap.mapping.putAll(map.mapping); + for (String key : map.mapping.keySet()) { + if (key.contains(",")) { + String[] keys = key.split(","); + for (String theKey : keys) { + secondMap.mapping.put(theKey.trim(), + secondMap.mapping.get(key)); } + secondMap.mapping.remove(key); } - return secondMap; - } catch (Exception e) { - e.printStackTrace(); - throw e; } + return secondMap; } } diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/VM_global_library.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/VM_global_library.vm index 5fcb86777c..fc517a5643 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/VM_global_library.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/VM_global_library.vm @@ -79,9 +79,9 @@ near ${singType}${list.get(${markers},0).name}. #set($marker1 = ${list.get(${markers},${startCounter}).name}) #set($marker2 = ${list.get(${markers},${endCounter}).name}) #if(${startCounter} == ${endCounter}) -near ${singType}${marker1}...## +near ${singType}${marker1}, ## #else -between ${plurType}${marker1} and ${marker2}...## +between ${plurType}${marker1} and ${marker2}, ## #end #set($phraseCount = $phraseCount + 1) #set($startIdx = $intIndex) @@ -108,7 +108,7 @@ ${singType}${marker1} and near ${singType}${marker2}. #set($marker1 = ${list.get(${markers},${startCounter}).name}) #set($marker2 = ${list.get(${markers},${endCounter}).name}) #set($marker3 = ${list.get(${markers},${counter}).name}) -between ${plurType}${marker1} and ${marker2}...and near ${singType}${marker3}. +between ${plurType}${marker1} and ${marker2}, and near ${singType}${marker3}. #end #end #set($counter = $counter + 1) @@ -118,11 +118,11 @@ near ${plurType}## #foreach($item in $markers) #set($counter = $counter + 1) #if($size > 1 && $counter == $size) -AND ${item.name}. +and ${item.name}. #elseif($size == 1 && $counter == $size) ${item.name}. #else -${item.name}...## +${item.name}, ## #end #end #end @@ -345,7 +345,7 @@ ISSUED BY NATIONAL WEATHER SERVICE ${backupSite} #macro(headlineext $officeLoc $backupSite $extend) #if($extend) -#set($issueVar = "extended a") +#set($issueVar = "extended the") #else #set($issueVar = "issued a") #end @@ -479,7 +479,7 @@ along a line extending from #outputLineOfStorms($used1, $nearText, $nearThreshol #set($used2 = []) #lineOfStorms($used2, $used, $points2, $threshold, $units) #if(${used1.size()} == ${used2.size()}) -...or along a line extending from #outputLineOfStorms($used2, $nearText, $nearThreshold, $overThreshold, $units)## +, or along a line extending from #outputLineOfStorms($used2, $nearText, $nearThreshold, $overThreshold, $units)## #end #end #else @@ -503,11 +503,11 @@ ${point1.roundedDistance} #capitalize($units "NONE") #direction(${point1.opposit ${location}## #if($point2 && $useSecondRef && ${point2.name} != ${point1.name}) #if($point2.roundedDistance <= $overThreshold) -...or ${overText} ## +, or ${overText} ## #elseif($point2.roundedDistance <= $nearThreshold) -...or ${nearText} ## +, or ${nearText} ## #else -...or ${point2.roundedDistance} #capitalize($units "NONE") #direction(${point2.oppositeRoundedAzimuth}) of ## +, or ${point2.roundedDistance} #capitalize($units "NONE") #direction(${point2.oppositeRoundedAzimuth}) of ## #end #if(${point2.partOfArea}) #set($location = "#areaFormat(${point2.partOfArea} true false false) ${point2.name}") @@ -1308,8 +1308,8 @@ At ${dateUtil.format(${time}, ${timeFormat.clock}, ${localtimezone})}## ## This macro will output a pathcast based on the thresholds/parameters ## defined in the product's .xml configuration file ## 1 - These dangerous storms will be near... -## Kansas City...Independence...Grain Valley around 800 PM CDT... -## Lee's Summit...Grandview...Raytown around 805 PM CDT... +## Kansas City, Independence, Grain Valley around 800 PM CDT. +## Lee's Summit, Grandview, Raytown around 805 PM CDT. ## Inputs: pathcastLead (string containing a lead-in to the pathcast) ## otherLead (string containing a lead-in to the list of other (typically 3rd level) towns ## pathCast (array of ClosestPoint objects) @@ -1343,7 +1343,7 @@ ${pathcastLead} #if($count == $numCities - 1) #set($output = "${output} and ") #elseif($count < $numCities) -#set($output = "${output}...") +#set($output = "${output}, ") #end #end #set($output = "${output} around ${dateUtil.format(${pc.time}, ${timeFormat.clock}, ${pc.timeZone})}.") @@ -1368,7 +1368,7 @@ ${location}## #if($count == $numOtherPoints - 1) and ## #elseif($count < $numOtherPoints) -...## +, ## #else . #end @@ -1384,7 +1384,7 @@ ${otherLead} will remain over ${noLocPhrase} of ## ### NEED TO CODE THIS ONCE SECTION IS ADDED #set($numOtherPoints = ${list.size($otherPoints)}) #if($numOtherPoints > 0) -...including the following locations...## +, including the following locations: ## #set($count = 0) #foreach(${loc} in ${otherPoints}) #set($count = $count + 1) @@ -1398,11 +1398,13 @@ ${location}## #if($count == $numOtherPoints - 1) and ## #elseif($count < $numOtherPoints) -...## +, ## #else .## #end #end +#else +.## #end #end @@ -1517,8 +1519,8 @@ ${inString}...## ## Joppa... Phelan... ## Arab... Wilburn... ## 3 - Locations in the warning include but are not limited to... -## Quinton...Susan Moore...West Jefferson...Warrior...Rosa, -## Fairview...Locust Fork...Trafford, Argo(--- yourself), Anderson, and Alton +## Quinton, Susan Moore, West Jefferson, Warrior, Rosa, +## Fairview, Locust Fork, Trafford, Argo(--- yourself), Anderson, and Alton ## Inputs: bulletLead (string containing a lead-in to the list of cities e.g. Locations Impacted Include...) ## stormType (string containing the storm type e.g. severe thunderstorm) ## columns (number of columns to list the cities (0 is a normal ellipsees separated list) @@ -1544,7 +1546,7 @@ ${bulletLead} #set($count = $count + 1) #if($count < $numMajorPoints) #if($columns == 0) -#set($strOutput = "${location}...") +#set($strOutput = "${location}, ") #else #set($strOutput = "${location}...") #end @@ -1600,7 +1602,7 @@ ${ruralPhrase} will remain over ${noLocPhrase} OF #headlineLocList(${areas} true #if(${numMinorPoints} == 1) , which includes ## #elseif(${numMinorPoints} > 1) -, including the following locations...## +, including the following locations: ## #else .## #end diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/airportWeatherWarning.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/airportWeatherWarning.vm index 41b6431024..d30aba41fb 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/airportWeatherWarning.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/airportWeatherWarning.vm @@ -13,13 +13,13 @@ AWW${siteId} ${ugcline} #if(${productClass}=="T") -TEST...AIRPORT WEATHER WARNING...TEST## +TEST...Airport Weather Warning...TEST## #else -AIRPORT WEATHER WARNING +Airport Weather Warning #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/arealFloodAdvisory.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/arealFloodAdvisory.vm index 3452973607..a205f2201e 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/arealFloodAdvisory.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/arealFloodAdvisory.vm @@ -114,13 +114,13 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} FLS${siteId} #if(${productClass}=="T") -TEST...FLOOD ADVISORY...TEST +TEST...Flood Advisory...TEST #else -FLOOD ADVISORY +Flood Advisory #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} ${ugcline} @@ -134,7 +134,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/arealFloodAdvisoryFollowup.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/arealFloodAdvisoryFollowup.vm index 24b0b04338..ca9d460f93 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/arealFloodAdvisoryFollowup.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/arealFloodAdvisoryFollowup.vm @@ -24,17 +24,17 @@ #set($advType = "FLOOD ADVISORY") #set($advTypeShort = "minor flooding") #if(${list.contains(${bullets}, "small")}) - #set($advType = "SMALL STREAM FLOOD ADVISORY") - #set($advTypeShort = "small stream flooding") + #set($advType = "SMALL STREAM FLOOD ADVISORY") + #set($advTypeShort = "small stream flooding") #elseif(${list.contains(${bullets}, "uss")}) - #set($advType = "URBAN AND SMALL STREAM FLOOD ADVISORY") - #set($advTypeShort = "urban and small stream flooding") + #set($advType = "URBAN AND SMALL STREAM FLOOD ADVISORY") + #set($advTypeShort = "urban and small stream flooding") #elseif(${list.contains(${bullets}, "arroyo")}) - #set($advType = "ARROYO AND SMALL STREAM FLOOD ADVISORY") - #set($advTypeShort = "arroyo and small stream flooding") + #set($advType = "ARROYO AND SMALL STREAM FLOOD ADVISORY") + #set($advTypeShort = "arroyo and small stream flooding") #elseif(${list.contains(${bullets}, "hydrologic")}) - #set($advType = "HYDROLOGIC ADVISORY") - #set($advTypeShort = "minor flooding") + #set($advType = "HYDROLOGIC ADVISORY") + #set($advTypeShort = "minor flooding") #end #set($hycType = "") @@ -166,13 +166,13 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} FLS${siteId} #if(${productClass}=="T") -TEST...FLOOD ADVISORY...TEST +TEST...Flood Advisory...TEST #else -FLOOD ADVISORY +Flood Advisory #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -190,7 +190,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -217,11 +217,10 @@ THIS IS A TEST MESSAGE.## #### GP End #if(${list.contains(${bullets}, "recedingWater")}) -THE HIGH WATER IS RECEDING...AND IS NO LONGER EXPECTED TO POSE A THREAT. PLEASE CONTINUE TO HEED ANY ROAD CLOSURES. - +The high water is receding, and is no longer expected to pose a threat. Please continue to heed any road closures. #end #if(${list.contains(${bullets}, "rainEnded")}) -THE HEAVY RAIN HAS ENDED...AND FLOODING IS NO LONGER EXPECTED TO POSE A THREAT. +The heavy rain has ended, and flooding is no longer expected to pose a threat. #end #end @@ -416,13 +415,13 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} FLS${siteId} #if(${productClass}=="T") -TEST...FLOOD ADVISORY...TEST +TEST...Flood Advisory...TEST #else -FLOOD ADVISORY +Flood Advisory #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -440,7 +439,7 @@ ${ugclinecan} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -486,7 +485,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -639,13 +638,13 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} FLS${siteId} #if(${productClass}=="T") -TEST...FLOOD ADVISORY...TEST +TEST...Flood Advisory...TEST #else -FLOOD ADVISORY +Flood Advisory #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -663,7 +662,7 @@ ${ugclinecan} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -707,7 +706,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/arealFloodWarning.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/arealFloodWarning.vm index 3be29d2552..f96d37ba70 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/arealFloodWarning.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/arealFloodWarning.vm @@ -77,13 +77,13 @@ FLW${siteId} BULLETIN - IMMEDIATE BROADCAST REQUESTED #if(${productClass}=="T") -TEST...FLOOD WARNING...TEST +TEST...Flood Warning...TEST #else -FLOOD WARNING +Flood Warning #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} ${ugcline} @@ -97,7 +97,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/arealFloodWarningFollowup.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/arealFloodWarningFollowup.vm index 2be4f54e56..8075ead714 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/arealFloodWarningFollowup.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/arealFloodWarningFollowup.vm @@ -63,11 +63,11 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} FLS${siteId} #if(${productClass}=="T") -TEST...FLOOD STATEMENT...TEST +TEST...Flood Statement...TEST #else -FLOOD STATEMENT +Flood Statement #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) ${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/burnScarFlashFloodWarning.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/burnScarFlashFloodWarning.vm index c99305d34d..9a04f94011 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/burnScarFlashFloodWarning.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/burnScarFlashFloodWarning.vm @@ -49,13 +49,13 @@ ${ugcline} #################################### MND HEADER ################################### BULLETIN - EAS ACTIVATION REQUESTED #if(${productClass}=="T") -TEST...FLASH FLOOD WARNING...TEST +TEST...Flash Flood Warning...TEST #else -FLASH FLOOD WARNING +Flash Flood Warning #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/burnScarFlashFloodWarningFollowup.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/burnScarFlashFloodWarningFollowup.vm index 54e677cb0c..e0f322f4b8 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/burnScarFlashFloodWarningFollowup.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/burnScarFlashFloodWarningFollowup.vm @@ -42,13 +42,13 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} FFS${siteId} #if(${productClass}=="T") -TEST...FLASH FLOOD STATEMENT...TEST +TEST...Flash Flood Statement...TEST #else -FLASH FLOOD STATEMENT +Flash Flood Statement #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${action}=="COR" && ${cancelareas}) @@ -94,7 +94,7 @@ ${ugcline} #end #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -170,7 +170,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -191,7 +191,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/extremeWindWarning.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/extremeWindWarning.vm index 64f3992bf6..e7872cc54d 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/extremeWindWarning.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/extremeWindWarning.vm @@ -20,13 +20,13 @@ ${ugcline} BULLETIN - EAS ACTIVATION REQUESTED #if(${productClass}=="T") -TEST...EXTREME WIND WARNING...TEST +TEST...Extreme Wind Warning...TEST #else -EXTREME WIND WARNING +Extreme Wind Warning #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/extremeWindWarningFollowup.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/extremeWindWarningFollowup.vm index 966d00392b..5fae00589e 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/extremeWindWarningFollowup.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/extremeWindWarningFollowup.vm @@ -30,13 +30,13 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} SVS${siteId} #if(${productClass}=="T") -TEST...SEVERE WEATHER STATEMENT...TEST +TEST...Severe Weather Statement...TEST #else -SEVERE WEATHER STATEMENT +Severe Weather Statement #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -53,7 +53,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -138,13 +138,13 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} SVS${siteId} #if(${productClass}=="T") -TEST...SEVERE WEATHER STATEMENT...TEST +TEST...Severe Weather Statement...TEST #else -SEVERE WEATHER STATEMENT +Severe Weather Statement #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -161,7 +161,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -309,13 +309,13 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} SVS${siteId} #if(${productClass}=="T") -TEST...SEVERE WEATHER STATEMENT...TEST +TEST...Severe Weather Statement...TEST #else -SEVERE WEATHER STATEMENT +Severe Weather Statement #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -332,7 +332,7 @@ ${ugclinecan} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -380,7 +380,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -490,10 +490,10 @@ The safest place to be during a major landfalling hurricane is in a reinforced i ${WMOId} ${vtecOffice} 000000 ${BBBId} SVS${siteId} -SEVERE WEATHER STATEMENT -NATIONAL WEATHER SERVICE ${officeShort} +Severe Weather Statement +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} ${ugcline} @@ -506,7 +506,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/fireWarning.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/fireWarning.vm index 0675c9f1cc..a0cc04daa3 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/fireWarning.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/fireWarning.vm @@ -15,9 +15,9 @@ FRW${siteId} BULLETIN - EAS ACTIVATION REQUESTED #if(${productClass}=="T") -TEST...FIRE WARNING...TEST +TEST...Fire Warning...TEST #else -FIRE WARNING +Fire Warning #end #set($requestedBy = "!** ENTER REQUESTING AGENCY NAME HERE **!") #if(${list.contains(${bullets}, "agency1")}) @@ -26,12 +26,12 @@ FRW${siteId} #if(${list.contains(${bullets}, "agency2")}) #set($requestedBy = "Example Agency 2") #end -#set($agencyNameLine = "REQUESTED BY ${requestedBy}") +#set($agencyNameLine = "Requested by ${requestedBy}") #capitalize(${agencyNameLine} "ALL") -RELAYED BY NATIONAL WEATHER SERVICE ${officeShort} +Relayed by National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/flashFloodWarning.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/flashFloodWarning.vm index e61fef3636..979d194a77 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/flashFloodWarning.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/flashFloodWarning.vm @@ -42,13 +42,13 @@ ${ugcline} #################################### MND HEADER ################################### BULLETIN - EAS ACTIVATION REQUESTED #if(${productClass}=="T") -TEST...FLASH FLOOD WARNING...TEST +TEST...Flash Flood Warning...TEST #else -FLASH FLOOD WARNING +Flash Flood Warning #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/flashFloodWarningFollowup.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/flashFloodWarningFollowup.vm index caae7fc3d6..2804dac1b9 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/flashFloodWarningFollowup.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/flashFloodWarningFollowup.vm @@ -42,13 +42,13 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} FFS${siteId} #if(${productClass}=="T") -TEST...FLASH FLOOD STATEMENT...TEST +TEST...Flash Flood Statement...TEST #else -FLASH FLOOD STATEMENT +Flash Flood Statement #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${action}=="COR" && ${cancelareas}) @@ -94,7 +94,7 @@ ${ugcline} #end #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -191,7 +191,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -212,7 +212,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/impactSevereThunderstormWarning.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/impactSevereThunderstormWarning.vm index 609876f4dd..9e1b1fdec6 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/impactSevereThunderstormWarning.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/impactSevereThunderstormWarning.vm @@ -308,13 +308,13 @@ ${ugcline} BULLETIN - ${easActivation} #if(${productClass}=="T") -TEST...SEVERE THUNDERSTORM WARNING...TEST +TEST...Severe Thunderstorm Warning...TEST #else -SEVERE THUNDERSTORM WARNING +Severe Thunderstorm Warning #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/impactSevereWeatherStatement.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/impactSevereWeatherStatement.vm index d0cdd87b6e..d2caf70c9f 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/impactSevereWeatherStatement.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/impactSevereWeatherStatement.vm @@ -42,7 +42,7 @@ ############################################ ##PATHCAST LEAD VARIABLE ADD LATER????? #if(${phenomena}=="SV") - #set($eventType = "severe thunderstorm") + #set($eventType = "SEVERE THUNDERSTORM") #if(${stormType} == "line") #set($reportType1 = "severe thunderstorms were") #set($reportType2 = "these storms were") @@ -55,7 +55,7 @@ #set($pathcastLead = "this severe storm") #end #elseif(${phenomena}=="TO") - #set($eventType = "tornado") + #set($eventType = "TORNADO") #set($torTag = "radar indicated") #set($torThreat = "") #set($torHazard = "tornado") @@ -86,13 +86,13 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} SVS${siteId} #if(${productClass}=="T") -TEST...SEVERE WEATHER STATEMENT...TEST +TEST...Severe Weather Statement...TEST #else -SEVERE WEATHER STATEMENT +Severe Weather Statement #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${action}=="COR" && ${cancelareas}) @@ -132,7 +132,7 @@ ${ugcline} #end #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -358,7 +358,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -378,7 +378,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/impactSpecialMarineWarning.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/impactSpecialMarineWarning.vm index 3f285d0598..281f0205bd 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/impactSpecialMarineWarning.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/impactSpecialMarineWarning.vm @@ -41,13 +41,13 @@ ${ugcline} BULLETIN - IMMEDIATE BROADCAST REQUESTED #if(${productClass}=="T") -TEST...SPECIAL MARINE WARNING...TEST +TEST...Special Marine Warning...TEST #else -SPECIAL MARINE WARNING +Special Marine Warning #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/impactSpecialMarineWarningFollowup.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/impactSpecialMarineWarningFollowup.vm index 5f03a8c88b..d6234556de 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/impactSpecialMarineWarningFollowup.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/impactSpecialMarineWarningFollowup.vm @@ -47,13 +47,13 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} MWS${siteId} #if(${productClass}=="T") -TEST...MARINE WEATHER STATEMENT...TEST +TEST...Marine Weather Statement...TEST #else -MARINE WEATHER STATEMENT +Marine Weather Statement #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -76,7 +76,7 @@ ${ugclinecan} ${ugcline} /${productClass}.${action}.${vtecOffice}.MA.W.${oldvtec}.000000T0000Z-${dateUtil.format(${expire}, ${timeFormat.ymdthmz}, 15)}/ #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -272,7 +272,7 @@ $$ ${ugcline} /${productClass}.CON.${vtecOffice}.MA.W.${oldvtec}.000000T0000Z-${dateUtil.format(${expire}, ${timeFormat.ymdthmz}, 15)}/ -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -285,7 +285,7 @@ THIS IS A TEST MESSAGE.## #elseif(${CORCAN}=="true") ${ugcline} /${productClass}.COR.${vtecOffice}.MA.W.${oldvtec}.000000T0000Z-${dateUtil.format(${expire}, ${timeFormat.ymdthmz}, 15)}/ -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/impactTornadoWarning.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/impactTornadoWarning.vm index 38d15ffd44..de7b9822a9 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/impactTornadoWarning.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/impactTornadoWarning.vm @@ -189,13 +189,13 @@ ${ugcline} BULLETIN - EAS ACTIVATION REQUESTED #if(${productClass}=="T") -TEST...TORNADO WARNING...TEST +TEST...Tornado Warning...TEST #else -TORNADO WARNING +Tornado Warning #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} ## end of addition #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/marineWeatherStatement.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/marineWeatherStatement.vm index f4a4c42ac7..0d62300d7c 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/marineWeatherStatement.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/marineWeatherStatement.vm @@ -29,13 +29,13 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} MWS${siteId} #if(${productClass}=="T") -TEST...MARINE WEATHER STATEMENT...TEST +TEST...Marine Weather Statement...TEST #else -MARINE WEATHER STATEMENT +Marine Weather Statement #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") ...THIS MESSAGE IS FOR TEST PURPOSES ONLY... @@ -46,7 +46,7 @@ NATIONAL WEATHER SERVICE ${officeShort} ## Deleted VTEC and Marine Zone Name lines to come in line with NWS Directive 10-314 ###################################################################### ${ugcline} -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/marineWeatherStatementAshfall.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/marineWeatherStatementAshfall.vm index 8c5b0905b3..e493b86124 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/marineWeatherStatementAshfall.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/marineWeatherStatementAshfall.vm @@ -23,13 +23,13 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} MWS${siteId} #if(${productClass}=="T") -TEST...MARINE WEATHER STATEMENT...TEST +TEST...Marine Weather Statement...TEST #else -MARINE WEATHER STATEMENT +Marine Weather Statement #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") ...THIS MESSAGE IS FOR TEST PURPOSES ONLY... @@ -40,7 +40,7 @@ NATIONAL WEATHER SERVICE ${officeShort} ## Deleted VTEC and Marine Zone Name lines to come in line with NWS Directive 10-314 ###################################################################### ${ugcline} -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/nonConvectiveFlashFloodWarning.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/nonConvectiveFlashFloodWarning.vm index f7a83dd764..6ffa7a615e 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/nonConvectiveFlashFloodWarning.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/nonConvectiveFlashFloodWarning.vm @@ -128,13 +128,13 @@ ${ugcline} BULLETIN - EAS ACTIVATION REQUESTED #if(${productClass}=="T") -TEST...FLASH FLOOD WARNING...TEST +TEST...Flash Flood Warning...TEST #else -FLASH FLOOD WARNING +Flash Flood Warning #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/nonConvectiveFlashFloodWarningFollowup.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/nonConvectiveFlashFloodWarningFollowup.vm index cbe6485d11..7ab92b67f9 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/nonConvectiveFlashFloodWarningFollowup.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/nonConvectiveFlashFloodWarningFollowup.vm @@ -147,13 +147,13 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} FFS${siteId} #if(${productClass}=="T") -TEST...FLASH FLOOD STATEMENT...TEST +TEST...Flash Flood Statement...TEST #else -FLASH FLOOD STATEMENT +Flash Flood Statement #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} ${ugcline} @@ -167,7 +167,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #end @@ -407,13 +407,13 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} FFS${siteId} #if(${productClass}=="T") -TEST...FLASH FLOOD STATEMENT...TEST +TEST...Flash Flood Statement...TEST #else -FLASH FLOOD STATEMENT +Flash Flood Statement #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} ${ugclinecan} @@ -427,7 +427,7 @@ ${ugclinecan} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -467,7 +467,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -663,13 +663,13 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} FFS${siteId} #if(${productClass}=="T") -TEST...FLASH FLOOD STATEMENT...TEST +TEST...Flash Flood Statement...TEST #else -FLASH FLOOD STATEMENT +Flash Flood Statement #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} ${ugclinecan} @@ -683,7 +683,7 @@ ${ugclinecan} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -715,7 +715,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/severeThunderstormWarning.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/severeThunderstormWarning.vm index e948c12edb..004d19d8a4 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/severeThunderstormWarning.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/severeThunderstormWarning.vm @@ -206,13 +206,13 @@ ${ugcline} BULLETIN - ${easActivation} #if(${productClass}=="T") -TEST...SEVERE THUNDERSTORM WARNING...TEST +TEST...Severe Thunderstorm Warning...TEST #else -SEVERE THUNDERSTORM WARNING +Severe Thunderstorm Warning #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/severeWeatherStatement.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/severeWeatherStatement.vm index 2b41fe465d..86c63274d2 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/severeWeatherStatement.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/severeWeatherStatement.vm @@ -57,13 +57,13 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} SVS${siteId} #if(${productClass}=="T") -TEST...SEVERE WEATHER STATEMENT...TEST +TEST...Severe Weather Statement...TEST #else -SEVERE WEATHER STATEMENT +Severe Weather Statement #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${action}=="COR" && ${cancelareas}) @@ -103,7 +103,7 @@ ${ugcline} #end #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -328,7 +328,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -348,7 +348,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/shortTermForecast.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/shortTermForecast.vm index 6cce67f020..1d2233235e 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/shortTermForecast.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/shortTermForecast.vm @@ -18,13 +18,13 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} NOW${siteId} #if(${productClass}=="T") -TEST...SHORT TERM FORECAST...TEST +TEST...Short Term Forecast...TEST #else -SHORT TERM FORECAST +Short Term Forecast #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -37,7 +37,7 @@ ${ugcline} #set($zoneList = "${zoneList}#capitalize(${area.name} 'ALL')-") #end ${zoneList} -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/significantWeatherAdvisory.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/significantWeatherAdvisory.vm index 4960e9e85f..edfe1a8526 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/significantWeatherAdvisory.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/significantWeatherAdvisory.vm @@ -108,14 +108,14 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} SPS${siteId} #if(${productClass}=="T") -TEST...SPECIAL WEATHER STATEMENT...TEST## +TEST...Special Weather Statement...TEST## #else -SPECIAL WEATHER STATEMENT## +Special Weather Statement## #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -132,7 +132,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/specialMarineWarning.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/specialMarineWarning.vm index 08c2c476cc..08ebc9cadd 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/specialMarineWarning.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/specialMarineWarning.vm @@ -33,13 +33,13 @@ ${ugcline} BULLETIN - IMMEDIATE BROADCAST REQUESTED #if(${productClass}=="T") -TEST...SPECIAL MARINE WARNING...TEST +TEST...Special Marine Warning...TEST #else -SPECIAL MARINE WARNING +Special Marine Warning #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/specialMarineWarningFollowup.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/specialMarineWarningFollowup.vm index 3f60cce918..6317210173 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/specialMarineWarningFollowup.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/specialMarineWarningFollowup.vm @@ -34,13 +34,13 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} MWS${siteId} #if(${productClass}=="T") -TEST...MARINE WEATHER STATEMENT...TEST +TEST...Marine Weather Statement...TEST #else -MARINE WEATHER STATEMENT +Marine Weather Statement #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -66,7 +66,7 @@ ${ugclinecan} ${ugcline} /${productClass}.${action}.${vtecOffice}.MA.W.${oldvtec}.000000T0000Z-${dateUtil.format(${expire}, ${timeFormat.ymdthmz}, 15)}/ #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/specialWeatherStatement.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/specialWeatherStatement.vm index 4590a9c786..7dbafc136d 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/specialWeatherStatement.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/specialWeatherStatement.vm @@ -171,13 +171,13 @@ ${WMOId} ${vtecOffice} 000000 ${BBBId} SPS${siteId} #if(${productClass}=="T") -TEST...SPECIAL WEATHER STATEMENT...TEST +TEST...Special Weather Statement...TEST #else -SPECIAL WEATHER STATEMENT +Special Weather Statement #end -NATIONAL WEATHER SERVICE ${officeShort} +National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") @@ -193,7 +193,7 @@ ${ugcline} -## #end -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/tornadoWarning.vm b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/tornadoWarning.vm index a752f1072d..6280a041b1 100755 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/tornadoWarning.vm +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/utility/common_static/base/warngen/tornadoWarning.vm @@ -107,14 +107,14 @@ ${ugcline} BULLETIN - EAS ACTIVATION REQUESTED #if(${productClass}=="T") -TEST...TORNADO WARNING...TEST +TEST...Tornado Warning...TEST #else -TORNADO WARNING +Tornado Warning #end -##NATIONAL WEATHER SERVICE ${officeShort} +##National Weather Service ${officeShort} National Weather Service ${officeShort} #backupText(${backupSite}) -#capitalize(${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} "ALL") +${dateUtil.format(${now}, ${timeFormat.header}, ${localtimezone})} ## end of addition #if(${productClass}=="T") diff --git a/edexOsgi/com.raytheon.uf.common.hydro/build.properties b/edexOsgi/com.raytheon.uf.common.hydro/build.properties index 5791d48d5f..73974cda80 100644 --- a/edexOsgi/com.raytheon.uf.common.hydro/build.properties +++ b/edexOsgi/com.raytheon.uf.common.hydro/build.properties @@ -2,4 +2,5 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ - res/ + res/,\ + utility/ diff --git a/cave/com.raytheon.viz.hydro/localization/hydro/shefIssue.xml b/edexOsgi/com.raytheon.uf.common.hydro/utility/common_static/base/hydro/shefIssue.xml similarity index 100% rename from cave/com.raytheon.viz.hydro/localization/hydro/shefIssue.xml rename to edexOsgi/com.raytheon.uf.common.hydro/utility/common_static/base/hydro/shefIssue.xml diff --git a/edexOsgi/com.raytheon.uf.edex.ndm/src/com/raytheon/uf/edex/ndm/ingest/NationalDatasetIngester.java b/edexOsgi/com.raytheon.uf.edex.ndm/src/com/raytheon/uf/edex/ndm/ingest/NationalDatasetIngester.java index a67bfd3e32..878b5dddf2 100644 --- a/edexOsgi/com.raytheon.uf.edex.ndm/src/com/raytheon/uf/edex/ndm/ingest/NationalDatasetIngester.java +++ b/edexOsgi/com.raytheon.uf.edex.ndm/src/com/raytheon/uf/edex/ndm/ingest/NationalDatasetIngester.java @@ -28,7 +28,6 @@ import java.util.Map; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; -import com.raytheon.uf.edex.core.EdexException; /** * National Dataset Maintenance ingester. @@ -44,6 +43,7 @@ import com.raytheon.uf.edex.core.EdexException; * Aug 24,2011 10775 rferrel Fixed error in processEvent and added * check on statusHandler messages. * Mar 06, 2014 2876 mpduff New NDM plugin. + * Jun 25, 2015 4512 mapeters Removed unnecessary Exception throw. * * * @@ -61,7 +61,7 @@ public class NationalDatasetIngester implements IDataSetIngester { * * @param filename * @param listener - * @return + * @return the registered listener */ @Override public INationalDatasetSubscriber registerListener(String filename, @@ -108,7 +108,7 @@ public class NationalDatasetIngester implements IDataSetIngester { * * @see org.apache.camel.Processor#process(org.apache.camel.Exchange) */ - public void processEvent(File file) throws EdexException { + public void processEvent(File file) { String fileName = file.getName(); IUFStatusHandler statusHandler = UFStatus .getHandler(NationalDatasetIngester.class); diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.qpf/src/com/raytheon/uf/edex/plugin/qpf/QPF.java b/edexOsgi/com.raytheon.uf.edex.plugin.qpf/src/com/raytheon/uf/edex/plugin/qpf/QPF.java index 1135d01ca3..4a6dd458b1 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.qpf/src/com/raytheon/uf/edex/plugin/qpf/QPF.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.qpf/src/com/raytheon/uf/edex/plugin/qpf/QPF.java @@ -108,7 +108,8 @@ import com.vividsolutions.jts.geom.Coordinate; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 02/17/2009 1981 dhladky Initial Creation. - * 02/26/2014 2836 dhladky Added diagnostic information. + * 02/26/2014 2836 dhladky Added diagnostic information. + * 07/02/2015 3073 dhladky Fixed walking off the two dimensional array. * * * @author dhladky @@ -596,16 +597,8 @@ public class QPF { while (doSearch) { for (id = imove_last - 2; id <= imove_last + 2; id++) { for (jd = jmove_last - 2; jd <= jmove_last + 2; jd++) { - - try { - if (binc[id + 10][jd + 10] >= 0.0) { - continue; - } - } catch (ArrayIndexOutOfBoundsException aioe) { - statusHandler.error("jd = "+jd+" id = "+id +"\n" - +"jd + 10 = "+(jd+10)+" id + 10 = "+(id + 10) +"\n" - +"imove_last = "+imove_last+" jmove_last = "+jmove_last +"\n" - +"binc[][] size = "+binc.length, aioe); + if (walkSurroundingValues(binc, id, jd, 10, 10) >= 0.0) { + continue; } // Displace the portion of grid1 that lies between JMIN to @@ -689,6 +682,46 @@ public class QPF { r.pb = pb; return r; } + + /** + * Attempts to scan values +10 i and j from the value being evaluated for the BINCOR test. + * It falls back by 1 in succession if you walk off the end of the two dimensional array. + * Attempting to stay within the grids boundaries. + * + * @param binc + * @param id + * @param jd + * @param i + * @param j + * @return + */ + private float walkSurroundingValues(float binc[][], int id, int jd, int i, int j) { + + float val = 0.0f; + + try { + val = binc[id + i][jd + j]; + } catch (ArrayIndexOutOfBoundsException aioe) { + // recurse until either you stay within or exhaust ability to stay within the array. + if (i > 1 && j > 1) { + i = i - 1; + j = j - 1; + } else { + statusHandler + .error("Exhausted attempts to constrain grid walking, i and j values out of bounds: " + + i + + " " + + j + + " values for grid at this point are unreliable!", + aioe); + return val; + } + val = walkSurroundingValues(binc, id, jd, i, j); + } + + return val; + + } private class BincorDirectResult { public int jmove; diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/Documentation/SampleFiles/ReadMe b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/Documentation/SampleFiles/ReadMe deleted file mode 100644 index bf9de37a52..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/Documentation/SampleFiles/ReadMe +++ /dev/null @@ -1,4 +0,0 @@ -This folder contains sample NDM files. - -Dropping RedbookHazardMenus.xml into the /awips2/edex/data/ndm directory will generate an override of the SPC hazards menu. -RedbookHazardMenus.xml as written here will generate the base version of the SPC hazard menus. \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/Documentation/SampleFiles/RedbookCPCMenus.xml b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/Documentation/SampleFiles/RedbookCPCMenus.xml deleted file mode 100644 index f4aeea4298..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/Documentation/SampleFiles/RedbookCPCMenus.xml +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/Documentation/SampleFiles/RedbookHPCMenus.xml b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/Documentation/SampleFiles/RedbookHPCMenus.xml deleted file mode 100644 index b75af9ade8..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/Documentation/SampleFiles/RedbookHPCMenus.xml +++ /dev/null @@ -1,259 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/Documentation/SampleFiles/RedbookHazardMenus.xml b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/Documentation/SampleFiles/RedbookHazardMenus.xml deleted file mode 100644 index a38004aa05..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/Documentation/SampleFiles/RedbookHazardMenus.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/Documentation/SampleFiles/RedbookMPCMenus.xml b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/Documentation/SampleFiles/RedbookMPCMenus.xml deleted file mode 100644 index 1d6020e5ed..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/Documentation/SampleFiles/RedbookMPCMenus.xml +++ /dev/null @@ -1,132 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/Documentation/SampleFiles/RedbookNCOMenus.xml b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/Documentation/SampleFiles/RedbookNCOMenus.xml deleted file mode 100644 index 58424248db..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/Documentation/SampleFiles/RedbookNCOMenus.xml +++ /dev/null @@ -1,163 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/Documentation/SampleFiles/RedbookUAMenus.xml b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/Documentation/SampleFiles/RedbookUAMenus.xml deleted file mode 100644 index 32379c01fa..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/Documentation/SampleFiles/RedbookUAMenus.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/META-INF/MANIFEST.MF index b619107567..aca44efc8e 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/META-INF/MANIFEST.MF @@ -2,12 +2,12 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Redbook Plug-in Bundle-SymbolicName: com.raytheon.uf.edex.plugin.redbook -Bundle-Version: 1.14.0.qualifier +Bundle-Version: 1.15.0.qualifier Bundle-Vendor: RAYTHEON Require-Bundle: com.raytheon.edex.common, javax.persistence, - com.raytheon.uf.common.localization;bundle-version="1.12.1174", - com.raytheon.uf.common.status;bundle-version="1.12.1174", + com.raytheon.uf.common.localization, + com.raytheon.uf.common.status, com.raytheon.uf.edex.ndm;bundle-version="1.14.0", com.raytheon.uf.edex.menus;bundle-version="1.0.0", com.raytheon.uf.common.dataplugin.redbook;bundle-version="1.14.0", diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/res/spring/redbook-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/res/spring/redbook-ingest.xml index 7940f30cac..fb0fa2856f 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/res/spring/redbook-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/res/spring/redbook-ingest.xml @@ -13,36 +13,53 @@ - + - - + + - - + + - - + + - - + + - - + + - - + + + + + + + + + + + + + + + + + + + diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/RedbookDecoder.java b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/RedbookDecoder.java index 8d44952cb0..64f9d4cc1f 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/RedbookDecoder.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/RedbookDecoder.java @@ -113,7 +113,6 @@ public class RedbookDecoder extends AbstractDecoder { /** * Empty constructor required by DecoderFactory. * - * @throws DecoderException */ public RedbookDecoder(String pluginName) { PLUGIN_NAME = pluginName; diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/decoder/RedbookFcstMap.java b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/decoder/RedbookFcstMap.java index 8ff233403f..ac7b00edf7 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/decoder/RedbookFcstMap.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/decoder/RedbookFcstMap.java @@ -43,13 +43,15 @@ import com.raytheon.uf.common.status.UFStatus.Priority; * *
  * SOFTWARE HISTORY
- * Date			Ticket#		Engineer	Description
- * ------------	-----------	-----------	--------------------------
- * 20101022            6424 kshrestha	Add fcsttime
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------- ----------- --------------------------
+ * 20101022            6424 kshrestha   Add fcsttime
  * Apr 29, 2013        1958 bgonzale    Map is loaded once, and then
  *                                       not loaded again unless the mapping
  *                                       file changes.
  * Nov 04, 2013        2361 njensen     Use JAXB for XML instead of SerializationUtil
+ * Jun 25, 2015        4512 mapeters    Added addEntry(), check for redbookFcstMap.xml
+ *                                      in common_static before edex_static
  * 
  * 
* @@ -84,7 +86,11 @@ public class RedbookFcstMap { private HashMap mapping; - private RedbookFcstMap() { + public void addEntry(String key, MapFcstHr value) { + if (mapping == null) { + mapping = new HashMap(); + } + mapping.put(key, value); } private static RedbookFcstMap load(LocalizationFile xmlFile) { @@ -114,17 +120,31 @@ public class RedbookFcstMap { public static synchronized RedbookFcstMap getInstance() { if (instance == null) { IPathManager pathMgr = PathManagerFactory.getPathManager(); - LocalizationContext ctx = pathMgr.getContext( - LocalizationContext.LocalizationType.EDEX_STATIC, - LocalizationContext.LocalizationLevel.BASE); - final LocalizationFile xmlFile = pathMgr.getLocalizationFile(ctx, + /* + * Check common_static/configured first, as it is now being saved + * there. If not found, check edex_static/base, where it used to be + * stored (in the future edex_static should no longer need to be + * checked). + */ + LocalizationContext context = pathMgr.getContext( + LocalizationContext.LocalizationType.COMMON_STATIC, + LocalizationContext.LocalizationLevel.CONFIGURED); + LocalizationFile xmlFile = pathMgr.getLocalizationFile(context, REDBOOK_FCST_MAP_XML); + if (xmlFile == null || !xmlFile.exists()) { + context = pathMgr.getContext( + LocalizationContext.LocalizationType.EDEX_STATIC, + LocalizationContext.LocalizationLevel.BASE); + xmlFile = pathMgr.getLocalizationFile(context, + REDBOOK_FCST_MAP_XML); + } + final LocalizationFile finalXmlFile = xmlFile; instance = load(xmlFile); xmlFile.addFileUpdatedObserver(new ILocalizationFileObserver() { @Override public void fileUpdated(FileUpdatedMessage message) { - RedbookFcstMap updatedMap = load(xmlFile); + RedbookFcstMap updatedMap = load(finalXmlFile); instance.mapping.clear(); instance.mapping.putAll(updatedMap.mapping); } diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/ingest/AbstractRedbookNdmSubscriber.java b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/ingest/AbstractRedbookNdmSubscriber.java new file mode 100644 index 0000000000..180c75e7f6 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/ingest/AbstractRedbookNdmSubscriber.java @@ -0,0 +1,160 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.edex.plugin.redbook.ingest; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import com.raytheon.uf.common.localization.IPathManager; +import com.raytheon.uf.common.localization.LocalizationContext; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; +import com.raytheon.uf.common.localization.LocalizationFile; +import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.edex.ndm.ingest.INationalDatasetSubscriber; + +/** + * Abstract class for listening for Redbook NDM files that are dropped into EDEX + * ingest. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 25, 2015 4512       mapeters    Initial creation.
+ * 
+ * 
+ * + * @author mapeters + * @version 1.0 + */ + +public abstract class AbstractRedbookNdmSubscriber implements + INationalDatasetSubscriber { + + protected static final IUFStatusHandler statusHandler = UFStatus + .getHandler(AbstractRedbookNdmSubscriber.class); + + /** + * Use this lock whenever the Redbook NDM files in localization + * (redbook/redbook*.txt) are being accessed to prevent simultaneous access + * by multiple threads. + */ + protected static final Lock lock = new ReentrantLock(); + + protected static final String DATA_KEYS_FILE_NAME = "redbookDataKeys.txt"; + + protected static final String DEPICT_KEYS_FILE_NAME = "redbookDepictKeys.txt"; + + protected static final String PRODUCT_BUTTONS_FILE_NAME = "redbookProductButtons.txt"; + + protected static final String NDM_LOC_DIR = "ndm" + IPathManager.SEPARATOR; + + protected static final LocalizationContext LOC_CONTEXT = PathManagerFactory + .getPathManager().getContext(LocalizationType.COMMON_STATIC, + LocalizationLevel.CONFIGURED); + + /** + * Get a map of key to substitution values (e.g. 5013 --> PAWO82). + * + * @param dataKeys + * List of strings from the redbookDataKeys.txt file + * @return Map for key -> substitution string + */ + protected static Map getSubstitutionMap( + List dataKeys) { + Map substitutionMap = new HashMap<>(); + for (String line : dataKeys) { + line = line.trim(); + // Skip comment/empty lines + if (line.startsWith("#") || line.length() == 0) { + continue; + } + String[] parts = line.split("\\|"); + substitutionMap.put(parts[0].trim(), + parts[10].trim().substring(0, 6)); + } + + return substitutionMap; + } + + /** + * + * Store the given file in localization in the ndm/ directory. + * + * @param fileName + * the name of the file to store + * @param file + * the file to store + */ + protected static void storeFile(String fileName, File file) { + IPathManager pm = PathManagerFactory.getPathManager(); + LocalizationFile locFile = pm.getLocalizationFile(LOC_CONTEXT, + NDM_LOC_DIR + fileName); + // Make sure the directory exists + if (!locFile.getFile().exists()) { + locFile.getFile().getParentFile().mkdirs(); + } + + try { + locFile.write(Files.readAllBytes(file.toPath())); + } catch (Exception e) { + statusHandler.handle(Priority.PROBLEM, + "Failed to write contents of " + file.getPath() + " to " + + locFile.getFile().getPath(), e); + } + } + + /** + * Get a list of the lines of the given file. + * + * @param fileName + * @return a list of the lines of the file + */ + protected static List getNdmFileLines(String fileName) { + IPathManager pm = PathManagerFactory.getPathManager(); + File file = pm.getStaticLocalizationFile( + LocalizationType.COMMON_STATIC, NDM_LOC_DIR + fileName) + .getFile(); + + List fileLines = null; + try { + fileLines = Files.readAllLines(file.toPath(), + Charset.defaultCharset()); + } catch (IOException e) { + statusHandler.handle(Priority.PROBLEM, "Failed to read lines from " + + file.getAbsolutePath(), e); + } + + return fileLines; + } +} diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/ingest/RedbookMenuSubscriber.java b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/ingest/RedbookMenuSubscriber.java deleted file mode 100644 index bf1fa4a877..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/ingest/RedbookMenuSubscriber.java +++ /dev/null @@ -1,108 +0,0 @@ -/** - * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA - * This software product contains export-restricted data whose - * export/transfer/disclosure is restricted by U.S. law. Dissemination - * to non-U.S. persons whether in the United States or abroad requires - * an export license or other authorization. - * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * - * See the AWIPS II Master Rights File ("Master Rights File.pdf") for - * further licensing information. - **/ -package com.raytheon.uf.edex.plugin.redbook.ingest; - -import java.io.File; - -import com.raytheon.uf.common.status.IUFStatusHandler; -import com.raytheon.uf.common.status.UFStatus; -import com.raytheon.uf.edex.ndm.ingest.INationalDatasetSubscriber; -import com.raytheon.uf.edex.plugin.redbook.menu.RedbookCpcMenuUtil; -import com.raytheon.uf.edex.plugin.redbook.menu.RedbookHazardsMenuUtil; -import com.raytheon.uf.edex.plugin.redbook.menu.RedbookHpcMenuUtil; -import com.raytheon.uf.edex.plugin.redbook.menu.RedbookMpcMenuUtil; -import com.raytheon.uf.edex.plugin.redbook.menu.RedbookNcoMenuUtil; -import com.raytheon.uf.edex.plugin.redbook.menu.RedbookUaMenuUtil; - -/** - * Redbook menu subscriber. Takes redbook menu files and passes them to the - * correct menu generators. - * - *
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Mar 10, 2014    2858    mpduff      Initial creation.
- * Mar 17, 2014    2855    mpduff      Implement HPC.
- * Mar 17, 2014    2856    mpduff      Implement CPC.
- * Mar 19, 2014    2857    mpduff      Implement NCO.
- * Mar 19, 2014    2859    mpduff      Implement MPC.
- * Mar 19, 2014    2860    mpduff      Implement Upper Air.
- * Jan 28, 2015    4030    mpduff      Changed constants to public.
- * 
- * 
- * - * @author mpduff - * @version 1.0 - */ - -public class RedbookMenuSubscriber implements INationalDatasetSubscriber { - /** Status handler */ - private static final IUFStatusHandler statusHandler = UFStatus - .getHandler(RedbookMenuSubscriber.class); - - /** Hazard menu file */ - public static final String HAZARD_MENU_FILE = "RedbookHazardMenus.xml"; - - /** HPC menu file */ - public static final String HPC_MENU_FILE = "RedbookHPCMenus.xml"; - - /** CPC menu file */ - public static final String CPC_MENU_FILE = "RedbookCPCMenus.xml"; - - /** MPC menu file */ - public static final String MPC_MENU_FILE = "RedbookMPCMenus.xml"; - - /** NCO menu file */ - public static final String NCO_MENU_FILE = "RedbookNCOMenus.xml"; - - /** Upper air menu file */ - public static final String UA_MENU_FILE = "RedbookUAMenus.xml"; - - /** - * {@inheritDoc} - */ - @Override - public void notify(String fileName, File file) { - statusHandler.info("Processing " + fileName); - if (HAZARD_MENU_FILE.equals(fileName)) { - // Convert input file to output menu format - RedbookHazardsMenuUtil menuUtil = new RedbookHazardsMenuUtil(); - menuUtil.createMenusFromFile(file.getAbsolutePath()); - } else if (HPC_MENU_FILE.equals(fileName)) { - RedbookHpcMenuUtil menuUtil = new RedbookHpcMenuUtil(); - menuUtil.createMenusFromFile(file.getAbsolutePath()); - } else if (CPC_MENU_FILE.equals(fileName)) { - RedbookCpcMenuUtil menuUtil = new RedbookCpcMenuUtil(); - menuUtil.createMenusFromFile(file.getAbsolutePath()); - } else if (MPC_MENU_FILE.equals(fileName)) { - RedbookMpcMenuUtil menuUtil = new RedbookMpcMenuUtil(); - menuUtil.createMenusFromFile(file.getAbsolutePath()); - } else if (NCO_MENU_FILE.equals(fileName)) { - RedbookNcoMenuUtil menuUtil = new RedbookNcoMenuUtil(); - menuUtil.createMenusFromFile(file.getAbsolutePath()); - } else if (UA_MENU_FILE.equals(fileName)) { - RedbookUaMenuUtil menuUtil = new RedbookUaMenuUtil(); - menuUtil.createMenusFromFile(file.getAbsolutePath()); - } - } -} diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/ingest/RedbookNdmMappingSubscriber.java b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/ingest/RedbookNdmMappingSubscriber.java new file mode 100644 index 0000000000..96274cf9cc --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/ingest/RedbookNdmMappingSubscriber.java @@ -0,0 +1,314 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.edex.plugin.redbook.ingest; + +import java.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.raytheon.uf.common.dataplugin.redbook.RedbookWMOMap; +import com.raytheon.uf.common.dataplugin.redbook.RedbookWMOMap.Info; +import com.raytheon.uf.common.localization.IPathManager; +import com.raytheon.uf.common.localization.LocalizationFile; +import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.common.serialization.SingleTypeJAXBManager; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.common.time.util.TimeUtil; +import com.raytheon.uf.edex.plugin.redbook.decoder.RedbookFcstMap; +import com.raytheon.uf.edex.plugin.redbook.decoder.RedbookFcstMap.MapFcstHr; + +/** + * This class listens for Redbook AWIPS1 NDM files (redbookDataKeys.txt, + * redbookDepictKeys.txt, redbookProductButtons.txt) to be dropped into EDEX + * ingest, updates the appropriate mapping file(s) (redbookMapping.xml and/or + * redbookFcstMap.xml) and tells the Redbook menus that they should be recreated + * using the new files. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 25, 2015 4512       mapeters    Initial creation.
+ * 
+ * 
+ * + * @author mapeters + * @version 1.0 + */ +public class RedbookNdmMappingSubscriber extends AbstractRedbookNdmSubscriber { + + protected static final IUFStatusHandler statusHandler = UFStatus + .getHandler(RedbookNdmMappingSubscriber.class); + + private static final String FCST_MAP_FILE_NAME = "redbookFcstMap.xml"; + + private static final String MAPPING_FILE_NAME = "redbookMapping.xml"; + + /* + * The following map projection values were determined from an A1 + * makeDataSups.csh file. For example, the line + * "$maksuparg 9 0 -80 0 b04.sup l -20.0 -160.0 50.0 0.0" in the file was + * used to map "b04" to b04_proj below, where the first number indicates the + * projection type (9 = mercator), and the fourth number is ignored. + */ + private static final String b04_proj = "mercator 0 -80 -20.0 -160.0 50.0 0.0"; + + private static final String b05_proj = "mercator 0 -80 -3.4581 -121.0959 45.0 -38.9041"; + + private static final String b06_proj = "mercator 0 -115 -30.0 -160.0 59.0 0.0"; + + private static final String b07_proj = "mercator 0 -120 -4.3808 -160.0 45.5722 -75.0"; + + private static final String b08_proj = "mercator 0 -75 -30.0 -160.0 59.0 0.0"; + + private static final String B05_proj = "mercator 0 -90 -48.6 170.7 69.4 15.4"; + + private static final String B07_proj = "mercator 0 180 -48.6 80.7 69.4 -76.4"; + + private static final String b_TSA_proj = "mercator 0 -80 -21.7022 -155.0 51.1567 -30.0"; + + private static enum ProjectionKey { + b04, b05, b06, b07, b08, B05, B07, b_TSA; + } + + private static Map projectionMap; + + private static String getProjection(String key) { + if (projectionMap == null) { + projectionMap = new HashMap( + ProjectionKey.values().length); + projectionMap.put(ProjectionKey.b04.name(), b04_proj); + projectionMap.put(ProjectionKey.b05.name(), b05_proj); + projectionMap.put(ProjectionKey.b06.name(), b06_proj); + projectionMap.put(ProjectionKey.b07.name(), b07_proj); + projectionMap.put(ProjectionKey.b08.name(), b08_proj); + projectionMap.put(ProjectionKey.B05.name(), B05_proj); + projectionMap.put(ProjectionKey.B07.name(), B07_proj); + projectionMap.put(ProjectionKey.b_TSA.name(), b_TSA_proj); + } + return projectionMap.get(key); + } + + /** + * Build and marshal a {@link RedbookFcstMap} object from the given + * redbookDataKeys.txt contents. + * + * Logic for parsing NDM files comes from the AWIPS1 documentation in the + * Redbook section of www.nws.noaa.gov/ndm/. + * + * @param dataKeysLines + */ + private static void buildRedbookFcstMapXml(List dataKeysLines) { + RedbookFcstMap fcstMap = new RedbookFcstMap(); + + for (String line : dataKeysLines) { + line = line.trim(); + // Skip comment/empty lines + if (line.startsWith("#") || line.length() == 0) { + continue; + } + + String[] parts = line.split("\\|"); + + int depictKeyValue = Integer.valueOf(parts[0].trim()); + if (depictKeyValue <= 5000 || depictKeyValue >= 6000) { + /* + * AWIPS1 documentation indicates that depict key values range + * from 5000 to 5999, so values outside this are ignored. First + * line in redbookDataKeys.txt starts with 5000 and has no WMO + * ID, so 5000 is also ignored. + */ + continue; + } + + MapFcstHr value = new MapFcstHr(); + String key = parts[10].trim().substring(0, 6); + + String prdAndOfs = parts[6].trim(); + if (!prdAndOfs.isEmpty()) { + String[] prdAndOfsArray = prdAndOfs.split(","); + value.binPeriod = Integer.valueOf(prdAndOfsArray[0]); + if (prdAndOfsArray.length > 1) { + value.binOffset = Integer.valueOf(prdAndOfsArray[1]); + } + } + String fcstHr = parts[3].trim(); + if (!fcstHr.isEmpty()) { + int fcstHrInt = Integer.valueOf(fcstHr); + if (fcstHrInt < 0) { + // Negative sign indicates value is in days, not + // hours + int days = fcstHrInt * -1; + fcstHr = Integer.toString(days * TimeUtil.HOURS_PER_DAY); + } else if (fcstHrInt > 240) { + // > 240 indicates value is in seconds, not hours + int seconds = fcstHrInt; + fcstHr = Integer.toString(seconds + / TimeUtil.SECONDS_PER_HOUR); + } + value.fcstHR = fcstHr; + } + fcstMap.addEntry(key, value); + } + + marshalToXml(fcstMap, FCST_MAP_FILE_NAME); + } + + /** + * Build and marshal a {@link RedbookWMOMap} object from the given + * redbookDataKeys.txt and redbookDepictKeys.txt contents. + * + * @param dataKeysLines + * @param depictKeysLines + */ + private static void buildRedbookMappingXml(List dataKeysLines, + List depictKeysLines) { + Map dataMap = getSubstitutionMap(dataKeysLines); + Map projectionMap = getProjectionMap(dataKeysLines); + + RedbookWMOMap wmoMap = new RedbookWMOMap(); + for (String line : depictKeysLines) { + line = line.trim(); + // Skip comment/empty lines + if (line.startsWith("#") || line.length() == 0) { + continue; + } + + Info value = new Info(); + + String[] depictKeysParts = line.split("\\|"); + String[] dataMapKeys = depictKeysParts[2].trim().split(","); + + StringBuilder key = new StringBuilder(); + String projectionKey = ""; + boolean first = true; + for (String dataMapKey : dataMapKeys) { + String dataMapValue = dataMap.get(dataMapKey); + if (dataMapValue != null) { + if (!first) { + key.append(","); + } else { + first = false; + } + key.append(dataMapValue); + /* + * Use any key that maps to a value to determine the + * projection + */ + projectionKey = dataMapKey; + } + } + + String projection = projectionMap.get(projectionKey); + if (projection != null) { + value.projection = projection; + } + + value.name = depictKeysParts[6].trim(); + + wmoMap.addEntry(key.toString(), value); + } + + marshalToXml(wmoMap, MAPPING_FILE_NAME); + } + + /** + * Marshal the given Redbook map object to the given file path in + * localization. + * + * @param redbookMap + * the Redbook map object (RedbookWMOMap or RedbookFcstMap) + * @param locFilePath + * the localization file path + */ + private static void marshalToXml(Object redbookMap, String locFilePath) { + lock.lock(); + try { + IPathManager pm = PathManagerFactory.getPathManager(); + LocalizationFile destinationLocFile = pm.getLocalizationFile( + LOC_CONTEXT, "redbook" + IPathManager.SEPARATOR + + locFilePath); + if (!destinationLocFile.getFile().exists()) { + destinationLocFile.getFile().getParentFile().mkdirs(); + } + try { + destinationLocFile.jaxbMarshal(redbookMap, + new SingleTypeJAXBManager<>(redbookMap.getClass())); + } catch (Exception e) { + statusHandler.handle(Priority.PROBLEM, "Failed to marshal " + + redbookMap.toString() + " to " + + destinationLocFile.getFile().getAbsolutePath(), e); + } + } finally { + lock.unlock(); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void notify(final String fileName, final File file) { + storeFile(fileName, file); + if (!fileName.equals(PRODUCT_BUTTONS_FILE_NAME)) { + List dataKeysLines = getNdmFileLines(DATA_KEYS_FILE_NAME); + List depictKeysLines = getNdmFileLines(DEPICT_KEYS_FILE_NAME); + + if (fileName.equals(DATA_KEYS_FILE_NAME)) { + buildRedbookFcstMapXml(dataKeysLines); + } + buildRedbookMappingXml(dataKeysLines, depictKeysLines); + } + RedbookNdmMenuSubscriber.notifyAllMenus(); + } + + /** + * Get a map of key to projection values (e.g. 5312 --> "mercator 0 -80 + * -21.7022 -155.0 51.1567 -30.0"). + * + * @param dataKeys + * List of strings from the redbookDataKeys.txt file + * @return Map for key -> projection string + */ + private static Map getProjectionMap(List dataKeys) { + Map projectionMap = new HashMap<>(); + for (String line : dataKeys) { + line = line.trim(); + // Skip comment/empty lines + if (line.startsWith("#") || line.length() == 0) { + continue; + } + String[] parts = line.split("\\|"); + String projectionKey = parts[1].trim(); + if (!projectionKey.isEmpty()) { + String projection = getProjection(projectionKey); + if (projection != null) + projectionMap.put(parts[0].trim(), projection); + } + } + + return projectionMap; + } +} diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/ingest/RedbookNdmMenuSubscriber.java b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/ingest/RedbookNdmMenuSubscriber.java new file mode 100644 index 0000000000..4df945f6ef --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/ingest/RedbookNdmMenuSubscriber.java @@ -0,0 +1,298 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.edex.plugin.redbook.ingest; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; + +import com.raytheon.uf.common.localization.IPathManager; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; +import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.edex.plugin.redbook.ingest.xml.MenuEntry; +import com.raytheon.uf.edex.plugin.redbook.ingest.xml.MenuEntryType; +import com.raytheon.uf.edex.plugin.redbook.ingest.xml.RedbookMenusXML; +import com.raytheon.uf.edex.plugin.redbook.menu.RedbookCpcMenuUtil; +import com.raytheon.uf.edex.plugin.redbook.menu.RedbookHazardsMenuUtil; +import com.raytheon.uf.edex.plugin.redbook.menu.RedbookHpcMenuUtil; +import com.raytheon.uf.edex.plugin.redbook.menu.RedbookMenuUtil; +import com.raytheon.uf.edex.plugin.redbook.menu.RedbookMpcMenuUtil; +import com.raytheon.uf.edex.plugin.redbook.menu.RedbookNcoMenuUtil; +import com.raytheon.uf.edex.plugin.redbook.menu.RedbookUaMenuUtil; + +/** + * This class updates the Redbook menus when Redbook A1 NDM files are dropped + * into EDEX ingest. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 30, 2015   4030     mpduff      Initial creation
+ * Mar 19, 2015   4310     mpduff      Some values must be trimmed.
+ * Jun 26, 2015   4512     mapeters    Renamed from NdmMenuConverter, automatically
+ *                                     runs and updates menus when A1 files dropped in.
+ * 
+ * 
+ * + * @author mpduff + * @version 1.0 + */ + +public class RedbookNdmMenuSubscriber extends AbstractRedbookNdmSubscriber { + + protected static final IUFStatusHandler statusHandler = UFStatus + .getHandler(RedbookNdmMenuSubscriber.class); + + private static final String WMO = "wmo"; + + private static final String HPC_FILE = "redbookHPCMenus.txt"; + + private static final String CPC_FILE = "redbookCPCMenus.txt"; + + private static final String NCO_FILE = "redbookNCOMenus.txt"; + + private static final String HAZARDS_FILE = "redbookHazardMenus.txt"; + + private static final String MARINE_FILE = "redbookMarineMenus.txt"; + + private static final String UPPER_AIR_FILE = "redbookUpperAirMenus.txt"; + + /** + * Build a {@link RedbookMenusXML} object from the NDM file with the given + * file name and call for the menu to be updated from the XML object. + * + * @param menuFileName + * the name of the A1 NDM menu file + */ + public static void buildMenuXml(String menuFileName) { + statusHandler.info("Processing " + menuFileName); + RedbookMenusXML menuXml = new RedbookMenusXML(); + MenuEntry titleMenuEntry; + int sepCounter = 0; + List subMenuList = new ArrayList(); + + List menuFileLines = getNdmFileLines(menuFileName); + List dataKeysLines = getNdmFileLines(DATA_KEYS_FILE_NAME); + List depictKeysLines = getNdmFileLines(DEPICT_KEYS_FILE_NAME); + List productButtonsLines = getNdmFileLines(PRODUCT_BUTTONS_FILE_NAME); + Map menuTextMap = getMenuTextMap(productButtonsLines); + Map dataKeyMap = getSubstitutionMap(dataKeysLines); + + MenuEntry subMenuEntry = null; + + int subMenuCount = -1; + for (String line : menuFileLines) { + line = line.trim(); + if (line.startsWith("submenu")) { + subMenuCount++; + if (line.contains("&")) { + line = line.replace("&", "&&"); + } + + String[] parts = line.split(":"); + String text = parts[1].replace("\"", ""); + + subMenuEntry = new MenuEntry(); + subMenuEntry.setFile(null); + subMenuEntry.setType(MenuEntryType.Submenu); + subMenuEntry.setText(text.trim()); + + subMenuList.add(subMenuEntry); + } else if (line.startsWith("title")) { + String[] parts = line.split(":"); + String text = parts[1].trim().replace("\"", ""); + text = "------ " + text + " ------"; + titleMenuEntry = new MenuEntry(); + titleMenuEntry.setFile(null); + titleMenuEntry.setType(MenuEntryType.Title); + titleMenuEntry.setText(text); + titleMenuEntry.setId(text); + subMenuList.get(subMenuCount).addMenuEntry(titleMenuEntry); + } else if (line.startsWith("productButton")) { + String[] parts = line.split(":"); + MenuEntry me = new MenuEntry(); + me.setFile(null); + me.setType(MenuEntryType.ProductButton); + /* + * There are certain productButtons in the NCO menu data keys in + * the (25000 range) that have data keys that don't map to + * anything. This results in those menu items not being created. + * The site will need to fix this after generating the new + * menus. + */ + String dataKey = parts[1].trim().substring(0, 4); + StringBuilder subValue = new StringBuilder(); + String menuText = menuTextMap.get(dataKey); + if (menuText == null) { + /* + * Ignore entries that don't have corresponding entries in + * the product buttons file. + */ + continue; + } + // Find the matching value + for (String depictKeyLine : depictKeysLines) { + if (depictKeyLine.trim().startsWith(dataKey)) { + String[] depictKeyParts = depictKeyLine.split("\\|"); + me.setText(menuText); + me.setId(depictKeyParts[6].trim()); + subMenuList.get(subMenuCount).addMenuEntry(me); + + String[] subParts = depictKeyParts[2].split(","); + MenuEntry subEntry = new MenuEntry(); + subEntry.setFile(null); + subEntry.setType(MenuEntryType.Substitute); + subEntry.setKey(WMO); + + for (String subPart : subParts) { + subPart = subPart.trim(); + for (String key : dataKeyMap.keySet()) { + key = key.trim(); + if (key.startsWith(subPart)) { + subValue.append(dataKeyMap.get(key)) + .append(","); + break; + } + } + } + + String subValueStr = subValue.toString(); + subValueStr = StringUtils.removeEnd(subValueStr, ","); + subEntry.setValue(subValueStr); + me.addMenuEntry(subEntry); + break; + } + } + } else if (line.startsWith("endSubmenu")) { + // subMenuList.add(subMenuEntry); + MenuEntry closedSubMenu = subMenuList.remove(subMenuCount); + subMenuCount--; + if (subMenuCount == -1) { + menuXml.addMenuEntry(closedSubMenu); + } else { + subMenuList.get(subMenuCount).addMenuEntry(closedSubMenu); + } + } else if (line.startsWith("separator")) { + MenuEntry sep = new MenuEntry(); + sep.setFile(null); + sep.setType(MenuEntryType.Separator); + sep.setId("Separator" + sepCounter++); + subMenuList.get(subMenuCount).addMenuEntry(sep); + } + } + + updateMenu(menuFileName, menuXml); + } + + /** + * Get a map of menu keys to menu text. + * + * @param productButtonKeys + * List of strings from redbookProductButtons.txt + * + * @return Map for key -> menu text + */ + private static Map getMenuTextMap( + List productButtonKeys) { + Map menuTextMap = new HashMap(); + for (String line : productButtonKeys) { + line = line.trim(); + // Skip comment/empty lines + if (line.startsWith("#") || line.trim().length() == 0) { + continue; + } + + String[] parts = line.split("\\|"); + menuTextMap.put(parts[0].trim(), parts[2].trim()); + } + + return menuTextMap; + } + + /** + * {@inheritDoc} + */ + @Override + public void notify(final String menuFileName, final File menuFile) { + lock.lock(); + try { + storeFile(menuFileName, menuFile); + buildMenuXml(menuFileName); + } finally { + lock.unlock(); + } + } + + /** + * Use the given menu XML object to update the menu that corresponds to the + * given A1 menu file name + * + * @param menuFileName + * the A1 menu file name + * @param xml + * the menu XML object created from the A1 file + */ + private static void updateMenu(String menuFileName, RedbookMenusXML xml) { + RedbookMenuUtil menuUtil = null; + if (HAZARDS_FILE.equals(menuFileName)) { + menuUtil = new RedbookHazardsMenuUtil(); + } else if (HPC_FILE.equals(menuFileName)) { + menuUtil = new RedbookHpcMenuUtil(); + } else if (CPC_FILE.equals(menuFileName)) { + menuUtil = new RedbookCpcMenuUtil(); + } else if (MARINE_FILE.equals(menuFileName)) { + menuUtil = new RedbookMpcMenuUtil(); + } else if (NCO_FILE.equals(menuFileName)) { + menuUtil = new RedbookNcoMenuUtil(); + } else if (UPPER_AIR_FILE.equals(menuFileName)) { + menuUtil = new RedbookUaMenuUtil(); + } + + if (menuUtil != null) { + menuUtil.createMenusFromFile(xml); + } + } + + /** + * Updates all the Redbook menus. Called from + * {@link RedbookNdmMappingSubscriber } when new A1 files that are used by + * all of the menus are dropped in. + */ + public static void notifyAllMenus() { + RedbookNdmMenuSubscriber menuSubscriber = new RedbookNdmMenuSubscriber(); + IPathManager pm = PathManagerFactory.getPathManager(); + for (String menuFileName : new String[] { CPC_FILE, HPC_FILE, NCO_FILE, + HAZARDS_FILE, MARINE_FILE, UPPER_AIR_FILE }) { + File menuFile = pm.getStaticLocalizationFile( + LocalizationType.COMMON_STATIC, NDM_LOC_DIR + menuFileName) + .getFile(); + menuSubscriber.notify(menuFileName, menuFile); + } + } +} diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/ingest/xml/RedbookMenusXML.java b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/ingest/xml/RedbookMenusXML.java index 1079d5cc33..22c5c9a240 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/ingest/xml/RedbookMenusXML.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/ingest/xml/RedbookMenusXML.java @@ -40,6 +40,7 @@ import javax.xml.bind.annotation.XmlRootElement; * Mar 07, 2014 2858 mpduff Initial creation. * Mar 17, 2014 2855 mpduff Renamed to RedbookMenusXML.java. * Jan 28, 2015 4030 mpduff Added addMenuEntry method. + * Jun 26, 2015 4512 mapeters Use System.lineSeparator() for new line. * * * @@ -90,7 +91,7 @@ public class RedbookMenusXML { */ @Override public String toString() { - final String nl = System.getProperty("line.separator"); + final String nl = System.lineSeparator(); StringBuilder sb = new StringBuilder("RedbookMenusXML").append(nl); for (MenuEntry sub : menuEntryList) { sb.append(sub.toString()); diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/NdmMenuConverter.java b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/NdmMenuConverter.java deleted file mode 100644 index 332d1f4bd6..0000000000 --- a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/NdmMenuConverter.java +++ /dev/null @@ -1,363 +0,0 @@ -/** - * This software was developed and / or modified by Raytheon Company, - * pursuant to Contract DG133W-05-CQ-1067 with the US Government. - * - * U.S. EXPORT CONTROLLED TECHNICAL DATA - * This software product contains export-restricted data whose - * export/transfer/disclosure is restricted by U.S. law. Dissemination - * to non-U.S. persons whether in the United States or abroad requires - * an export license or other authorization. - * - * Contractor Name: Raytheon Company - * Contractor Address: 6825 Pine Street, Suite 340 - * Mail Stop B8 - * Omaha, NE 68106 - * 402.291.0100 - * - * See the AWIPS II Master Rights File ("Master Rights File.pdf") for - * further licensing information. - **/ -package com.raytheon.uf.edex.plugin.redbook.menu; - -import java.io.File; -import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Marshaller; - -import org.apache.commons.lang.StringUtils; - -import com.raytheon.uf.edex.plugin.redbook.ingest.RedbookMenuSubscriber; -import com.raytheon.uf.edex.plugin.redbook.ingest.xml.MenuEntry; -import com.raytheon.uf.edex.plugin.redbook.ingest.xml.MenuEntryType; -import com.raytheon.uf.edex.plugin.redbook.ingest.xml.RedbookMenusXML; - -/** - * This class is called from /awips2/edex/bin/ndmMenuIngester.sh. - * - * It reads in the NDM menu files and outputs an A2 version into the NDM - * endpoint on edex. - * - *
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Jan 30, 2015   4030     mpduff      Initial creation
- * Mar 19, 2015   4310     mpduff      Some values must be trimmed.
- * 
- * 
- * - * @author mpduff - * @version 1.0 - */ - -public class NdmMenuConverter { - private static final String WMO = "wmo"; - - private static final String OUTPUT_PATH = File.separator + "awips2" - + File.separator + "edex" + File.separator + "data" - + File.separator + "ndm" + File.separator; - - private static final String HPC_FILE = "redbookHPCMenus.txt"; - - private static final String CPC_FILE = "redbookCPCMenus.txt"; - - private static final String NCO_FILE = "redbookNCOMenus.txt"; - - private static final String HAZARDS_FILE = "redbookHazardMenus.txt"; - - private static final String MARINE_FILE = "redbookMarineMenus.txt"; - - private static final String UPPER_AIR_FILE = "redbookUpperAirMenus.txt"; - - private String dataKeysPath; - - private String depictKeysPath; - - private String menuFilePath; - - private String productButtonPath; - - private JAXBContext jax; - - private Marshaller marshaller; - - private File depictFile; - - public NdmMenuConverter() { - createContext(); - } - - public void convert() { - RedbookMenusXML menuXml = new RedbookMenusXML(); - MenuEntry titleMenuEntry; - int sepCounter = 0; - List subMenuList = new ArrayList(); - - try { - File dataFile = new File(this.dataKeysPath); - File menuFile = new File(this.menuFilePath); - depictFile = new File(this.depictKeysPath); - File productButtonFile = new File(this.productButtonPath); - - List dataKeys = Files.readAllLines(dataFile.toPath(), - Charset.defaultCharset()); - List depictKeys = Files.readAllLines(depictFile.toPath(), - Charset.defaultCharset()); - List lines = Files.readAllLines(menuFile.toPath(), - Charset.defaultCharset()); - List productButtonKeys = Files.readAllLines( - productButtonFile.toPath(), Charset.defaultCharset()); - Map menuTextMap = getMenuTextMap(productButtonKeys); - Map dataKeyMap = getSubstitutionMap(dataKeys); - - MenuEntry subMenuEntry = null; - - int subMenuCount = -1; - for (String line : lines) { - line = line.trim(); - if (line.startsWith("submenu")) { - subMenuCount++; - if (line.contains("&")) { - line = line.replace("&", "&&"); - } - - String[] parts = line.split(":"); - String text = parts[1].replace("\"", ""); - - subMenuEntry = new MenuEntry(); - subMenuEntry.setFile(null); - subMenuEntry.setType(MenuEntryType.Submenu); - subMenuEntry.setText(text.trim()); - - subMenuList.add(subMenuEntry); - } else if (line.startsWith("title")) { - String[] parts = line.split(":"); - String text = parts[1].replace("\"", ""); - titleMenuEntry = new MenuEntry(); - titleMenuEntry.setFile(null); - titleMenuEntry.setType(MenuEntryType.Title); - titleMenuEntry.setText(text); - titleMenuEntry.setId(text); - subMenuList.get(subMenuCount).addMenuEntry(titleMenuEntry); - } else if (line.startsWith("productButton")) { - String[] parts = line.split(":"); - MenuEntry me = new MenuEntry(); - me.setFile(null); - me.setType(MenuEntryType.ProductButton); - /* - * There are certain productButtons in the NCO menu data - * keys in the (25000 range) that have data keys that don't - * map to anything. This results in those menu items not - * being created. The site will need to fix this after - * generating the new menus. - */ - String dataKey = parts[1].trim().substring(0, 4); - StringBuilder subValue = new StringBuilder(); - // Find the matching value - for (String depictKeyLine : depictKeys) { - if (depictKeyLine.trim().startsWith(dataKey)) { - String[] depictKeyParts = depictKeyLine - .split("\\|"); - me.setText(menuTextMap.get(dataKey)); - me.setId(depictKeyParts[6].trim()); - subMenuList.get(subMenuCount).addMenuEntry(me); - - String[] subParts = depictKeyParts[2].split(","); - MenuEntry subEntry = new MenuEntry(); - subEntry.setFile(null); - subEntry.setType(MenuEntryType.Substitute); - subEntry.setKey(WMO); - - for (String subPart : subParts) { - subPart = subPart.trim(); - for (String key : dataKeyMap.keySet()) { - key = key.trim(); - if (key.startsWith(subPart)) { - subValue.append(dataKeyMap.get(key)) - .append(","); - break; - } - } - } - - String subValueStr = subValue.toString(); - subValueStr = StringUtils.removeEnd(subValueStr, - ","); - subEntry.setValue(subValueStr); - me.addMenuEntry(subEntry); - break; - } - } - } else if (line.startsWith("endSubmenu")) { - // subMenuList.add(subMenuEntry); - MenuEntry closedSubMenu = subMenuList.remove(subMenuCount); - subMenuCount--; - if (subMenuCount == -1) { - menuXml.addMenuEntry(closedSubMenu); - } else { - subMenuList.get(subMenuCount).addMenuEntry( - closedSubMenu); - } - } else if (line.startsWith("separator")) { - MenuEntry sep = new MenuEntry(); - sep.setFile(null); - sep.setType(MenuEntryType.Separator); - sep.setId("Separator" + sepCounter++); - subMenuList.get(subMenuCount).addMenuEntry(sep); - } - } - - // Set output file name - String inputFileName = menuFile.getName(); - String outputFileName = null; - if (inputFileName.equals(CPC_FILE)) { - outputFileName = RedbookMenuSubscriber.CPC_MENU_FILE; - } else if (inputFileName.equals(HPC_FILE)) { - outputFileName = RedbookMenuSubscriber.HPC_MENU_FILE; - } else if (inputFileName.equals(NCO_FILE)) { - outputFileName = RedbookMenuSubscriber.NCO_MENU_FILE; - } else if (inputFileName.equals(HAZARDS_FILE)) { - outputFileName = RedbookMenuSubscriber.HAZARD_MENU_FILE; - } else if (inputFileName.equals(MARINE_FILE)) { - outputFileName = RedbookMenuSubscriber.MPC_MENU_FILE; - } else if (inputFileName.equals(UPPER_AIR_FILE)) { - outputFileName = RedbookMenuSubscriber.UA_MENU_FILE; - } else { - throw new IOException("Error processing file"); - } - - marshaller.marshal(menuXml, new File(OUTPUT_PATH + outputFileName)); - } catch (Exception e) { - System.err.println("Error occurred processing file: " - + menuFilePath); - e.printStackTrace(); - } - } - - /** - * Get a map of menu keys to menu text. - * - * @param productButtonKeys - * List of strings from redbookProductButtons.txt - * - * @return Map for key -> menu text - */ - private Map getMenuTextMap(List productButtonKeys) { - Map menuTextMap = new HashMap(); - for (String line : productButtonKeys) { - line = line.trim(); - // Skip comment lines - if (line.startsWith("#") || line.trim().length() == 0) { - continue; - } - - String[] parts = line.split("\\|"); - menuTextMap.put(parts[0].trim(), parts[2].trim()); - } - - return menuTextMap; - } - - /** - * Get a map of key to substitution values. - * - * @param dataKeys - * List of strings from the redbookDataKeys.txt file - * @returnMap for key -> substitution string - */ - private Map getSubstitutionMap(List dataKeys) { - Map dataKeyMap = new HashMap(); - for (String line : dataKeys) { - line = line.trim(); - // Skip comment lines - if (line.startsWith("#") || line.trim().length() == 0) { - continue; - } - String[] parts = line.split("\\|"); - dataKeyMap.put(parts[0].trim(), parts[10].substring(0, 6)); - } - - return dataKeyMap; - } - - public String getDataKeysPath() { - return dataKeysPath; - } - - public void setDataKeysPath(String dataKeysPath) { - this.dataKeysPath = dataKeysPath; - } - - public String getDepictKeysPath() { - return depictKeysPath; - } - - public void setDepictKeysPath(String depictKeysPath) { - this.depictKeysPath = depictKeysPath; - } - - public String getMenuFilePath() { - return menuFilePath; - } - - public void setMenuFilePath(String menuFilePath) { - this.menuFilePath = menuFilePath; - } - - public void setProductButtonPath(String productButtonPath) { - this.productButtonPath = productButtonPath; - } - - public String getProductButtonPath() { - return this.productButtonPath; - } - - private void createContext() { - Class[] classes = new Class[] { MenuEntry.class, MenuEntryType.class, - RedbookMenusXML.class }; - - try { - jax = JAXBContext.newInstance(classes); - this.marshaller = jax.createMarshaller(); - this.marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public static void main(String[] args) { - - if (args.length != 2) { - System.err.println("Unexpected Arguments"); - System.err - .println("Expecting local NDM directory and NDM File Menu Name"); - return; - } - - String dirPath = args[0]; - if (!dirPath.endsWith(File.separator)) { - dirPath = dirPath.concat(File.separator); - } - String menuFile = dirPath + args[1]; - String dataKeysFile = dirPath + "redbookDataKeys.txt"; - String depictKeysFile = dirPath + "redbookDepictKeys.txt"; - String productButtonFile = dirPath + "redbookProductButtons.txt"; - - NdmMenuConverter converter = new NdmMenuConverter(); - converter.setDataKeysPath(dataKeysFile); - converter.setMenuFilePath(menuFile); - converter.setDepictKeysPath(depictKeysFile); - converter.setProductButtonPath(productButtonFile); - converter.convert(); - - } -} diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookCpcMenuUtil.java b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookCpcMenuUtil.java index 7411bf4c07..ee8a518363 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookCpcMenuUtil.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookCpcMenuUtil.java @@ -19,8 +19,7 @@ **/ package com.raytheon.uf.edex.plugin.redbook.menu; -import java.io.File; - +import com.raytheon.uf.common.localization.IPathManager; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; @@ -34,6 +33,7 @@ import com.raytheon.uf.common.status.UFStatus; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Mar 18, 2014 2856 mpduff Initial creation + * Jun 26, 2015 4512 mapeters Abstract out createMenusFromFile() * * * @@ -47,15 +47,15 @@ public class RedbookCpcMenuUtil extends RedbookMenuUtil { .getHandler(RedbookHpcMenuUtil.class); /** Menu type constant */ - private static final String MENU_TYPE = "ncepHydro" + File.separator + private static final String MENU_TYPE = NCEP_HYDRO + IPathManager.SEPARATOR + "cpc"; /** HPC menu file */ private static final String CPC_MENU = "cpcMenus.xml"; /** HPC menu file full path */ - private static final String MENU_FILE = "menus" + File.separator - + MENU_TYPE + File.separator + CPC_MENU; + private static final String MENU_FILE = MENUS + IPathManager.SEPARATOR + + MENU_TYPE + IPathManager.SEPARATOR + CPC_MENU; /** * Constructor. @@ -64,16 +64,6 @@ public class RedbookCpcMenuUtil extends RedbookMenuUtil { super(); } - /** - * {@inheritDoc} - */ - @Override - public void createMenusFromFile(String filename) { - xml = read(filename); - - createMenus(); - } - /** * {@inheritDoc} */ diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookHazardsMenuUtil.java b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookHazardsMenuUtil.java index 1394bc99c2..acf111a846 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookHazardsMenuUtil.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookHazardsMenuUtil.java @@ -19,8 +19,7 @@ **/ package com.raytheon.uf.edex.plugin.redbook.menu; -import java.io.File; - +import com.raytheon.uf.common.localization.IPathManager; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; @@ -35,6 +34,7 @@ import com.raytheon.uf.common.status.UFStatus; * ------------ ---------- ----------- -------------------------- * Mar 07, 2014 2858 mpduff Initial creation * Mar 14, 2014 2855 mpduff Renamed and refactored common code. + * Jun 26, 2015 4512 mapeters Abstract out createMenusFromFile() * * * @@ -48,15 +48,15 @@ public class RedbookHazardsMenuUtil extends RedbookMenuUtil { .getHandler(RedbookHpcMenuUtil.class); /** Menu type constant */ - private static final String MENU_TYPE = "ncepHydro" + File.separator + private static final String MENU_TYPE = NCEP_HYDRO + IPathManager.SEPARATOR + "spc"; /** SPC hazard menu file */ private static final String HAZARD_MENU = "hazardMenus.xml"; /** SPC hazard menu file including full path */ - private static final String MENU_FILE = "menus" + File.separator - + MENU_TYPE + File.separator + HAZARD_MENU; + private static final String MENU_FILE = MENUS + IPathManager.SEPARATOR + + MENU_TYPE + IPathManager.SEPARATOR + HAZARD_MENU; /** * Constructor. @@ -65,16 +65,6 @@ public class RedbookHazardsMenuUtil extends RedbookMenuUtil { super(); } - /** - * {@inheritDoc} - */ - @Override - public void createMenusFromFile(String filename) { - xml = read(filename); - - createMenus(); - } - /** * {@inheritDoc} */ diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookHpcMenuUtil.java b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookHpcMenuUtil.java index cad4438bbf..72ac566605 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookHpcMenuUtil.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookHpcMenuUtil.java @@ -19,8 +19,7 @@ **/ package com.raytheon.uf.edex.plugin.redbook.menu; -import java.io.File; - +import com.raytheon.uf.common.localization.IPathManager; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; @@ -34,6 +33,7 @@ import com.raytheon.uf.common.status.UFStatus; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Mar 12, 2014 2855 mpduff Initial creation. + * Jun 26, 2015 4512 mapeters Abstract out createMenusFromFile() * * * @@ -47,15 +47,15 @@ public class RedbookHpcMenuUtil extends RedbookMenuUtil { .getHandler(RedbookHpcMenuUtil.class); /** Menu type constant */ - private static final String MENU_TYPE = "ncepHydro" + File.separator + private static final String MENU_TYPE = NCEP_HYDRO + IPathManager.SEPARATOR + "hpc"; /** HPC menu file */ private static final String HPC_MENU = "hpcMenus.xml"; /** HPC menu file full path */ - private static final String MENU_FILE = "menus" + File.separator - + MENU_TYPE + File.separator + HPC_MENU; + private static final String MENU_FILE = MENUS + IPathManager.SEPARATOR + + MENU_TYPE + IPathManager.SEPARATOR + HPC_MENU; /** * Constructor. @@ -64,16 +64,6 @@ public class RedbookHpcMenuUtil extends RedbookMenuUtil { super(); } - /** - * {@inheritDoc} - */ - @Override - public void createMenusFromFile(String filename) { - xml = read(filename); - - createMenus(); - } - /** * {@inheritDoc} */ diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookMenuUtil.java b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookMenuUtil.java index 18d80e8c47..943f632781 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookMenuUtil.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookMenuUtil.java @@ -56,6 +56,8 @@ import com.raytheon.uf.edex.plugin.redbook.ingest.xml.RedbookMenusXML; * Mar 19, 2014 2860 mpduff Implemented Redbook UpperAir. * Apr 30, 2014 2860 mpduff Fixed instances of empty substitution tags. * Jun 09, 2014 3266 njensen Removed reference to dataURIs + * Jun 26, 2015 4512 mapeters Implement createMenusFromFile() here, takes in + * {@link RedbookMenusXML} object. * * * @@ -92,7 +94,10 @@ public abstract class RedbookMenuUtil extends AbstractMenuUtil { * @param filename * The file droped into /awips2/edex/data/ndm */ - public abstract void createMenusFromFile(String filename); + public void createMenusFromFile(RedbookMenusXML xml) { + this.xml = xml; + createMenus(); + } /** * Create the JaxB context. diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookMpcMenuUtil.java b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookMpcMenuUtil.java index e401e712be..f6a4f61ed9 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookMpcMenuUtil.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookMpcMenuUtil.java @@ -19,8 +19,7 @@ **/ package com.raytheon.uf.edex.plugin.redbook.menu; -import java.io.File; - +import com.raytheon.uf.common.localization.IPathManager; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; @@ -34,6 +33,7 @@ import com.raytheon.uf.common.status.UFStatus; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Mar 19, 2014 2859 mpduff Initial creation + * Jun 26, 2015 4512 mapeters Abstract out createMenusFromFile() * * * @@ -47,15 +47,15 @@ public class RedbookMpcMenuUtil extends RedbookMenuUtil { .getHandler(RedbookMpcMenuUtil.class); /** Menu type constant */ - private static final String MENU_TYPE = "ncepHydro" + File.separator + private static final String MENU_TYPE = NCEP_HYDRO + IPathManager.SEPARATOR + "mpc"; /** HPC menu file */ private static final String MPC_MENU = "mpcMenus.xml"; /** HPC menu file full path */ - private static final String MENU_FILE = "menus" + File.separator - + MENU_TYPE + File.separator + MPC_MENU; + private static final String MENU_FILE = MENUS + IPathManager.SEPARATOR + + MENU_TYPE + IPathManager.SEPARATOR + MPC_MENU; /** * Constructor. @@ -64,16 +64,6 @@ public class RedbookMpcMenuUtil extends RedbookMenuUtil { super(); } - /** - * {@inheritDoc} - */ - @Override - public void createMenusFromFile(String filename) { - xml = read(filename); - - createMenus(); - } - /** * {@inheritDoc} */ diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookNcoMenuUtil.java b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookNcoMenuUtil.java index 05a310c7f1..d583c7759e 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookNcoMenuUtil.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookNcoMenuUtil.java @@ -19,8 +19,7 @@ **/ package com.raytheon.uf.edex.plugin.redbook.menu; -import java.io.File; - +import com.raytheon.uf.common.localization.IPathManager; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; @@ -34,6 +33,7 @@ import com.raytheon.uf.common.status.UFStatus; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Mar 19, 2014 2857 mpduff Initial creation + * Jun 26, 2015 4512 mapeters Abstract out createMenusFromFile() * * * @@ -47,15 +47,15 @@ public class RedbookNcoMenuUtil extends RedbookMenuUtil { .getHandler(RedbookNcoMenuUtil.class); /** Menu type constant */ - private static final String MENU_TYPE = "ncepHydro" + File.separator + private static final String MENU_TYPE = NCEP_HYDRO + IPathManager.SEPARATOR + "nco"; /** HPC menu file */ private static final String NCO_MENU = "ncoMenus.xml"; /** HPC menu file full path */ - private static final String MENU_FILE = "menus" + File.separator - + MENU_TYPE + File.separator + NCO_MENU; + private static final String MENU_FILE = MENUS + IPathManager.SEPARATOR + + MENU_TYPE + IPathManager.SEPARATOR + NCO_MENU; /** * Constructor. @@ -64,16 +64,6 @@ public class RedbookNcoMenuUtil extends RedbookMenuUtil { super(); } - /** - * {@inheritDoc} - */ - @Override - public void createMenusFromFile(String filename) { - xml = read(filename); - - createMenus(); - } - /** * {@inheritDoc} */ diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookUaMenuUtil.java b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookUaMenuUtil.java index 58c8c6b479..b4b8124e67 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookUaMenuUtil.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/src/com/raytheon/uf/edex/plugin/redbook/menu/RedbookUaMenuUtil.java @@ -19,8 +19,7 @@ **/ package com.raytheon.uf.edex.plugin.redbook.menu; -import java.io.File; - +import com.raytheon.uf.common.localization.IPathManager; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; @@ -34,6 +33,7 @@ import com.raytheon.uf.common.status.UFStatus; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Mar 19, 2014 2860 mpduff Initial creation + * Jun 26, 2015 4512 mapeters Abstract out createMenusFromFile() * * * @@ -53,8 +53,8 @@ public class RedbookUaMenuUtil extends RedbookMenuUtil { private static final String UA_MENU = "uaMenus.xml"; /** HPC menu file full path */ - private static final String MENU_FILE = MENUS + File.separator + MENU_TYPE - + File.separator + UA_MENU; + private static final String MENU_FILE = MENUS + IPathManager.SEPARATOR + + MENU_TYPE + IPathManager.SEPARATOR + UA_MENU; /** * Constructor. @@ -63,16 +63,6 @@ public class RedbookUaMenuUtil extends RedbookMenuUtil { super(); } - /** - * {@inheritDoc} - */ - @Override - public void createMenusFromFile(String filename) { - xml = read(filename); - - createMenus(); - } - /** * {@inheritDoc} */ diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookCPCMenus.txt b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookCPCMenus.txt new file mode 100644 index 0000000000..4872374b07 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookCPCMenus.txt @@ -0,0 +1,27 @@ +# Release +submenu: "Hazards Charts" +#productButton: 5292 # PYIA88 drought monitor +#productButton: 5286 # PMNV88 Drought Outlook +# title: "3-10 Day Threats Assessment" +# productButton: 5289 # PEIY50 Precipitation Fcst +# productButton: 5290 # PTIY98 Temp/Wind Fcst +# productButton: 5291 # PYIY88 Soil/Wildfire Fcst + title: "3-7 Day Hazards Outlook" + productButton: 5432 # PEIY97 3-7 day Precipitation Fcst + productButton: 5434 # PTIY97 3-7 day Temperature/Wind Fcst + productButton: 5436 # PYIY97 3-7 day Soil/Wildfire Fcst + title: "8-14 Day Hazards Outlook" + productButton: 5433 # PEIY96 8-14 day Precipitation Fcst + productButton: 5435 # PTIY96 8-14 day Temperature/Wind Fcst + productButton: 5437 # PYIY96 8-14 day Soil/Wildfire Fcst + title: "6-10 Day Heat Index Fcst" + productButton: 5298 # PTAS90 >=85F for 3 days of 5 + productButton: 5299 # PTAS95 >=90F for 2 days of 5 + productButton: 5300 # PTAS00 >=95F for 1 day of 5 + productButton: 5383 # PTNR98 Max Heat Index Outlook + title: "8-14 Day Heat Index Fcst" + productButton: 5301 # PTAT90 >=85F for 3 days of 7 + productButton: 5302 # PTAT95 >=90F for 2 days of 7 + productButton: 5303 # PTAT00 >=95F for 1 day of 7 + productButton: 5247 # PTNT98 Max Heat Index Outlook +endSubmenu diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookDataKeys.txt b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookDataKeys.txt new file mode 100644 index 0000000000..929a903447 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookDataKeys.txt @@ -0,0 +1,239 @@ +5000 | | | | | | |redbook |KWBC. | |Redbook graphic master key +5013 | | | | |1|3600,2100|redbook/sfc/radar |PAWO82KWBC. | |PAWO82 Radar Summary +5014 | | | | |1|3600,2100|redbook/sfc/radar |PAWO83KWBC. | |PAWO83 Radar Legend +5015 | | | | | | |redbook/misc |PAW883KWBC. | |PAW883 redbook graphic +5021 | | | | | | |redbook/misc |PDKI59KWBC. | |PDKI59 redbook graphic +5238 | | | 72| | | |redbook/models/MRF/MSLP |PPKK01KWNO. | |PPKK01 gfs 72hr MSLP * +5239 | | | 96| | | |redbook/models/MRF/MSLP |PPKM01KWNO. | |PPKM01 gfs 96hr MSLP * +5240 | | |120| | | |redbook/models/MRF/MSLP |PPKO01KWNO. | |PPKO01 gfs 120hr MSLP * +5241 | | |144| | | |redbook/models/MRF/MSLP |PPKQ01KWNO. | |PPKQ01 gfs 144hr MSLP * +5046 | | | | | |21600 |redbook/sfc/pcp/excrain |PEI745KWBC. | |PEI745 day 1 excessive rainfall +5200 | | | 6 | | |21600 |redbook/sfc/pcp/QPF |PEIB40KWNO. | |PEIB40 0-6HR QPF +5047 | | |12 | | |21600 |redbook/sfc/pcp/QPF |PEIC43KWBC. | |PEIC43 6-12HR QPF +5049 | | |18 | | |21600 |redbook/sfc/pcp/QPF |PEID44KWBC. | |PEID44 12-18HR QPF +5201 | | |24 | | |21600 |redbook/sfc/pcp/QPF |PEIE40KWNO. | |PEIE40 18-24HR QPF +5202 | | |30 | | |21600 |redbook/sfc/pcp/QPF |PEIF40KWNO. | |PEIF40 24-30HR QPF +5050 | | |24 | | |21600 |redbook/sfc/pcp/QPF |PEIE41KWBC. | |PEIE41 24hr qpf over 24hr +5053 | | |48 | | | |redbook/sfc/pcp/QPF |PEII42KWBC. | |PEII42 48hr qpf over 24hr +5048 | | |12 | | |21600 |redbook/sfc/pcp/QPF |PEIC61KWBC. | |PEIC61 12hr inst prcp +5051 | | |24 | | |21600 |redbook/sfc/pcp/QPF |PEIE62KWBC. | |PEIE62 24hr inst prcp +5052 | | |36 | | | |redbook/sfc/pcp/QPF |PEIG63KWBC. | |PEIG63 36hr clds/precip +5054 | | |48 | | | |redbook/sfc/pcp/QPF |PEII64KWBC. | |PEII64 48hr clds/precip +5055 | | |60| |1|86400,86400|redbook/sfc/pcp/total |PEIO46KWBC. | |PEIO46 5 dy total precip +# estimating freq for 5439 +5439| | |168| | |43200,43200|redbook/sfc/pcp/total |PEIS46KWBC. | |PEIS46 7 dy total precip +5056 | | | | | | |redbook/sfc/pcp/daily |PEWA31KWBC. | |PEWA31 Daily Precipitation +5057 | | | | | | |redbook/sfc/pcp/snow |PEWA32KWBC. | |PEWA32 Snow Cover Plot +5058 | | | | | | |redbook/sfc/pcp/h2o |PEWA33KWBC. | |PEWA33 pcp h20 plot +5059 | | | | | | |redbook/sfc/pcp/h2o |PEWA34KWBC. | |PEWA34 pcp h20 anal +5062 | | |12 | | |21600 |redbook/sfc/wxdepict |PGIC42KWBC. | |PGIC42 Wx Depiction +5063 | | |24 | | |21600 |redbook/sfc/wxdepict |PGIE43KWBC. | |PGIE43 Wx Depiction +5064 | | | | | |3600 |redbook/sfc/wxdepict |PGWA31KWBC. | |PGWA31 Wx Depiction plot +5065 | | | | | |3600 |redbook/sfc/wxdepict |PGWA32KWBC. | |PGWA32 Wx Depiction analysis +5066 | | | | | |3600 |redbook/sfc/wxdepict |PGWA39KWBC. | |PGWA39 Wx Depiction plot +5067 | | |6 | | |10800 |redbook/sfc/tstm/prob |PJMB44KWBC. | |PJMB44 tstm prob\ 2-6hr +5068 | | |6 | | |10800 |redbook/sfc/tstm/prob |PJMB45KWBC. | |PJMB45 svr wx prob\ 2-6hr +5069 | | | | | |3600 |redbook/sfc/tstm/outlook|PGWE46KWNS. | |PGWE46 day 1 conv outlook +5072 | | |48 | | |3600 |redbook/sfc/tstm/outlook|PGWI47KWNS. | |PGWI47 day 2 conv outlook +5215 | | | 96| | | |redbook/models/UKMO |PHZM50KWNO. | |PHZM50 96 ukmo 500 hgt +5101 | | |120| | | |redbook/models/UKMO |PHZO50KWNO. | |PHZO50 120 ukmo 500 hgt +5216 | | |144| | | |redbook/models/UKMO |PHZQ50KWNO. | |PHZQ50 144 ukmo 500 hgt +5102 | | | | | | |redbook/misc |PLQI51KWBC. | |PLQI51 redbook graphic +5104 | | | | | | |redbook/misc |PNWA68KWBC. | |PNWA68 redbook graphic +5107 | | | | | | |redbook/misc |POWA31KWBC. | |POWA31 redbook graphic +5108 | | |72 | |1|86400,43200|redbook/sfc/fronts |PPHK01KWBC. | |PPHK01 day 3 frnt/pres +5109 | | |96 | |1|86400,43200|redbook/sfc/fronts |PPHM01KWBC. | |PPHM01 day 4 frnt/pres +5110 | | |120| |1|86400,43200|redbook/sfc/fronts |PPHO01KWBC. | |PPHO01 day 5 frnt/pres +5204 | | |0 | | |10800 |redbook/sfc/fronts |PYAA98KWNO. | |PYAA98 frontal analysis +5243 | | |0 | | |21600 |redbook/sfc/fronts |PYBA98KWNO. | |PYBA98 NA frontal analysis +5111 | | |12 | | |21600 |redbook/sfc/fronts |PPIC01KWBC. | |PPIC01 12hr frnt/pres +5112 | | |24 | | |21600 |redbook/sfc/fronts |PPIE01KWBC. | |PPIE01 24hr frnt/pres +5113 | | |36 | | | |redbook/sfc/fronts |PPIG01KWBC. | |PPIG01 36hr frnt/pres +5114 | | |48 | | | |redbook/sfc/fronts |PPII01KWBC. | |PPII01 48hr frnt/pres +5115 | | | | | |10800 |redbook/sfc/MSLP |PPAA89KWNO. | |PPAA89 mslp anal +5244 | | | | | |21600 |redbook/sfc/MSLP |PPBA89KWNO. | |PPBA89 NA mslp anal +5227 | | | 96| | | |redbook/models/UKMO |PPZM50KWNO. | |PPZM50 ukmo 96 mslp +5118 | | |120| | | |redbook/models/UKMO |PPZO50KWNO. | |PPZO50 ukmo 120 mslp +5288 | | |144| | | |redbook/models/UKMO |PPZQ50KWNO. | |PPZQ50 ukmo 144 mslp +5134 | | | | | | |redbook/sfc/rh |PRWA51KWBC. | |PRWA51 sfc-500 rh plot +5136 | | |12 | | |21600 |redbook/sfc/temp/frzglvl|PTIC94KWBC. | |PTIC94 12hr frz lvl anal * +5137 | | |24 | | |21600 |redbook/sfc/temp/frzglvl|PTIE94KWBC. | |PTIE94 24hr frz lvl anal * +5138 | | |60 | | | |redbook/sfc/temp/anomaly|PTIO52KWBC. | |PTIO52 5dy max temp anom +5139 | | |60 | | | |redbook/sfc/temp/anomaly|PTIO53KWBC. | |PTIO53 5dy min temp anom +5140 | | | | | | |redbook/sfc/temp/maxmin |PTWA31KWBC. | |PTWA31 Max Temperatures +5141 | | | | | | |redbook/sfc/temp/maxmin |PTWA32KWBC. | |PTWA32 Min Temperatures +5142 | | | | | | |redbook/sfc/temp/frzglvl|PTWA94KWBC. | |PTWA94 freezing level plot +5145 | | | | | | |redbook/sfc/temp/frzglvl|PTWA93KWBC. | |PTWA93 freezing level analysis +5146 | | | | | | |redbook/misc |PXVA01KWBC. | |PXVA01 redbook graphic +5147 | | | | | | |redbook/sfc/LI-KI |PXWA50KWBC. | |PXWA50 lifted-K plot +5148 |d2_national| | | | | |redbook/upperair |PYMA20KWBC. | |PYMA20 200mb plot +5149 |d2_national| | | | | |redbook/upperair |PYMA25KWBC. | |PYMA25 250mb plot +5150 |d2_national| | | | | |redbook/upperair |PYMA30KWBC. | |PYMA30 300mb plot +5151 |d2_national| | | | | |redbook/upperair |PYMA50KWBC. | |PYMA50 500mb plot +5152 |d2_national| | | | | |redbook/upperair |PYMA70KWBC. | |PYMA70 700mb plot +5153 |d2_national| | | | | |redbook/upperair |PYMA85KWBC. | |PYMA85 850mb plot +5154 | | | | | |10800 |redbook/sfc/geostroph |PYWA31KWBC. | |PYWA31 sfc geo wind +5155 | | | | | |10800 |redbook/sfc/geostroph |PYWA32KWBC. | |PYWA32 sfc geo rel vort +5159 | | |72 | | | |redbook/sfc/temp/pop |PYWK43KWBC. | |PYWK43 day 3 temp/pop +5160 | | | | | | |redbook/misc |PYWK62KWBC. | |PYWK62 redbook graphic +5161 | | |96 | | | |redbook/sfc/temp/pop |PYWM44KWBC. | |PYWM44 day 4 temp/pop +5162 | | |120| | | |redbook/sfc/temp/pop |PYWO45KWBC. | |PYWO45 day 5 temp/pop +5163 | | | | | | |redbook/misc |PZKY51KWBC. | |PZKY51 redbook graphic +5164 | | |180| |1|86400,86400|redbook/sfc/pcp/total |PEIY47KWBC. | |PEIY47 6-10 day Total Pcp +5169 | | |180| | | |redbook/sfc/temp/anomaly|PTIY51KWBC. | |PTIY51 6-10 day Temp Anomaly +5172 | | |180| | | |redbook/misc |PHBV50KWBC. | |PHBV50 6-10 day mean 500 Height +5245 | | |0 | | |10800 |redbook/marine |PWIA98KWNM. | |PWIA98 WATL wind/wave anal +5246 | | |24 | | | |redbook/marine |PWIE98KWNM. | |PWIE98 WATL wind/wave 24hr +5248 | | |0 | | |10800 |redbook/marine |PWIA97KWNM. | |PWIA97 EPAC wind/wave anal +5249 | | |24 | | | |redbook/marine |PWIE97KWNM. | |PWIE97 EPAC wind/wave 24hr +#5289 | | |-10| | |86400,43200|redbook/sfc/drought |PEIY50KWNC. | |PEIY50 3-10 Day Threats Assessment: Precip FCST +#5290 | | |-10| | |86400,43200|redbook/sfc/drought |PTIY98KWNC. | |PTIY98 3-10 Day Threats Assessment: Temp/Wind FCST +#5291 | | |-10| | |86400,43200|redbook/sfc/drought |PYIY88KWNC. | |PYIY88 3-10 Day Threats Assessment: Soil/Wildfire FCST +5432 | | |-7 | | |86400,43200|redbook/sfc/drought |PEIY97KWNC.| |PEIY97 Precip Hazards 3-7 Days Outlook +5433 | | |-14| | |86400,43200|redbook/sfc/drought |PEIY96KWNC.| |PEIY96 Precip Hazards 8-14 Days Outlook +5434 | | |-7 | | |86400,43200|redbook/sfc/drought |PTIY97KWNC. | |PTIY97 Temp/Wind Hazards 3-7 Days Outlook +5435 | | |-14| | |86400,43200|redbook/sfc/drought |PTIY96KWNC. | |PTIY96 Temp/Wind Hazards 8-14 Days Outlook +5436 | | |-7 | | |86400,43200|redbook/sfc/drought |PYIY97KWNC. | |PYIY97 Soil/Wildfire Hazards 3-7 Days Outlook +5437 | | |-14| | |86400,43200|redbook/sfc/drought |PYIY96KWNC. | |PYIY96 Soil/Wildfire Hazards 8-14 Days Outlook +5293 | | |72 | | | |redbook/sfc/pcp/QPF |PEIK98KWNH. | |PEIK98 Day 3 QPF - Time Proj 60-72Hrs +5381 | | |72 | | |86400,43200|redbook/sfc/drought |PTNK98KWNH. | |PTNK98 Day 3 Heat Index Prob >=85F +5386 | | |96 | | |86400,43200|redbook/sfc/drought |PTNM98KWNH. | |PTNM98 Day 4 Heat Index Prob >=85F +5387 | | |120| | |86400,43200|redbook/sfc/drought |PTNO98KWNH. | |PTNO98 Day 5 Heat Index Prob >=85F +5382 | | |144| | |86400,43200|redbook/sfc/drought |PTNQ98KWNH. | |PTNQ98 Day 6 Heat Index Prob >=85F +5383 | | |-10| | |86400,43200|redbook/sfc/drought |PTNR98KWNC. | |PTNR98 6-10 Day Max Heat Index Outlook +5247 | | |-14| | |86400,43200|redbook/sfc/drought |PTNT98KWNC. | |PTNT98 8-14 Day Max Heat Index Outlook +5388 | | |168| | |86400,43200|redbook/sfc/drought |PTNS98KWNH. | |PTNS98 Day 7 Heat Index Prob >=85F +5298 | | |-10| | |86400,43200|redbook/sfc/drought |PTAS90KWNC. | |PTAS90 6-10 Day FCST - Heat Index >=85F for 3+ Days +5299 | | |-10| | |86400,43200|redbook/sfc/drought |PTAS95KWNC. | |PTAS95 6-10 Day FCST - Heat Index >=90F for 2+ Days +5300 | | |-10| | |86400,43200|redbook/sfc/drought |PTAS00KWNC. | |PTAS00 6-10 Day FCST - Heat Index >=95F for 1+ Day +5301 | | |-14| | |86400,43200|redbook/sfc/drought |PTAT90KWNC. | |PTAT90 8-14 Day FCST - Heat Index >=85F for 3+ Days +5302 | | |-14| | |86400,43200|redbook/sfc/drought |PTAT95KWNC. | |PTAT95 8-14 Day FCST - Heat Index >=90F for 2+ Days +5303 | | |-14| | |86400,43200|redbook/sfc/drought |PTAT00KWNC. | |PTAT00 8-14 Day FCST - Heat Index >=95F for 1+ Day +5304 | | |36 | | |21600 |redbook/sfc/pcp/QPF |PEBF98KWNH. | |PEBF98 6Hr QPF - Time Proj 30-36Hrs +5305 | | |42 | | |21600 |redbook/sfc/pcp/QPF |PEBG98KWNH. | |PEBG98 6Hr QPF - Time Proj 36-42Hrs +5306 | | |48 | | |21600 |redbook/sfc/pcp/QPF |PEBH98KWNH. | |PEBH98 6Hr QPF - Time Proj 42-48Hrs +5307 | | |54 | | |21600 |redbook/sfc/pcp/QPF |PEBI88KWNH. | |PEBI88 6Hr QPF - Time Proj 48-54Hrs +5308 | | |60 | | |21600 |redbook/sfc/pcp/QPF |PEBI98KWNH. | |PEBI98 6Hr QPF - Time Proj 54-60Hrs +5309 | | |66 | | |21600 |redbook/sfc/pcp/QPF |PEBJ88KWNH. | |PEBJ88 6Hr QPF - Time Proj 60-66Hrs +5310 | | |72 | | |21600 |redbook/sfc/pcp/QPF |PEBJ98KWNH. | |PEBJ98 6Hr QPF - Time Proj 66-72Hrs +5311 | | |78 | | |21600 |redbook/sfc/pcp/QPF |PEBK98KWNH. | |PEBK98 6Hr QPF - Time Proj 72-78Hrs +5312 |b_TSA | | | | |21600 |redbook/sfc/fronts |PYNA98KNHC. | |PYNA98 Tropical Surface Analysis +5313 |b05 | | | | | |redbook/upperair |PWAA85KNHC. | |PWAA85 Atlantic 850MB StreamLines and Wind Analysis +5314 |b05 | | | | | |redbook/upperair |PWAA20KNHC. | |PWAA20 Atlantic 200MB StreamLines and Wind Analysis +5315 |b05 | | | | | |redbook/upperair |PWAA00KNHC. | |PWAA00 Atlantic Deep Layer Mean Circulation 1000-100MB +5316 |b05 | | | | | |redbook/upperair |PWAA65KNHC. | |PWAA65 Atlantic 850-200MB Wind Shear/Wind Analysis +5317 |b06 | | | | | |redbook/marine |PWBA88KNHC. | |PWBA88 Eastern Pacific Winds/Seas Analysis +5318 |b07 | | | | | |redbook/upperair |PWDA00KNHC. | |PWDA00 Pacific Deep Layer Mean Circulation 1000-100MB +5319 |b07 | | | | | |redbook/upperair |PWDA65KNHC. | |PWDA65 Pacific 850-200MB Wind Shear/Wind Analysis +5320 |b08 | |00 | | |21600 |redbook/marine |PWEA88KNHC. | |PWEA88 Caribbean Wind/Seas (ft) 00Hr FCST +5321 |b08 | |12 | | |21600 |redbook/marine |PWEC88KNHC. | |PWEC88 Caribbean Wind/Seas (ft) 12Hr FCST +5322 |b08 | |24 | | | |redbook/marine |PWEE88KNHC. | |PWEE88 Caribbean Wind/Seas (ft) 24Hr FCST +5323 |b08 | |36 | | | |redbook/marine |PWEG88KNHC. | |PWEG88 Caribbean Wind/Seas (ft) 36Hr FCST +5324 | | | | | |21600 |redbook/sfc/fronts |PYAA89KWNM. | |PYAA89 Northern Atlantic Hemispheric Surface Analysis +5325 | | | | | |86400,43200|redbook/marine |PJAA88KWNM. | |PJAA88 Northern Atlantic Sig Wave Analysis +5326 | | |48 | | | |redbook/marine |PJAI88KWNM. | |PJAI88 48Hr North Atlantic Sig Wave/Winds FCST +5327 | | |24 | | | |redbook/sfc/fronts |PPAE89KWNM. | |PPAE89 24Hr Western Atlantic Fronts/Pressure FCST +5328 | | |48 | | | |redbook/sfc/fronts |PPAI89KWNM. | |PPAI89 48Hr North Atlantic Fronts/Pressure/Winds FCST +5329 | | |96 | | |86400 |redbook/sfc/fronts |PPAM89KWNM. | |PPAM89 96Hr North Atlantic Fronts/Pressure/Winds FCST +5330 | | | | | |21600 |redbook/sfc/fronts |PYBA89KWNM. | |PYBA89 Northern Pacific Hemispheric Surface Analysis +5331 | | | | | |86400 |redbook/marine |PJBA88KWNM. | |PJBA88 North Pacific Sig Wave Analysis +5332 | | |48 | | | |redbook/marine |PJBI88KWNM. | |PJBI88 48Hr North Pacific Sig Wave/Winds/FCST +5333 | | |24 | | | |redbook/sfc/fronts |PPBE89KWNM. | |PPBE89 24Hr Eastern Pacific Fronts/Pressure FCST +5334 | | |48 | | | |redbook/sfc/fronts |PPBI89KWNM. | |PPBI89 48Hr North Pacific Fronts/Pressure/Winds FCST +5335 | | |96 | | |86400 |redbook/sfc/fronts |PPBM89KWNM. | |PPBM89 96Hr North Pacific Fronts/Pressure/Winds FCST +5336 | | |24 | | | |redbook/marine |PGNE88KWNM. | |PGNE88 24Hr Marine Dense Fog FCST +5337 | | |24 | | | |redbook/marine |PGNE98KWNM. | |PGNE98 24Hr Marine Freezing Spray FCST +5338 | | |144| | |86400,43200|redbook/sfc/fronts |PPTG98KWNO. | |PPTG98 Day 6 Frontal Position FCST +5339 | | |168| | |86400,43200|redbook/sfc/fronts |PPTR98KWNO. | |PPTR98 Day 7 Frontal Position FCST +5340 | | |144| | |86400,43200|redbook/sfc/temp/pop |PYWQ46KWNO. | |PYWQ46 Day 6 Temp and POP FCST +5341 | | |168| | |86400,43200|redbook/sfc/temp/pop |PYWS98KWNO. | |PYWS98 Day 7 Temp and POP FCST +5342 | | |-45| | | |redbook/sfc/pcp/total|PEIV98KWNC. | |PEIV98 30 Day Precip Anom +5343 | | |-105| | | |redbook/sfc/pcp/total|PEIW01KWNC. | |PEIW01 0.5 Mo (15-105 day) Precip Outlook +5344 | | |-135| | | |redbook/sfc/pcp/total|PEIW02KWNC. | |PEIW02 1.5 Mo (45-135 day) Precip Outlook +5345 | | |-165| | | |redbook/sfc/pcp/total|PEIW03KWNC. | |PEIW03 2.5 Mo (75-165 day) Precip Outlook +5346 | | |-195| | | |redbook/sfc/pcp/total|PEIW04KWNC. | |PEIW04 3.5 Mo (105-195 day) Precip Outlook +5347 | | |-225| | | |redbook/sfc/pcp/total|PEIW05KWNC. | |PEIW05 4.5 Mo (135-225 day) Precip Outlook +5348 | | |-255| | | |redbook/sfc/pcp/total|PEIW06KWNC. | |PEIW06 5.5 Mo (165-255 day) Precip Outlook +5349 | | |-285| | | |redbook/sfc/pcp/total|PEIW07KWNC. | |PEIW07 6.5 Mo (195-285 day) Precip Outlook +5350 | | |-315| | | |redbook/sfc/pcp/total|PEIW08KWNC. | |PEIW08 7.5 Mo (225-315 day) Precip Outlook +5351 | | |-345| | | |redbook/sfc/pcp/total|PEIW09KWNC. | |PEIW09 8.5 Mo (255-345 day) Precip Outlook +5352 | | |-375| | | |redbook/sfc/pcp/total|PEIW10KWNC. | |PEIW10 9.5 Mo (285-375 day) Precip Outlook +5353 | | |-405| | | |redbook/sfc/pcp/total|PEIW11KWNC. | |PEIW11 10.5 Mo (315-405 day) Precip Outlook +5354 | | |-435| | | |redbook/sfc/pcp/total|PEIW12KWNC. | |PEIW12 11.5 Mo (345-435 day) Precip Outlook +5355 | | |-465| | | |redbook/sfc/pcp/total|PEIW13KWNC. | |PEIW13 12.5 Mo (375-465 day) Precip Outlook +5356 | | |-45 | | | |redbook/sfc/temp/anomaly|PTIV98KWNC. | |PTIV98 30 Day Temp Anom +5357 | | |-105| | | |redbook/sfc/temp/norm|PTIW01KWNC. | |PTIW01 0.5 Mo (15-105 day) Temp Outlook +5358 | | |-135| | | |redbook/sfc/temp/norm|PTIW02KWNC. | |PTIW02 1.5 Mo (45-135 day) Temp Outlook +5359 | | |-165| | | |redbook/sfc/temp/norm|PTIW03KWNC. | |PTIW03 2.5 Mo (75-165 day) Temp Outlook +5360 | | |-195| | | |redbook/sfc/temp/norm|PTIW04KWNC. | |PTIW04 3.5 Mo (105-195 day) Temp Outlook +5361 | | |-225| | | |redbook/sfc/temp/norm|PTIW05KWNC. | |PTIW05 4.5 Mo (135-225 day) Temp Outlook +5362 | | |-255| | | |redbook/sfc/temp/norm|PTIW06KWNC. | |PTIW06 5.5 Mo (165-255 day) Temp Outlook +5363 | | |-285| | | |redbook/sfc/temp/norm|PTIW07KWNC. | |PTIW07 6.5 Mo (195-285 day) Temp Outlook +5364 | | |-315| | | |redbook/sfc/temp/norm|PTIW08KWNC. | |PTIW08 7.5 Mo (225-315 day) Temp Outlook +5365 | | |-345| | | |redbook/sfc/temp/norm|PTIW09KWNC. | |PTIW09 8.5 Mo (255-345 day) Temp Outlook +5366 | | |-375| | | |redbook/sfc/temp/norm|PTIW10KWNC. | |PTIW10 9.5 Mo (285-375 day) Temp Outlook +5367 | | |-405| | | |redbook/sfc/temp/norm|PTIW11KWNC. | |PTIW11 10.5 Mo (315-405 day) Temp Outlook +5368 | | |-435| | | |redbook/sfc/temp/norm|PTIW12KWNC. | |PTIW12 11.5 Mo (345-435 day) Temp Outlook +5369 | | |-465| | | |redbook/sfc/temp/norm|PTIW13KWNC. | |PTIW13 12.5 Mo (375-465 day) Temp Outlook +5370 | | | 12| | | |redbook/sfc/firewx |PMWE98KWNS. | |PMWE98 Day 1 Fire Wx Outlook +5371 | | | 36| | | |redbook/sfc/firewx |PMWI98KWNS. | |PMWI98 Day 2 Fire Wx Outlook +5372 | | |-11 | | | |redbook/sfc/pcp/total|PETT00KWNC. | |PETT00 8-14 day precip prob +5373 | | |-11 | | | |redbook/sfc/temp/norm|PTTU98KWNC. | |PTTU98 8-14 day temp prob +5374 | | |-11 | | | |redbook/misc |PHTT50KWNC. | |PHTT50 8-14 day mean 500 ht +5375 | | |-11 | | | |redbook/misc |PHTT51KWNC. | |PHTT51 8-14 day mean 500 ht anomaly +5376 | | |24 | | | |redbook/sfc/tstm/outlook|PENE00KWNS.| |PENE00 Day 1 Hail outlook +5377 | | |24 | | | |redbook/sfc/tstm/outlook|PWNE00KWNS.| |PWNE00 Day 1 Wind outlook +5378 | | |24 | | | |redbook/sfc/tstm/outlook|PGNE00KWNS.| |PGNE00 Day 1 Tornado outlook +5379 | | |48 | | | |redbook/sfc/tstm/outlook|PGNI00KWNS.| |PGNI00 Day 2 Combined Severe Outlook +5380 | | |180 | | | |redbook/misc |PHNT50KWNC.| |PHNT50 6-10 day 500 Hgt Anomaly +5384 | | |72 | | | |redbook/sfc/tstm/outlook|PZNK00KWNS.| |PZNK00 Day 3 Combined Severe Outlook +5385 | | |72 | | | |redbook/sfc/tstm/outlook|PGWK48KWNS.| |PGWK48 Day 3 Convective Outlook +5389 | | |24 | | | |redbook/sfc/pcp/excrain |PENJ88KWNH.| |PENJ88 Sig River Flood Outlook +5390 | | | | | |60 |redbook/sfc/tstm/outlook|PGNA00KWNS.| |PGNA00 Active Mesoscale Disc Summary +5391 | | |24 | | | |redbook/sfc/pcp/snow |PSBB04KWNH. | |PSBB04 Day 1 Prob 4+" Snow +5392 | | |24 | | | |redbook/sfc/pcp/snow |PSBB08KWNH. | |PSBB08 Day 1 Prob 8+" Snow +5393 | | |24 | | | |redbook/sfc/pcp/snow |PSBB12KWNH. | |PSBB12 Day 1 Prob 12+" Snow +5394 | | |24 | | | |redbook/sfc/pcp/snow |PSBB25KWNH. | |PSBB25 Day 1 Prob .25+" Ice +5395 | | |48 | | | |redbook/sfc/pcp/snow |PSBC04KWNH. | |PSBC04 Day 2 Prob 4+" Snow +5396 | | |48 | | | |redbook/sfc/pcp/snow |PSBC08KWNH. | |PSBC08 Day 2 Prob 8+" Snow +5397 | | |48 | | | |redbook/sfc/pcp/snow |PSBC12KWNH. | |PSBC12 Day 2 Prob 12+" Snow +5398 | | |48 | | | |redbook/sfc/pcp/snow |PSBC25KWNH. | |PSBC25 Day 2 Prob .25+" Ice +5399 | | |72 | | | |redbook/sfc/pcp/snow |PSBD04KWNH. | |PSBD04 Day 3 Prob 4+" Snow +5400 | | |72 | | | |redbook/sfc/pcp/snow |PSBD08KWNH. | |PSBD08 Day 3 Prob 8+" Snow +5401 | | |72 | | | |redbook/sfc/pcp/snow |PSBD12KWNH. | |PSBD12 Day 3 Prob 12+" Snow +5402 | | |72 | | | |redbook/sfc/pcp/snow |PSBD25KWNH. | |PSBD25 Day 3 Prob .25+" Ice +5403 | | |72 | | | |redbook/sfc/fronts |PSAO72KWNH. | |PSAO72 3-Day Sig Winter Low Tracks +5404 | | |-105| | | |redbook/sfc/pcp/total|PENV01KWNC. | |PENV01 0.5 Mo (15-105 day) 50% POE Precip Outlook +5405 | | |-135| | | |redbook/sfc/pcp/total|PENV02KWNC. | |PENV02 1.5 Mo (45-135 day) 50% POE Precip Outlook +5406 | | |-165| | | |redbook/sfc/pcp/total|PENV03KWNC. | |PENV03 2.5 Mo (75-165 day) 50% POE Precip Outlook +5407 | | |-195| | | |redbook/sfc/pcp/total|PENV04KWNC. | |PENV04 3.5 Mo (105-195 day) 50% POE Precip Outlook +5408 | | |-225| | | |redbook/sfc/pcp/total|PENV05KWNC. | |PENV05 4.5 Mo (135-225 day) 50% POE Precip Outlook +5409 | | |-255| | | |redbook/sfc/pcp/total|PENV06KWNC. | |PENV06 5.5 Mo (165-255 day) 50% POE Precip Outlook +5410 | | |-285| | | |redbook/sfc/pcp/total|PENV07KWNC. | |PENV07 6.5 Mo (195-285 day) 50% POE Precip Outlook +5411 | | |-315| | | |redbook/sfc/pcp/total|PENV08KWNC. | |PENV08 7.5 Mo (225-315 day) 50% POE Precip Outlook +5412 | | |-345| | | |redbook/sfc/pcp/total|PENV09KWNC. | |PENV09 8.5 Mo (255-345 day) 50% POE Precip Outlook +5413 | | |-375| | | |redbook/sfc/pcp/total|PENV10KWNC. | |PENV10 9.5 Mo (285-375 day) 50% POE Precip Outlook +5414 | | |-405| | | |redbook/sfc/pcp/total|PENV11KWNC. | |PENV11 10.5 Mo (315-405 day) 50% POE Precip Outlook +5415 | | |-435| | | |redbook/sfc/pcp/total|PENV12KWNC. | |PENV12 11.5 Mo (345-435 day) 50% POE Precip Outlook +5416 | | |-465| | | |redbook/sfc/pcp/total|PENV13KWNC. | |PENV13 12.5 Mo (375-465 day) 50% POE Precip Outlook +5417 | | |-105| | | |redbook/sfc/temp/norm|PTNV01KWNC. | |PTNV01 0.5 Mo (15-105 day) 50% POE Temp Outlook +5418 | | |-135| | | |redbook/sfc/temp/norm|PTNV02KWNC. | |PTNV02 1.5 Mo (45-135 day) 50% POE Temp Outlook +5419 | | |-165| | | |redbook/sfc/temp/norm|PTNV03KWNC. | |PTNV03 2.5 Mo (75-165 day) 50% POE Temp Outlook +5420 | | |-195| | | |redbook/sfc/temp/norm|PTNV04KWNC. | |PTNV04 3.5 Mo (105-195 day) 50% POE Temp Outlook +5421 | | |-225| | | |redbook/sfc/temp/norm|PTNV05KWNC. | |PTNV05 4.5 Mo (135-225 day) 50% POE Temp Outlook +5422 | | |-255| | | |redbook/sfc/temp/norm|PTNV06KWNC. | |PTNV06 5.5 Mo (165-255 day) 50% POE Temp Outlook +5423 | | |-285| | | |redbook/sfc/temp/norm|PTNV07KWNC. | |PTNV07 6.5 Mo (195-285 day) 50% POE Temp Outlook +5424 | | |-315| | | |redbook/sfc/temp/norm|PTNV08KWNC. | |PTNV08 7.5 Mo (225-315 day) 50% POE Temp Outlook +5425 | | |-345| | | |redbook/sfc/temp/norm|PTNV09KWNC. | |PTNV09 8.5 Mo (255-345 day) 50% POE Temp Outlook +5426 | | |-375| | | |redbook/sfc/temp/norm|PTNV10KWNC. | |PTNV10 9.5 Mo (285-375 day) 50% POE Temp Outlook +5427 | | |-405| | | |redbook/sfc/temp/norm|PTNV11KWNC. | |PTNV11 10.5 Mo (315-405 day) 50% POE Temp Outlook +5428 | | |-435| | | |redbook/sfc/temp/norm|PTNV12KWNC. | |PTNV12 11.5 Mo (345-435 day) 50% POE Temp Outlook +5429 | | |-465| | | |redbook/sfc/temp/norm|PTNV13KWNC. | |PTNV13 12.5 Mo (375-465 day) 50% POE Temp Outlook +#5430 | | |192 | | |86400,43200|redbook/sfc/tstm/outlook|PGNM98KWNS.| |PGNM98 Day 4-8 Composite Severe Outlook +5431 | | |192 | | |86400,43200|redbook/sfc/firewx |PGNO98KWNS.| |PGNO98 Day 3-8 Composite Fire Wx Outlook +5438 | | | | | | |redbook/sfc/pcp/excrain |PENA01KWNH.| |PENA01 Mesoscale Precip +5440 | | |-4 | | |86400,43200|redbook/sfc/tstm/outlook|PGNW49KWNS.| |PGNW49 Day 4 Severe Outlook +5441 | | |120 | | |86400,43200|redbook/sfc/tstm/outlook|PGNW50KWNS.| |PGNW50 Day 5 Severe Outlook +5442 | | |-6 | | |86400,43200|redbook/sfc/tstm/outlook|PGNW51KWNS.| |PGNW51 Day 6 Severe Outlook +5443 | | |-7 | | |86400,43200|redbook/sfc/tstm/outlook|PGNW52KWNS.| |PGNW52 Day 7 Severe Outlook +5444 | | |-8 | | |86400,43200|redbook/sfc/tstm/outlook|PGNW53KWNS.| |PGNW53 Day 8 Severe Outlook diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookDepictKeys.txt b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookDepictKeys.txt new file mode 100644 index 0000000000..bb6d976360 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookDepictKeys.txt @@ -0,0 +1,131 @@ + 5013 |33|5013| |0 |1 |Radar Summary |Radar Summary |1 |0 |1 | + 5014 |33|5014| |0 |1 |Radar Legends |Radar Legends |1 |0 |1 | + 5021 |33|5021| |0 |1 |Redbook graphic PDKI59 |PDKI59 |1 |0 |1 | + 5046 |33|5046| |0 |1 |Day 1 Excessive Rainfall|Day 1 Exssv Rain |1 |0 |1 | + 5047 |33|5200,5047,5049,5201,5202,5304,5305,5306,5307,5308,5309,5310,5311| |0|1 |Precip Fcst - 6hr accum |6h QPF |1 |0 |1 | + 5050 |33|5050,5053,5293| |0|1 |Precip Fcst - 24hr accum|24h QPF |1 |0 |1 | + 5048 |33|5048,5051,5052,5054| |0|1 |Instantaneous Precip |Inst Precip |1 |0 |1 | + 5055 |33|5055| |0 |1 |5 Day Total Precip |5-day QPF |1 |0 |1 | + 5439 |33|5439| |0 |1 |7 Day Total Precip |7-day QPF |1 |0 |1 | + 5056 |33|5056| |0 |1 |Daily Precipitation |Obs Precip |1 |0 |1 | + 5057 |33|5057| |0 |1 |Snow Cover Plot |Snow Cover |1 |0 |1 | + 5058 |33|5058| |0 |1 |Precip H20 Plot |Precip H2O Plot |1 |0 |1 | + 5059 |33|5059| |0 |1 |Precip H20 Analysis |Precip H2O Anal |1 |0 |1 | + 5062 |33|5062,5063| |0|1 |Wx Depiction Fcst |Wx Depict Fcst |1 |0 |1 | + 5064 |33|5064| |0 |1 |Wx Depiction plot |Wx Depict Plot |1 |0 |1 | + 5065 |33|5065| |0 |1 |Wx Depiction analysis |Wx Depict Anal |1 |0 |1 | + 5066 |33|5066| |0 |1 |Wx Depiction plot |Wx Depict Plot |1 |0 |1 | + 5069 |33|5069| |0 |1 |Day One Convectv Outlook|Conv Otlk Day1 |1 |0 |1 | + 5072 |33|5072| |0 |1 |Day Two Convectv Outlook|Conv Otlk Day2 |1 |0 |1 | + 5101 |33|5215,5101,5216| |0 |1 |UKMO 500 Height |UKMO 500 Hgt |1 |0 |1 | + 5102 |33|5102| |0 |1 |Redbook graphic PLQI51 |PLQI51 |1 |0 |1 | + 5104 |33|5104| |0 |1 |Redbook graphic PNWA68 |PNWA68 |1 |0 |1 | + 5107 |33|5107| |0 |1 |Redbook graphic POWA31 |POWA31 |1 |0 |1 | + 5108 |33|5108,5109,5110,5338,5339| |0 |1 |Fronts/Pressure |Fronts/Pres |1 |0 |1 | + 5111 |33|5061,5111,5112,5113,5114| |0 |1 |Fronts/Pressure |Fronts/Pres |1 |0 |1 | + 5204 |33|5204| |0 |1 |Sfc Frontal Analysis |Sfc Fronts |1 |0 |1 | + 5243 |33|5243| |0 |1 |Sfc Frontal Analysis |NA Sfc Fronts |1 |0 |1 | + 5115 |33|5115| |0 |1 |MSL Pressure Analysis |MSLP Anal |1 |0 |1 | + 5244 |33|5244| |0 |1 |MSL Pressure Analysis |NA MSLP Anal |1 |0 |1 | + 5118 |33|5227,5118,5288| |0 |1 |UKMO MSL Pressure |UKMO MSLP |1 |0 |1 | + 5134 |33|5134| |0 |1 |Surface-500mb RH Plot |Sfc-500 RH plot |1 |0 |1 | + 5136 |33|5136,5137| |0 |1 |Freezing Level Fcst |Fzlvl Fcst |1 |0 |1 | + 5138 |33|5138| |0 |1 |5-day Max Temp Anom |5-day Max T Anom |1 |0 |1 | + 5139 |33|5139| |0 |1 |5-day Min Temp Anom |5-day Min T Anom |1 |0 |1 | + 5140 |33|5140,5141| |0 |1 |Max/Min Temperatures |Max/Min Temps |1 |0 |1 | + 5141 |33|5141| |0 |1 |Min Temperatures |Min Temps |1 |0 |1 | + 5142 |33|5142| |0 |1 |Freezing Level Plot |Fzlvl Plot |1 |0 |1 | + 5145 |33|5145| |0 |1 |Freezing Level Analysis |Fzlvl Analysis |1 |0 |1 | + 5146 |33|5146| |0 |1 |Redbook graphic PXVA01 |PXVA01 |1 |0 |1 | + 5147 |33|5147| |0 |1 |Lifted-K Index Plot |LI/KI Plot |1 |0 |1 | + 5154 |33|5154| |0 |1 |Sfc Geostrophic Wind |Sfc Geo Wind |1 |0 |1 | + 5155 |33|5155| |0 |1 |Sfc Geo Relative Vort |Sfc Geo Vort |1 |0 |1 | + 5159 |33|5159,5161,5162,5340,5341| |0 |1 |Max/Min/PoP Prog |Max/Min/PoP Prog |1 |0 |1 | + 5160 |33|5160| |0 |1 |Redbook graphic PYWK62 |PYWK62 |1 |0 |1 | + 5163 |33|5163| |0 |1 |Redbook graphic PZKY51 |PZKY51 |1 |0 |1 | + 5164 |33|5164,5372| |0|1 |6-10, 8-14 Day Precip Anom|6-10,8-14 pcp anom|1 |0 |1 | + 5169 |33|5169,5373| |0|1 |6-10, 8-14 Day Temp Anom |6-10,8-14 tmp anom|1 |0 |1 | + 5172 |33|5172| |0 |1 |6-10 Day Mean 500 Hgt |6-10 500 hgt |1 |0 |1 | + 5245 |33|5245,5246| |0 |1 |WATL wind/wave |WATL wind/wave |1 |0 |1 | + 5248 |33|5248,5249| |0 |1 |EPAC wind/wave |EPAC wind/wave |1 |0 |1 | +# 5289 |33|5289| |0|1 |3-10 Day Threat Assess Precip |Precip Threat |1 |0 |1 | +# 5290 |33|5290| |0|1 |3-10 Day Threat Assess Temp/Wind |Temp/Wind Threat |1 |0 |1 | +# 5291 |33|5291| |0|1 |3-10 Day Threat Assess Soil/Wildfire|Soil/Wildfire Threat|1 |0 |1 | + 5432 |33|5432| |0|1 |3-7 Day Precip Hazards |Precip Hazards |1 |0 |1 | + 5433 |33|5433| |0|1 |8-14 Day Precip Hazards |Precip Hazards |1 |0 |1 | + 5434 |33|5434| |0|1 |3-7 Day Temp/Wind Hazards |Temp/Wind Hazards |1 |0 |1 | + 5435 |33|5435| |0|1 |8-14 Day Temp/Wind Hazards |Temp/Wind Hazards |1 |0 |1 | + 5436 |33|5436| |0|1 |3-7 Day Soil/Wildfire Hazards |Soil/Wildfire Hazards |1 |0 |1 | + 5437 |33|5437| |0|1 |8-14 Day Soil/Wildfire Hazards |Soil/Wildfire Hazards |1 |0 |1 | + 5381 |33|5381| |0|1 |Day 3 Heat Index Probabilities |Day 3 Heat Index % |1 |0 |1 | + 5386 |33|5386| |0|1 |Day 4 Heat Index Probabilities |Day 4 Heat Index % |1 |0 |1 | + 5387 |33|5387| |0|1 |Day 5 Heat Index Probabilities |Day 5 Heat Index % |1 |0 |1 | + 5382 |33|5382| |0|1 |Day 6 Heat Index Probabilities |Day 6 Heat Index % |1 |0 |1 | + 5388 |33|5388| |0|1 |Day 7 Heat Index Probabilities |Day 7 Heat Index % |1 |0 |1 | + 5298 |33|5298| |0|1 |6-10 Day Heat Index >=85F |6-10Day Temp 85F |1 |0 |1 | + 5299 |33|5299| |0|1 |6-10 Day Heat Index >=90F |6-10Day Temp 90F |1 |0 |1 | + 5300 |33|5300| |0|1 |6-10 Day Heat Index >=95F |6-10Day Temp 95F |1 |0 |1 | + 5301 |33|5301| |0|1 |8-14 Day Heat Index >=85F |8-14Day Temp 85F |1 |0 |1 | + 5302 |33|5302| |0|1 |8-14 Day Heat Index >=90F |8-14Day Temp 90F |1 |0 |1 | + 5303 |33|5303| |0|1 |8-14 Day Heat Index >=95F |8-14Day Temp 95F |1 |0 |1 | + 5383 |33|5383| |0|1 |6-10 Day Maximum Heat Index Outlook|6-10Day Max HI Outlk |1 |0 |1 | + 5247 |33|5247| |0|1 |8-14 Day Maximum Heat Index Outlook|8-14Day Max HI Outlk |1 |0 |1 | + 5312 |33|5312| |0|1 |Tropical Surface Analysis |Trop Sfc Anal |1 |0 |1 | + 5313 |33|5313| |0|1 |Atl 850MB Strmlines/Wind Anal |Atl 850MB |1 |0 |1 | + 5314 |33|5314| |0|1 |Atl 200MB Strmlines/Wind Anal |Atl 200MB |1 |0 |1 | + 5315 |33|5315| |0|1 |Atl Deep Layer Mean Circulation |Atl Deep Layer |1 |0 |1 | + 5316 |33|5316| |0|1 |Atl 850-200MB Winds/Shear Analy |Atl 850-200MB |1 |0 |1 | + 5317 |33|5317| |0|1 |Eastern Pacific Winds/Seas |E Pac Winds/Seas |1 |0 |1 | + 5318 |33|5318| |0|1 |Pac Deep Layer Mean Circulation |Pac Deep Layer |1 |0 |1 | + 5319 |33|5319| |0|1 |Pac 850-200MB Winds/Shear Analy |Pac 850-200MB |1 |0 |1 | + 5320 |33|5320,5321,5322,5323| |0|1 |Caribbean Wind/Seas|Carib Wind/Seas |1 |0 |1 | + 5324 |33|5324| |0|1 |N Atlantic Surface Anal |N Atl Sfc Anal |1 |0 |1 | + 5325 |33|5325,5326| |0|1 |N Atlantic Sig Wave/Winds |N Atl Sig Wave/Winds |1 |0 |1 | + 5327 |33|5327| |0|1 |W Atlantic Fronts/Press Fcst |W Atl Fronts/Press |1 |0 |1 | + 5328 |33|5328,5329| |0|1 |N Atl Fronts/Press/Winds |N Atl Frnt/Pres/Winds|1 |0 |1 | + 5330 |33|5330| |0|1 |N Pacific Surface Anal |N Pac Sfc Anal |1 |0 |1 | + 5331 |33|5331,5332| |0|1 |N Pacific Sig Wave/Winds |N Pac Sig Wave/Winds |1 |0 |1 | + 5333 |33|5333| |0|1 |E Pacific Fronts/Press Fcst |E Pac Fronts/Press |1 |0 |1 | + 5334 |33|5334,5335| |0|1 |N Pac Fronts/Press/Winds |N Pac Frnt/Pres/Winds|1 |0 |1 | + 5336 |33|5336| |0|1 |24 Hour Marine Dense Fog |24h Marine Dense Fog |1 |0 |1 | + 5337 |33|5337| |0|1 |24 Hour Marine Freezing Spray |24h Marine Frz Spray |1 |0 |1 | + 5342 |33|5342| |0|1 |30 Day Precip Anomaly |30 Day Precip Anom |1 |0 |1 | + 5343 |33|5343,5344,5345,5346,5347,5348,5349,5350,5351,5352,5353,5354,5355| |0|1 |90 Day Seasonal Precip Outlook|90 Day Season Precip Outlk|1 |0 |1 | + 5404 |33|5404,5405,5406,5407,5408,5409,5410,5411,5412,5413,5414,5415,5416| |0|1 |50% POE Precip Outlook|50% POE Precip Outlk|1 |0 |1 | + 5356 |33|5356| |0|1 |30 Day Temp Anomaly |30 Day Temp Anom |1 |0 |1 | + 5357 |33|5357,5358,5359,5360,5361,5362,5363,5364,5365,5366,5367,5368,5369| |0|1 |90 Day Seasonal Temp Outlook|90 Day Season Temp Outlk|1 |0 |1 | + 5417 |33|5417,5418,5419,5420,5421,5422,5423,5424,5425,5426,5427,5428,5429| |0|1 |50% POE Temp Outlook|50% POE Temp Outlk|1 |0 |1 | + 5370 |33|5370| |0|1 |SPC Fire Weather Outlook - Day 1 |Day 1 Fire Wx Otlk |1 |0 |1 | + 5371 |33|5371| |0|1 |SPC Fire Weather Outlook - Day 2 |Day 2 Fire Wx Otlk |1 |0 |1 | + 5431 |33|5431| |0|1 |SPC Fire Weather Outlook - Day 3-8|Day 3-8 Fire Wx Outlk|1 |0 |1 | + 5374 |33|5374| |0|1 |8-14 day Mean 500 Height |8-14 day Mean 500 ht |1 |0 |1 | + 5375 |33|5375| |0|1 |8-14 day Mean 500 Height Anom |8-14 day 500 ht Anom |1 |0 |1 | + 5376 |33|5376| |0|1 |Day 1 Hail Outlook |Day 1 Hail Outlook |1 |0 |1 | + 5377 |33|5377| |0|1 |Day 1 Convective wind outlook |Day 1 Wind Outlook |1 |0 |1 | + 5378 |33|5378| |0|1 |Day 1 Tornado outlook |Day 1 Tornado outlook|1 |0 |1 | + 5379 |33|5379| |0|1 |Day 2 Combined Severe Outlook |Day 2 Combined severe|1 |0 |1 | + 5380 |33|5380| |0|1 |6-10 day 500 Hgt Anomaly |6-10 day 500 Hgt Anom|1 |0 |1 | + 5384 |33|5384| |0|1 |Day 3 Combined Severe Outlook |Day 3 Combined severe|1 |0 |1 | + 5385 |33|5385| |0|1 |Day 3 Convective Outlook |Day 3 Convect Outlook|1 |0 |1 | +# 5430 |33|5430| |0|1 |Day 4-8 Composite Severe Outlook |Day 4-8 Comp Severe |1 |0 |1 | + 5389 |33|5389| |0|1 |Sig River Flood Outlook |Sig Riv Flood Outlook|1 |0 |1 | + 5390 |33|5390| |0|1 |Active Mesoscale Disc Summary |Active Meso Disc Sum |1 |0 |1 | + 5438 |33|5438| |0|1 |Mesoscale Precipitation Discussion|Mesoscale Precip Disc|1 |0 |1 | + 5391 |33|5391 | |0 |1 |Day 1 Prob 4+" Snow |4+" snow prob |1 |0 |1 | + 5392 |33|5392 | |0 |1 |Day 1 Prob 8+" Snow |8+" snow prob |1 |0 |1 | + 5393 |33|5393 | |0 |1 |Day 1 Prob 12+" Snow |12+" snow prob|1 |0 |1 | + 5394 |33|5394 | |0 |1 |Day 1 Prob .25+" Ice |.25+" ice prob|1 |0 |1 | + 5395 |33|5395 | |0 |1 |Day 2 Prob 4+" Snow |4+" snow prob |1 |0 |1 | + 5396 |33|5396 | |0 |1 |Day 2 Prob 8+" Snow |8+" snow prob |1 |0 |1 | + 5397 |33|5397 | |0 |1 |Day 2 Prob 12+" Snow |12+" snow prob|1 |0 |1 | + 5398 |33|5398 | |0 |1 |Day 2 Prob .25+" Ice |.25+" ice |1 |0 |1 | + 5399 |33|5399 | |0 |1 |Day 3 Prob 4+" Snow |4+" snow prob |1 |0 |1 | + 5400 |33|5400 | |0 |1 |Day 3 Prob 8+" Snow |8+" snow prob |1 |0 |1 | + 5401 |33|5401 | |0 |1 |Day 3 Prob 12+" Snow |12+" snow prob |1 |0 |1 | + 5402 |33|5402 | |0 |1 |Day 3 Prob .25+" Ice |.25+" ice prob |1 |0 |1 | + 5403 |33|5403 | |0 |1 |3-Day Sig Winter Low Tracks |Low tracks |1 |0 |1 | + 5440 |33|5440 | |0 |1 |Day 4 Severe Outlook |Day 4 Convect Outlook|1 |0 |1 | + 5441 |33|5441 | |0 |1 |Day 5 Severe Outlook |Day 5 Convect Outlook|1 |0 |1 | + 5442 |33|5442 | |0 |1 |Day 6 Severe Outlook |Day 6 Convect Outlook|1 |0 |1 | + 5443 |33|5443 | |0 |1 |Day 7 Severe Outlook |Day 7 Convect Outlook|1 |0 |1 | + 5444 |33|5444 | |0 |1 |Day 8 Severe Outlook |Day 8 Convect Outlook|1 |0 |1 | diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookHPCMenus.txt b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookHPCMenus.txt new file mode 100644 index 0000000000..18454b351d --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookHPCMenus.txt @@ -0,0 +1,62 @@ +submenu: "Precipitation" + productButton: 5048 # PEIC61 Instantaneous Precip + productButton: 5046 # PEI745 Day 1 Excessive Rainfall + productButton: 3313821600 # 1-3 Day Excessive Rainfall + productButton: 5047 # PEIC43 Precip Fcst--6hr accum + productButton: 5050 # PEIE41,PEIK98 Precip Fcst--24hr accum + productButton: 5389 # PENJ88 Significant River Flood Outlook + productButton: 5438 # PENA01 Mesoscale Precip Discussion + separator + submenu: "Day 1-3 Prob 4+ Inches Snow" + productButton: 5391 # PSBB04 Day 1 Prob 4+ Inches + productButton: 5395 # PSBC04 Day 2 Prob 4+ Inches + productButton: 5399 # PSBD04 Day 3 Prob 4+ Inches + endSubmenu + submenu: "Day 1-3 Prob 8+ Inches Snow" + productButton: 5392 # PSBB08 Day 1 Prob 8+" + productButton: 5396 # PSBC08 Day 2 Prob 8+" + productButton: 5400 # PSBD08 Day 3 Prob 8+" + endSubmenu + submenu: "Day 1-3 Prob 12+ Inches Snow" + productButton: 5393 # PSBB12 Day 1 Prob 12+" + productButton: 5397 # PSBC12 Day 2 Prob 12+" + productButton: 5401 # PSBD12 Day 3 Prob 12+" + endSubmenu + submenu: "Day 1-3 Prob .25+ Inches Ice" + productButton: 5394 # PSBB25 Day 1 Prob .25+" + productButton: 5398 # PSBC25 Day 2 Prob .25+" + productButton: 5402 # PSBD25 Day 3 Prob .25+" + endSubmenu + separator + productButton: 5055 # 5 Day Total Precip + productButton: 5439 # 7 Day Total Precip + productButton: 5164 # 6-10,8-14 Day Precip Anom + productButton: 5342 # PEIV98 30 Day Precip Anom + productButton: 5343 # PEIW* 90 Day Seasonal Precip Outlook + productButton: 5404 # PENV* 50% POE Precip Outlook + separator + productButton: 3313819760 # 1-3 Day Total Precip + productButton: 3313821000 # 4-5 Day Total Precip + productButton: 3313821592 # 1-5 Day Total Precip +endSubmenu + +submenu: "Temps & Weather" + productButton: 5138 # PTIO52 5dy max temp anom + productButton: 5139 # PTIO53 5dy min temp anom + productButton: 5159 # PYWK43 3-7 day max/min/PoP + productButton: 5381 # PTNK98 Day 3 heat index + productButton: 5386 # PTNM98 Day 4 heat index + productButton: 5387 # PTNO98 Day 5 heat index + productButton: 5382 # PTNQ98 Day 6 heat index + productButton: 5388 # PTNS98 Day 7 heat index + productButton: 5169 # PTIY51,PTTU98 6-10,8-14 day temp anom + productButton: 5356 # PTIV98 30 day temp anom + productButton: 5357 # PTIW* 90 Day Seasonal Temp Outlook + productButton: 5417 # PTNV* 50% POE Temp Outlook + separator + productButton: 5115 # PPVA01 MSL Pressure Analysis + productButton: 5204 # PYIA01 Frontal Analysis + productButton: 5111 # PPIC01 Fronts/Pressure + productButton: 5108 # PPIC01 3-7 day Fronts/Pressure + productButton: 5403 # PSAO72 3-Day Low Tracks +endSubmenu diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookHazardMenus.txt b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookHazardMenus.txt new file mode 100644 index 0000000000..afa9319992 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookHazardMenus.txt @@ -0,0 +1,25 @@ +# +submenu: "SPC Convective Outlooks" + productButton: 5069 # PGWE46 Day 1 Convective Outlook + productButton: 5072 # PGWI47 Day 2 Convective Outlook + productButton: 5385 # PGWK48 Day 3 Convective Outlook + productButton: 5067 # PGWB44 Thunderstorm Prob + productButton: 5068 # PGWB45 Severe Tstm Prob + productButton: 5376 # PENE00 Day 1 Hail Outlook + productButton: 5377 # PWNE00 Day 1 Convective Wind Outlook + productButton: 5378 # PGNE00 Day 1 Tornado Outlook + productButton: 5379 # PGNI00 Day 2 Combined Severe Outlook + productButton: 5384 # PZNK00 Day 3 Combined Severe Outlook +# productButton: 5430 # PGNM98 Day 4-8 Composite Severe Outlook + productButton: 5440 # PGNW49 Day 4 Severe Outlook + productButton: 5441 # PGNW50 Day 5 Severe Outlook + productButton: 5442 # PGNW51 Day 6 Severe Outlook + productButton: 5443 # PGNW52 Day 7 Severe Outlook + productButton: 5444 # PGNW53 Day 8 Severe Outlook + productButton: 5390 # PGNA00 Active Mesoscale Disc Summary +endSubmenu +submenu: "Fire Weather" + productButton: 5370 # PMWE98 Day 1 outlook + productButton: 5371 # PMWI98 Day 2 outlook + productButton: 5431 # PGNO98 Day 3-8 outlook +endSubmenu diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookMarineMenus.txt b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookMarineMenus.txt new file mode 100644 index 0000000000..5d1d99b84f --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookMarineMenus.txt @@ -0,0 +1,27 @@ +submenu: "Marine Guidance" + productButton: 5312 # PYNA98 Tropical Sfc Analysis + productButton: 5336 # PGNE88 Dense Fog Fcst + productButton: 5337 # PGNE98 Freezing Spray Fcst + title: "West Atlantic" + productButton: 5313 # PWAA85 Atl 850MB Wind Anal + productButton: 5314 # PWAA20 Atl 200MB Wind Anal + productButton: 5315 # PWAA00 Atl Deep Layer Mean Cir + productButton: 5316 # PWAA65 Atl Winds/Shear Anal + productButton: 5245 # PWIA98,PWIE98 Wind/Wave + productButton: 5327 # PPAE89 Fronts/Press Fcst + productButton: 5320 # PWE* Caribbean Wind/Seas Fcst + title: "North Atlantic" + productButton: 5324 # PYAA89 Surface Analysis + productButton: 5328 # PPAI89,PPAM89 Fronts/Press/Winds Fcst + productButton: 5325 # PJAA88,PJAI88 Sig/Wind/Wave + title: "East Pacific" + productButton: 5317 # PWBA88 Eastern Pac Wind/Seas + productButton: 5318 # PWDA00 Pac Deep Layer Mean Cir + productButton: 5319 # PWDA65 Pac Winds/Shear Anal + productButton: 5248 # PWIA97,PWIE97 Wind/Wave + productButton: 5333 # PPBE89 Fronts/Press Fcst + title: "North Pacific" + productButton: 5330 # PYBA89 Surface Analysis + productButton: 5334 # PPBI89,PPBM89 Fronts/Press/Winds Fcst + productButton: 5331 # PJBA88,PJBI88 Sig/Wind/Wave +endSubmenu diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookNCOMenus.txt b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookNCOMenus.txt new file mode 100644 index 0000000000..ed9c342551 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookNCOMenus.txt @@ -0,0 +1,39 @@ +submenu: "Precip & Stability" + productButton: 5056 # PEWA31 Daily Precipitation + productButton: 5057 # PEWA32 Snow Cover Plot + + submenu: "Snow images" + title: "NOHRSC" + productButton: 25500 # Snow Cover + productButton: 25501 # Snow Cover elev + productButton: 25502 # Snow Water Equiv + productButton: 25503 # Snow Water % normal + endSubmenu + + productButton: 5013 # PAWO82 Radar Summary + productButton: 5014 # PAWO83 Radar Legends + productButton: 5058 # PEWA33 Precip H20 Plot + productButton: 5059 # PEWA34 Precip H20 Analysis + productButton: 5134 # PRWA51 Surface-500mb RH Plot + productButton: 5147 # PXWA50 Lifted-K Index Plot +endSubmenu + +submenu: "Temps & Weather" + productButton: 5140 # PTWA31 Observed Max/Min Temps + separator + productButton: 5142 # PTWA94 LOA freezing level plot + productButton: 5145 # PTWA93 LOF freezing level analysis + productButton: 5136 # PTIC94 Freezing Level/Turb Fcst + separator + productButton: 5064 # PGWA31 Wx Depiction Plot + productButton: 5065 # PGWA32 Wx Depiction Analysis + productButton: 5062 # PGIC42 Wx Depiction Fcst + separator + productButton: 5154 # PYWA31 Sfc Geostrophic Wind + productButton: 5155 # PYWA32 Sfc Geo Relative Vort +endSubmenu + +submenu: "National Centers models" + productButton: 5118 # PPZ*50 UKMO MSL Pressure +endSubmenu + diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookProductButtons.txt b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookProductButtons.txt new file mode 100644 index 0000000000..127e413ab1 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookProductButtons.txt @@ -0,0 +1,138 @@ + 5013 | >700, 5013 |Radar Summary |PAWO82 | 0 + 5014 | >700, 5014 |Radar Legends |PAWO82 | 0 + 5015 | >700, 5015 |Redbook graphic PAW883 |PAW883* | 0 + 5021 | >700, 5021 |Redbook graphic PDKI59 |PDKI59* | 0 + 5046 | >700, 5046 |Day 1 Excessive Rainfall |PEI745 | 0 + 5047 | >700, 5047 |Precip Accum - 6hr |PEIC43,PEID44,PEB* | 0 + 5048 | >700, 5048 |Instantaneous Precip |PEIC61,PEIE62 | 0 + 5050 | >700, 5050 |Precip Accum - 24hr |PEIE41,PEII42,PEIK98 | 0 + 5055 | >700, 5055 |1-5 day Total Precip |PEIO46 | 0 + 5056 | >700, 5056 |Daily Precipitation |PEWA31 | 0 + 5057 | >700, 5057 |Snow Cover Plot |PEWA32 | 0 + 5058 | >700, 5058 |Precip H2O Plot |PEWA33 | 0 + 5059 | >700, 5059 |Precip H2O Anal |PEWA34 | 0 + 5062 | >700, 5062 |Wx Depiction Fcst |PGIC42 | 0 + 5063 | >700, 5063 |24h Wx Depiction |PGIE43 | 0 + 5064 | >700, 5064 |Wx Depiction plot |PGWA31 | 0 + 5065 | >700, 5065 |Wx Depiction analysis |PGWA32 | 0 + 5066 | >700, 5066 |Wx Depiction plot |PGWA39* | 0 + 5067 | >700, 5067 |Thunderstorm Prob |PGWB44 | 0 + 5068 | >700, 5068 |Severe Thunderstorm Prob |PGWB45 | 0 + 5069 | >700, 5069 |Day 1 Convective Outlook |PGWE46 | 0 + 5072 | >700, 5072 |Day 2 Convective Outlook |PGWI47 | 0 + 5101 | >700, 5101 |UKMO 500 hgt |PHZ[MOQ]50 | 0 + 5102 | >700, 5102 |Redbook graphic PLQI51 |PLQI51* | 0 + 5104 | >700, 5104 |Redbook graphic PNWA68 |PNWA68* | 0 + 5107 | >700, 5107 |Redbook graphic POWA31 |POWA31* | 0 + 5108 | >1000, 5108 |Day 3-7 Fronts/Press |PPH[KMO]01,PPT[GR]98 | 0 + 5111 | >700, 5111 |12-48 hr Fronts/Press |PPI[CEGI]01 | 0 + 5115 | >700, 5115 |MSL Pressure Analysis |PPVA01 | 0 + 5204 | >700, 5204 |Surface Fronts Analysis |PYIA01 | 0 + 5244 | >2500, 5244 |NA MSL Pres Anal |PYAA98 | 0 + 5243 | >2500, 5243 |NA Surface Fronts |PYBA98 | 0 + 5118 | >700, 5118 |UKMO MSLP |PPZ[MOQ]50 | 0 + 5134 | >700, 5134 |Sfc-500 RH plot |PRWA51 | 0 + 5136 | >700, 5136 |Frzg Lvl/Turbulence Fcst |PTIC94 | 0 + 5137 | >700, 5137 |24h Frzg Lvl Fcst |PTIE94 | 0 + 5138 | >700, 5138 |1-5 Day Max Temp Anomaly |PTIO52 | 0 + 5139 | >700, 5139 |1-5 Day Min Temp Anomaly |PTIO53 | 0 + 5140 | >700, 5140 |Observed Max/Min Temps |PTWA31 | 0 + 5141 | >700, 5141 |Min Temperatures |PTWA32 | 0 + 5142 | >700, 5142 |Frzg Lvl Plot |PTWA94 | 0 + 5145 | >700, 5145 |Frzg Lvl Analysis |PTWA93 | 0 + 5146 | >700, 5146 |Redbook graphic PXVA01 |PXVA01* | 0 + 5147 | >700, 5147 |Lifted-K Index Plot |PXWA50 | 0 + 5154 | >700, 5154 |Sfc Geo Wind Plot |PYWA31 | 0 + 5155 | >700, 5155 |Sfc Geo Relative Vort |PYWA32 | 0 + 5159 | >700, 5159 |Day 3-7 Max/Min/PoP |PYWK43,PYWM44,PYWO45,PYWQ46,PYWS98 | 0 + 5160 | >700, 5160 |Redbook graphic PYWK62 |PYWK62* | 0 + 5163 | >700, 5163 |Redbook graphic PZKY51 |PZKY51* | 0 + 5164 | >700, 5164 |6-10, 8-14 day Precip Anom |PEIY47,PETT00 | 0 + 5169 | >700, 5169 |6-10, 8-14 day Temp Anomaly |PTIY51 | 0 + 5172 | >700, 5172 |6-10 day mean 500 Hgt |PHBV50 | 0 + 5245 | >1000, 5245 |WATL wind/wave |PWAA01*,PPAE89 | 0 + 5248 | >1000, 5248 |EPAC wind/wave |PWBA01*,PPBE89 | 0 +# 5289 | >700, 5289 |Precipitation Fcst |PEIY50 | 0 +# 5290 | >700, 5290 |Temperature/Wind Fcst |PTIY98 | 0 +# 5291 | >700, 5291 |Soil/Wildfire Fcst |PYIY88 | 0 + 5298 | >700, 5298 |>= 85F for 3 days of 5 |PTAS90 | 0 + 5299 | >700, 5299 |>= 90F for 2 days of 5 |PTAS90 | 0 + 5300 | >700, 5300 |>= 95F for 1 day of 5 |PTAS90 | 0 + 5301 | >700, 5301 |>= 85F for 3 days of 7 |PTAT90 | 0 + 5302 | >700, 5302 |>= 90F for 2 days of 7 |PTAT95 | 0 + 5303 | >700, 5303 |>= 95F for 1 day of 7 |PTAT00 | 0 + 5312 | >700, 5312 |Tropical Surface Analysis |PYNA98 | 0 + 5313 | >700, 5313 |Atl 850mb Strmlines/Winds Analysis |PWAA85 | 0 + 5314 | >700, 5314 |Atl 200mb Strmlines/Winds Analysis |PWAA20 | 0 + 5315 | >700, 5315 |Atl Deep Layer Mean Circ 1000-100mb|PWAA00 | 0 + 5316 | >700, 5316 |Atl 850-200mb Winds/Shear Analysis |PWAA65 | 0 + 5317 | >700, 5317 |E Pacific Wind/Seas Analysis |PWBA88 | 0 + 5318 | >700, 5318 |Pac Deep Layer Mean Circ 1000-100mb|PWDA00 | 0 + 5319 | >700, 5319 |Pac 850-200mb Winds/Shear Analysis |PWDA65 | 0 + 5320 | >700, 5320 |Caribbean Wind/Seas Fcst |PWE* | 0 + 5324 | >700, 5324 |Surface Analysis |PYAA89 | 0 + 5325 | >700, 5325 |Sig Wave/Wind |PJAA88,PJAI88 | 0 + 5327 | >700, 5327 |Fronts/Press Fcst |PPAE89 | 0 + 5328 | >700, 5328 |Fronts/Press/Winds Fcst |PPAI88,PPAM89 | 0 + 5330 | >700, 5330 |Surface Analysis |PYBA89 | 0 + 5331 | >700, 5331 |Sig Wave/Wind |PJBA88,PJBI88 | 0 + 5333 | >700, 5333 |Fronts/Press Fcst |PPBE89 | 0 + 5334 | >700, 5334 |Fronts/Press/Winds Fcst |PPBI89,PPBM89 | 0 + 5336 | >700, 5336 |24 Hr Dense Fog Fcst |PGNE88 | 0 + 5337 | >700, 5337 |24 Hr Freezing Spray Fcst |PGNE98 | 0 + 5338 | >700, 5338 |Day 6-7 Frontal Pos Fcst |PPTG98,PPTR98 | 0 + 5340 | >700, 5340 |Day 6-7 Temp and POP Fcst |PYWQ46,PYWS98 | 0 + 5342 | >700, 5342 |30 Day Precip Anomaly |PEIV98 | 0 + 5343 | >700, 5343 |90 Day Seasonal Precip Outlook|PEIW* | 0 + 5356 | >700, 5356 |30 Day Temp Anomaly |PTIV98 | 0 + 5357 | >700, 5357 |90 Day Seasonal Temp Outlook|PTIW* | 0 + 5370 | >700, 5370 |Fire Wx Outlook - Day 1 |PMWE98 | 0 + 5371 | >700, 5371 |Fire Wx Outlook - Day 2 |PMWI98 | 0 + 5374 | >700, 5374 |8-14 day Mean 500 Hgt |PHTT50 | 0 + 5375 | >700, 5375 |8-14 day 500 Hgt Anom |PHTT51 | 0 + 5376 | >700, 5376 |Day 1 Hail Outlook |PENE00 | 0 + 5377 | >700, 5377 |Day 1 Convective Wind Outlook |PWNE00 | 0 + 5378 | >700, 5378 |Day 1 Tornado Outlook |PGNE00 | 0 + 5379 | >700, 5379 |Day 2 Combined Severe Outlook |PGNI00 | 0 + 5380 | >700, 5380 |6-10 day 500 Hgt Anomaly |PHNT50 | 0 + 5381 | >700, 5381 |Day 3 Heat Index Probabilities|PTNK98 | 0 + 5382 | >700, 5382 |Day 6 Heat Index Probabilities|PTNQ98 | 0 + 5386 | >700, 5386 |Day 4 Heat Index Probabilities|PTNM98 | 0 + 5387 | >700, 5387 |Day 5 Heat Index Probabilities|PTNO98 | 0 + 5388 | >700, 5388 |Day 7 Heat Index Probabilities|PTNS98 | 0 + 5383 | >700, 5383 |6-10 Day Max Heat Index Outlook|PTNR98 | 0 + 5247 | >700, 5247 |8-14 Day Max Heat Index Outlook|PTNT98 | 0 + 5384 | >700, 5384 |Day 3 Combined Severe Outlook|PZNK00 | 0 + 5385 | >700, 5385 |Day 3 Convective Outlook |PGWK48 | 0 + 5389 | >700, 5389 |Sig River Flood Outlook |PENJ88 | 0 + 5390 | >700, 5390 |Active Mesoscale Disc Sum |PGNA00 | 0 + 5391 | >700, 5391 |Day 1 Prob 4+" Snow |PSBB04 | 0 + 5392 | >700, 5392 |Day 1 Prob 8+" Snow |PSBB08 | 0 + 5393 | >700, 5393 |Day 1 Prob 12+" Snow |PSBB12 | 0 + 5394 | >700, 5394 |Day 1 Prob .25+" Ice |PSBB25 | 0 + 5395 | >700, 5395 |Day 2 Prob 4+" Snow |PSBC04 | 0 + 5396 | >700, 5396 |Day 2 Prob 8+" Snow |PSBC08 | 0 + 5397 | >700, 5397 |Day 2 Prob 12+" Snow |PSBD12 | 0 + 5398 | >700, 5398 |Day 2 Prob .25+" Ice |PSBC25 | 0 + 5399 | >700, 5399 |Day 3 Prob 4+" Snow |PSBD04 | 0 + 5400 | >700, 5400 |Day 3 Prob 8+" Snow |PSBD08 | 0 + 5401 | >700, 5401 |Day 3 Prob 12+" Snow |PSBD12 | 0 + 5402 | >700, 5402 |Day 3 Prob .25+" Ice |PSBD25 | 0 + 5403 | >700, 5403 |3-Day Sig Winter Low Tracks |PSAO72 | 0 + 5404 | >700, 5404 |0.5 Mo (15-105 day) 50% POE Precip Outlook|PENV* | 0 + 5417 | >700, 5417 |0.5 Mo (15-105 day) 50% POE Temp Outlook |PTNV* | 0 +# 5430 | >700, 5430 |Day 4-8 Composite Severe Outlook|PGNM98 | 0 + 5431 | >700, 5431 |Fire Wx Outlook - Day 3-8 |PGNO98 | 0 + 5432 | >700, 5432 |3-7 day Precipitation Fcst |PEIY97 | 0 + 5433 | >700, 5433 |8-14 day Precipitation Fcst |PEIY96 | 0 + 5434 | >700, 5434 |3-7 Temperature/Wind Fcst |PTIY97 | 0 + 5435 | >700, 5435 |8-14 Temperature/Wind Fcst |PTIY96 | 0 + 5436 | >700, 5436 |3-7 day Soil/Wildfire Fcst |PYIY97 | 0 + 5437 | >700, 5437 |8-14 day Soil/Wildfire Fcst |PYIY96 | 0 + 5438 | >700, 5438 |Mesoscale Precip Discussion |PENA01 | 0 + 5439 | >700, 5439 |1-7 Day Total Precip |PEIS46 | 0 + 5440 | >700, 5440 |Severe Weather Outlook - Day 4 |PGNW49 | 0 + 5441 | >700, 5441 |Severe Weather Outlook - Day 5 |PGNW50 | 0 + 5442 | >700, 5442 |Severe Weather Outlook - Day 6 |PGNW51 | 0 + 5443 | >700, 5443 |Severe Weather Outlook - Day 7 |PGNW52 | 0 + 5444 | >700, 5444 |Severe Weather Outlook - Day 8 |PGNW53 | 0 diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookUpperAirMenus.txt b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookUpperAirMenus.txt new file mode 100644 index 0000000000..05d3f0a39d --- /dev/null +++ b/edexOsgi/com.raytheon.uf.edex.plugin.redbook/utility/common_static/base/ndm/redbookUpperAirMenus.txt @@ -0,0 +1,10 @@ +submenu: "Model Graphics" + productButton: 5101 # PHZ*50 UKMO 500 Height +endSubmenu +submenu: "CPC Charts" + productButton: 5172 # PHBV50 6-10 day mean 500 Hgt + productButton: 5374 # PHTT50 8-14 day mean 500 ht + productButton: 5380 # PHNT50 6-10 day 500 ht anom + productButton: 5375 # PHTT51 8-14 day 500 ht anom +endSubmenu + diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/util/xpath/RegistryXPathProcessor.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/util/xpath/RegistryXPathProcessor.java index 107503b7cb..e660703e76 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/util/xpath/RegistryXPathProcessor.java +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/util/xpath/RegistryXPathProcessor.java @@ -65,6 +65,7 @@ import com.raytheon.uf.edex.registry.ebxml.util.EbxmlExceptionUtil; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 8/8/2013 1692 bphillip Initial implementation + * 06/02/2015 4499 dhladky Security comment on xpath requests. * * * @author bphillip @@ -154,6 +155,7 @@ public class RegistryXPathProcessor { Node newNode = toDom(addNode).getDocumentElement(); Node importedNode = domDocument.importNode(newNode, true); currentNode.appendChild(importedNode); + } // Converts the updated object back from DOM return fromDom(domDocument); @@ -190,6 +192,7 @@ public class RegistryXPathProcessor { if (currentNode.getNodeType() == Node.ATTRIBUTE_NODE) { checkForProhibitedUpdates(currentNode); currentNode.setNodeValue(String.valueOf(updateNode)); + } else { currentNode.getParentNode().replaceChild( domDocument.importNode(toDom(updateNode) @@ -237,6 +240,12 @@ public class RegistryXPathProcessor { return fromDom(domDocument); } + /** + * Check the security blacklist of nodes not allowed for update. + * + * @param node + * @throws MsgRegistryException + */ private void checkForProhibitedUpdates(Node node) throws MsgRegistryException { String nodeName = node.getNodeName(); @@ -250,7 +259,7 @@ public class RegistryXPathProcessor { } /** - * Method used to evaulate XPATH expressions on a DOM Document + * Method used to evaluate XPATH expressions on a DOM Document * * @param document * The DOM document to apply the xpath expression to @@ -268,10 +277,22 @@ public class RegistryXPathProcessor { * RegistryObject tag. This is so relative xpath queries will be based * off the RegistryObjectTag not the root */ + NodeList list = null; xpath.reset(); + try { - return (NodeList) xpath.evaluate(xpathExpression, - document.getFirstChild(), XPathConstants.NODESET); + /********************* Security Comment *********************** + * The entire xpathExpression was provided by the user and the + * document is user stored content, not a system level document. + * The authenticated user has full CRUD operation access to the document. + * XPath injection is not considered to be a security risk in this scenario + * since the query was provided in entirety by the user and the query + * is running against their own previously stored document. + */ + Node firstNode = document.getFirstChild(); + list = (NodeList) xpath.evaluate(xpathExpression, firstNode, + XPathConstants.NODESET); + } catch (XPathExpressionException e) { throw EbxmlExceptionUtil.createMsgRegistryException( LifecycleManagerImpl.UPDATE_OBJECTS_ERROR_MSG, @@ -279,6 +300,8 @@ public class RegistryXPathProcessor { new EbxmlRegistryException( "Error evaluating XPath expression", e)); } + + return list; } /** diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/webServiceBeans.xml b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/webServiceBeans.xml index 1fc8b4abc8..8a9577d20c 100644 --- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/webServiceBeans.xml +++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/web/webServiceBeans.xml @@ -1,10 +1,10 @@ - + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/getNotify.py b/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/getNotify.py index 747934d8a3..28d62fa645 100644 --- a/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/getNotify.py +++ b/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/getNotify.py @@ -30,58 +30,59 @@ # ------------ ---------- ----------- -------------------------- # 11/18/10 njensen Initial Creation. # 06/13/13 #2044 randerso Fixed to use correct python -# +# 06/23/2015 #4573 randerso Removed obsolete A1 options, added new options for A2 # # import time, sys import threading +from collections import OrderedDict import dynamicserialize from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.server.notify import * from dynamicserialize.dstypes.com.raytheon.uf.common.activetable import VTECTableChangeNotification -letterList = ['L', 'G', 'D', 'S', 'R', 'C', 'T', 'U', 'B', 'V'] -printoutMap = {'L': 'LOCK', - 'G': 'GRID', - 'D': 'DB', - 'S': 'SAMPLE', - 'R': 'REF', - 'C': 'COLOR', - 'T': 'TEXT', - 'U': 'USER', - 'B': 'PROC', - 'V': 'VTEC' } +printoutMap = OrderedDict([ + ('L', 'LOCK'), + ('G', 'GRID'), + ('D', 'DB'), + ('U', 'USER'), + ('V', 'VTEC'), + ('C', 'COMBO'), + ('S', 'SBU'), + ('H', 'HISTORY'), +]) + classMap = { - LockNotification: 'L', - GridUpdateNotification: 'G', - DBInvChangeNotification: 'D', - UserMessageNotification: 'U', - VTECTableChangeNotification: 'V', - } + LockNotification: 'L', + GridUpdateNotification: 'G', + DBInvChangeNotification: 'D', + UserMessageNotification: 'U', + VTECTableChangeNotification: 'V', + CombinationsFileChangedNotification: 'C', + ServiceBackupJobStatusNotification: 'S', + GridHistoryUpdateNotification: 'H' +} topicList = ['edex.alerts.gfe', 'edex.alerts.vtec'] messageQueueMap = {} -for letter in letterList: +for letter in printoutMap.keys(): messageQueueMap[letter] = [] class GetGfeNotifyTopicListener(threading.Thread): - def __init__(self, topicName, hostname, portNumber, user, L, G, D, S, R, C, T, U, B, V): + def __init__(self, topicName, hostname, portNumber, L, G, D, U, V, C, S, H): self.hostname = hostname self.portNumber = portNumber - self.user = user self.topicName = topicName self.L = L self.G = G self.D = D - self.S = S - self.R = R - self.C = C - self.T = T self.U = U - self.B = B self.V = V + self.C = C + self.S = S + self.H = H self.qs = None threading.Thread.__init__(self) @@ -93,17 +94,21 @@ class GetGfeNotifyTopicListener(threading.Thread): def addMessageToQueue(self, obj, t): if classMap.has_key(t): messageQueueMap[classMap[t]].append(obj) -# else: -# print "Does not yet support type", t + else: + print "Does not yet support type", t def receivedMessage(self, msg): - obj = dynamicserialize.deserialize(msg) - t = type(obj) - if t is list: - for notification in obj: - self.addMessageToQueue(notification, type(notification)) - else: - self.addMessageToQueue(obj, t) + try: + obj = dynamicserialize.deserialize(msg) + t = type(obj) + if t is list: + for notification in obj: + self.addMessageToQueue(notification, type(notification)) + else: + self.addMessageToQueue(obj, t) + except: + import traceback + traceback.print_exc() def stop(self): self.qs.close() @@ -112,45 +117,39 @@ class GetGfeNotifyTopicListener(threading.Thread): def decodeOptions(): import getopt - optionlist, arglist = getopt.getopt(sys.argv[1:], 'h:p:u:lgdsrcbmtv') + optionlist, arglist = getopt.getopt(sys.argv[1:], 'h:p:lgduvcsH') badFormat = False - optionMap = {"hostname": "", "portNumber": 0, "user": None} - for letter in letterList: + optionMap = {"hostname": "", "portNumber": 5672, } + for letter in printoutMap.keys(): optionMap[letter] = False for option in optionlist: - if option[0] == '-l': + if option[0] == '-h': + optionMap["hostname"] = option[1] + elif option[0] == '-p': + optionMap["portNumber"] = int(option[1]) + elif option[0] == '-l': optionMap["L"] = True elif option[0] == '-g': optionMap["G"] = True - elif option[0] == '-v': - optionMap["V"] = True elif option[0] == '-d': optionMap["D"] = True - elif option[0] == '-s': - optionMap["S"] = True - elif option[0] == '-r': - optionMap["R"] = True + elif option[0] == '-u': + optionMap["U"] = True + elif option[0] == '-v': + optionMap["V"] = True elif option[0] == '-c': optionMap["C"] = True - elif option[0] == '-t': - optionMap["T"] = True - elif option[0] == '-b': - optionMap["B"] = True - elif option[0] == '-m': - optionMap["U"] = True - elif option[0] == '-p': - optionMap["portNumber"] = int(option[1]) - elif option[0] == '-h': - optionMap["hostname"] = option[1] - elif option[0] == '-u': - optionMap["user"] = option[1] + elif option[0] == '-s': + optionMap["S"] = True + elif option[0] == '-H': + optionMap["H"] = True else: badFormat = True break - if len(optionMap["hostname"]) == 0 or optionMap["portNumber"] == 0 or badFormat: + if len(optionMap["hostname"]) == 0 == 0 or badFormat: usage() return None @@ -158,21 +157,17 @@ def decodeOptions(): def usage(): s = """ -Usage: getNotify -h -p [-u ] -[-l] [-g] [-d] [-s] [-r] [-c] [-m] [-t] [-b] [-v] - -h hostname : upon which the ifpServer is running - -p portNumber: the RPC port that ifpServer is serving - -u user: user to connect to ifpServer +Usage: getNotify -h [-p ] [-l] [-g] [-d] [-u] [-v] [-c] [-s] [-H] + -h hostname : upon which the JMS broker is running + -p portNumber: the port that JMS broker is using, defaults to 5672 -l: display detailed lock notifications -g: display detailed grid update notifications -d: display detailed database update notifications - -s: display detailed sample notifications - -r: display detailed edit area notifications - -c: display detailed color table notifications - -b: display detailed server process notifications - -m: display detailed user message notifications - -t: display detailed TEXT notifications + -u: display detailed user message notifications -v: display detailed VTEC notifications + -c: display detailed combinations file change notifications + -s: display detailed service backup job status notifications + -H: display detailed grid history update notifications """ print s @@ -182,10 +177,10 @@ def printLoop(options): while True: time.sleep(3) msg = '' - for letter in letterList: + for letter in printoutMap.keys(): msg += letter + '=' + str(len(messageQueueMap[letter])) + "," print msg - for letter in letterList: + for letter in printoutMap.keys(): if options[letter] and len(messageQueueMap[letter]) > 0: msg = printoutMap[letter] + "=[" + "\n" for obj in messageQueueMap[letter]: @@ -195,6 +190,7 @@ def printLoop(options): print msg else: messageQueueMap[letter] = [] + sys.stdout.flush() except KeyboardInterrupt: pass diff --git a/pythonPackages/dynamicserialize/adapters/JobProgressAdapter.py b/pythonPackages/dynamicserialize/adapters/JobProgressAdapter.py new file mode 100644 index 0000000000..7d0a40dccb --- /dev/null +++ b/pythonPackages/dynamicserialize/adapters/JobProgressAdapter.py @@ -0,0 +1,51 @@ +## +# This software was developed and / or modified by Raytheon Company, +# pursuant to Contract DG133W-05-CQ-1067 with the US Government. +# +# U.S. EXPORT CONTROLLED TECHNICAL DATA +# This software product contains export-restricted data whose +# export/transfer/disclosure is restricted by U.S. law. Dissemination +# to non-U.S. persons whether in the United States or abroad requires +# an export license or other authorization. +# +# Contractor Name: Raytheon Company +# Contractor Address: 6825 Pine Street, Suite 340 +# Mail Stop B8 +# Omaha, NE 68106 +# 402.291.0100 +# +# See the AWIPS II Master Rights File ("Master Rights File.pdf") for +# further licensing information. +## + + +# +# Adapter for com.raytheon.uf.common.dataplugin.gfe.svcbu.JobProgress +# +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# 06/22/2015 4573 randerso Initial creation +# +# +# + +from thrift.Thrift import TType +from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.gfe.svcbu import JobProgress + +ClassAdapter = 'com.raytheon.uf.common.dataplugin.gfe.svcbu.JobProgress' + +def serialize(context, mode): + context.protocol.writeFieldBegin('__enumValue__', TType.STRING, 0) + context.writeString(mode.value) + +def deserialize(context): + result = JobProgress() + # Read the TType.STRING, "__enumValue__", and id. + # We're not interested in any of those, so just discard them. + context.protocol.readFieldBegin() + # now get the actual enum value + result.value = context.readString() + return result diff --git a/pythonPackages/dynamicserialize/adapters/__init__.py b/pythonPackages/dynamicserialize/adapters/__init__.py index 83ccb89571..fdf496f84c 100644 --- a/pythonPackages/dynamicserialize/adapters/__init__.py +++ b/pythonPackages/dynamicserialize/adapters/__init__.py @@ -31,7 +31,7 @@ # 03/20/13 #1774 randerso Added TimeConstraintsAdapter # 04/22/13 #1949 rjpeter Added LockTableAdapter # 02/06/14 #2672 bsteffen Added JTSEnvelopeAdapter - +# 06/22/2015 #4573 randerso Added JobProgressAdapter # # @@ -56,8 +56,8 @@ __all__ = [ 'ByteBufferAdapter', 'TimeConstraintsAdapter', 'LockTableAdapter', - 'JTSEnvelopeAdapter' -# 'GridDataHistoryAdapter', + 'JTSEnvelopeAdapter', + 'JobProgressAdapter', ] classAdapterRegistry = {} diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/response/GeometryResponseData.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/response/GeometryResponseData.py index 9a1c69758f..9cadff010c 100644 --- a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/response/GeometryResponseData.py +++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/response/GeometryResponseData.py @@ -27,6 +27,7 @@ # ------------ ---------- ----------- -------------------------- # 06/04/13 #2023 dgilling Initial Creation. # 01/06/14 #2537 bsteffen Store geometry index instead of WKT. +# 06/30/15 #4569 nabowle Rename *WKT* to *WKB*. # # @@ -38,7 +39,7 @@ class GeometryResponseData(AbstractResponseData): def __init__(self): super(GeometryResponseData, self).__init__() self.dataMap = None - self.geometryWKTindex = None + self.geometryWKBindex = None def getDataMap(self): return self.dataMap @@ -46,8 +47,8 @@ class GeometryResponseData(AbstractResponseData): def setDataMap(self, dataMap): self.dataMap = dataMap - def getGeometryWKTindex(self): - return self.geometryWKTindex + def getGeometryWKBindex(self): + return self.geometryWKBindex - def setGeometryWKTindex(self, geometryWKTindex): - self.geometryWKTindex = geometryWKTindex + def setGeometryWKBindex(self, geometryWKBindex): + self.geometryWKBindex = geometryWKBindex diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/response/GetGeometryDataResponse.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/response/GetGeometryDataResponse.py index 2107a0704f..0927426db8 100644 --- a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/response/GetGeometryDataResponse.py +++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataaccess/response/GetGeometryDataResponse.py @@ -23,14 +23,14 @@ class GetGeometryDataResponse(object): def __init__(self): - self.geometryWKTs = None + self.geometryWKBs = None self.geoData = None - def getGeometryWKTs(self): - return self.geometryWKTs + def getGeometryWKBs(self): + return self.geometryWKBs - def setGeometryWKTs(self, geometryWKTs): - self.geometryWKTs = geometryWKTs + def setGeometryWKBs(self, geometryWKBs): + self.geometryWKBs = geometryWKBs def getGeoData(self): return self.geoData diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/CombinationsFileChangedNotification.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/CombinationsFileChangedNotification.py new file mode 100644 index 0000000000..8c21f31bf4 --- /dev/null +++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/CombinationsFileChangedNotification.py @@ -0,0 +1,53 @@ +## +# This software was developed and / or modified by Raytheon Company, +# pursuant to Contract DG133W-05-CQ-1067 with the US Government. +# +# U.S. EXPORT CONTROLLED TECHNICAL DATA +# This software product contains export-restricted data whose +# export/transfer/disclosure is restricted by U.S. law. Dissemination +# to non-U.S. persons whether in the United States or abroad requires +# an export license or other authorization. +# +# Contractor Name: Raytheon Company +# Contractor Address: 6825 Pine Street, Suite 340 +# Mail Stop B8 +# Omaha, NE 68106 +# 402.291.0100 +# +# See the AWIPS II Master Rights File ("Master Rights File.pdf") for +# further licensing information. +## +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# 06/22/2015 4573 randerso Initial creation (hand generated) +# +## + +import GfeNotification + +class CombinationsFileChangedNotification(GfeNotification.GfeNotification): + + def __init__(self): + super(CombinationsFileChangedNotification, self).__init__() + self.combinationsFileName = None + self.whoChanged = None + + def __str__(self): + msg = "fileName: " + str(self.combinationsFileName) + msg += '\n' + "whoChanged: " + str(self.whoChanged) + return msg + + def getCombinationsFileName(self): + return self.combinationsFileName + + def setCombinationsFileName(self, combinationsFileName): + self.combinationsFileName = combinationsFileName + + def getWhoChanged(self): + return self.whoChanged + + def setWhoChanged(self, whoChanged): + self.whoChanged = whoChanged diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/DBInvChangeNotification.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/DBInvChangeNotification.py index 2cec637bb5..c539441f0c 100644 --- a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/DBInvChangeNotification.py +++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/DBInvChangeNotification.py @@ -17,23 +17,25 @@ # See the AWIPS II Master Rights File ("Master Rights File.pdf") for # further licensing information. ## +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# ??/??/???? ???? njensen Modified to add __repr__ +# 06/22/2015 4573 randerso Change to extend GfeNotification +# removed inventory methods +# +## -# File auto-generated against equivalent DynamicSerialize Java class -# Modified by njensen to add __repr__ +import GfeNotification -class DBInvChangeNotification(object): +class DBInvChangeNotification(GfeNotification.GfeNotification): def __init__(self): - self.inventory = None + super(DBInvChangeNotification, self).__init__() self.additions = None self.deletions = None - self.siteID = None - - def getInventory(self): - return self.inventory - - def setInventory(self, inventory): - self.inventory = inventory def getAdditions(self): return self.additions @@ -47,15 +49,8 @@ class DBInvChangeNotification(object): def setDeletions(self, deletions): self.deletions = deletions - def getSiteID(self): - return self.siteID - - def setSiteID(self, siteID): - self.siteID = siteID - - def __repr__(self): - msg = 'Inventory' + str(self.inventory) + '\n' - msg += 'Additions' + str(self.additions) + '\n' + def __str__(self): + msg = 'Additions' + str(self.additions) + '\n' msg += 'Deletions' + str(self.deletions) return msg diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/GfeNotification.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/GfeNotification.py index 40361214bb..a1405cee3d 100644 --- a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/GfeNotification.py +++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/GfeNotification.py @@ -15,11 +15,21 @@ # # See the AWIPS II Master Rights File ("Master Rights File.pdf") for # further licensing information. +## +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# 10/07/2014 3684 randerso Manually updated to add sourceID +# +## +import abc -# File auto-generated against equivalent DynamicSerialize Java class - -class GfeNotification: +class GfeNotification(object): + __metaclass__ = abc.ABCMeta + @abc.abstractmethod def __init__(self): self.siteID = None self.sourceID = None diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/GridHistoryUpdateNotification.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/GridHistoryUpdateNotification.py new file mode 100644 index 0000000000..3a084362ae --- /dev/null +++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/GridHistoryUpdateNotification.py @@ -0,0 +1,61 @@ +## +# This software was developed and / or modified by Raytheon Company, +# pursuant to Contract DG133W-05-CQ-1067 with the US Government. +# +# U.S. EXPORT CONTROLLED TECHNICAL DATA +# This software product contains export-restricted data whose +# export/transfer/disclosure is restricted by U.S. law. Dissemination +# to non-U.S. persons whether in the United States or abroad requires +# an export license or other authorization. +# +# Contractor Name: Raytheon Company +# Contractor Address: 6825 Pine Street, Suite 340 +# Mail Stop B8 +# Omaha, NE 68106 +# 402.291.0100 +# +# See the AWIPS II Master Rights File ("Master Rights File.pdf") for +# further licensing information. +## +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# 06/22/2015 4573 randerso Initial creation (hand generated) +# +## + +import GfeNotification + +class GridHistoryUpdateNotification(GfeNotification.GfeNotification): + + def __init__(self): + super(GridHistoryUpdateNotification, self).__init__() + self.parmId = None + self.workstationID = None + self.histories = None + + def getParmId(self): + return self.parmId + + def setParmId(self, parmId): + self.parmId = parmId + + def getWorkstationID(self): + return self.workstationID + + def setWorkstationID(self, workstationID): + self.workstationID = workstationID + + def getHistories(self): + return self.histories + + def setHistories(self, histories): + self.histories = histories + + def __str__(self): + msg = "ParmID: " + str(self.parmId) + msg += '\n' + "Histories: " + str(self.histories) + return msg + diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/GridUpdateNotification.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/GridUpdateNotification.py index c003345bce..2fb7cf8918 100644 --- a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/GridUpdateNotification.py +++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/GridUpdateNotification.py @@ -17,17 +17,25 @@ # See the AWIPS II Master Rights File ("Master Rights File.pdf") for # further licensing information. ## +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# ??/??/???? ???? njensen Modified to add __repr__ +# 06/22/2015 4573 randerso Change to extend GfeNotification +# +## -# File auto-generated against equivalent DynamicSerialize Java class -# Modified by njensen to add __repr__ +import GfeNotification -class GridUpdateNotification(object): +class GridUpdateNotification(GfeNotification.GfeNotification): def __init__(self): + super(GridUpdateNotification, self).__init__() self.parmId = None self.replacementTimeRange = None self.workstationID = None - self.siteID = None self.histories = None def getParmId(self): @@ -48,12 +56,6 @@ class GridUpdateNotification(object): def setWorkstationID(self, workstationID): self.workstationID = workstationID - def getSiteID(self): - return self.siteID - - def setSiteID(self, siteID): - self.siteID = siteID - def getHistories(self): return self.histories @@ -61,9 +63,6 @@ class GridUpdateNotification(object): self.histories = histories def __str__(self): - return self.__repr__() - - def __repr__(self): msg = "ParmID: " + str(self.parmId) msg += '\n' + "Replacement TimeRange: " + str(self.replacementTimeRange) msg += '\n' + "Histories: " + str(self.histories) diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/LockNotification.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/LockNotification.py index 0472a761d5..cc7049ceb1 100644 --- a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/LockNotification.py +++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/LockNotification.py @@ -17,15 +17,23 @@ # See the AWIPS II Master Rights File ("Master Rights File.pdf") for # further licensing information. ## +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# ??/??/???? ???? njensen Modified to add __repr__ +# 06/22/2015 4573 randerso Change to extend GfeNotification +# +## -# File auto-generated against equivalent DynamicSerialize Java class -# Modified by njensen to add __repr__ +import GfeNotification -class LockNotification(object): +class LockNotification(GfeNotification.GfeNotification): def __init__(self): + super(LockNotification, self).__init__() self.lockTable = None - self.siteID = None def getLockTable(self): return self.lockTable @@ -33,12 +41,6 @@ class LockNotification(object): def setLockTable(self, lockTable): self.lockTable = lockTable - def getSiteID(self): - return self.siteID - - def setSiteID(self, siteID): - self.siteID = siteID - - def __repr__(self): + def __str__(self): return str(self.lockTable) diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/ServiceBackupJobStatusNotification.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/ServiceBackupJobStatusNotification.py new file mode 100644 index 0000000000..9f15b563cc --- /dev/null +++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/ServiceBackupJobStatusNotification.py @@ -0,0 +1,54 @@ +## +# This software was developed and / or modified by Raytheon Company, +# pursuant to Contract DG133W-05-CQ-1067 with the US Government. +# +# U.S. EXPORT CONTROLLED TECHNICAL DATA +# This software product contains export-restricted data whose +# export/transfer/disclosure is restricted by U.S. law. Dissemination +# to non-U.S. persons whether in the United States or abroad requires +# an export license or other authorization. +# +# Contractor Name: Raytheon Company +# Contractor Address: 6825 Pine Street, Suite 340 +# Mail Stop B8 +# Omaha, NE 68106 +# 402.291.0100 +# +# See the AWIPS II Master Rights File ("Master Rights File.pdf") for +# further licensing information. +## +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# 06/22/2015 4573 randerso Initial creation (hand generated) +# +## + +import GfeNotification + +class ServiceBackupJobStatusNotification(GfeNotification.GfeNotification): + + def __init__(self): + super(ServiceBackupJobStatusNotification, self).__init__() + self.name = None + self.state = "UNKNOWN" + + def __str__(self): + msg = "name: " + str(self.name) + msg += '\n' + "state: " + str(self.state) + return msg + + def getName(self): + return self.name + + def setName(self, name): + self.name = name + + def getState(self): + return self.state + + def setState(self, state): + self.state = state + \ No newline at end of file diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/UserMessageNotification.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/UserMessageNotification.py index 8ec848cc8c..5189851ae2 100644 --- a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/UserMessageNotification.py +++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/UserMessageNotification.py @@ -17,16 +17,24 @@ # See the AWIPS II Master Rights File ("Master Rights File.pdf") for # further licensing information. ## +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# 06/22/2015 4573 randerso Change to extend GfeNotification +# +## -# File auto-generated against equivalent DynamicSerialize Java class +import GfeNotification -class UserMessageNotification(object): +class UserMessageNotification(GfeNotification.GfeNotification): def __init__(self): + super(UserMessageNotification, self).__init__() self.category = None self.priority = None self.message = None - self.siteID = None def getCategory(self): return self.category @@ -46,13 +54,7 @@ class UserMessageNotification(object): def setMessage(self, message): self.message = message - def getSiteID(self): - return self.siteID - - def setSiteID(self, siteID): - self.siteID = siteID - - def __repr__(self): + def __str__(self): msg = 'Message: ' + str(self.message) + '\n' msg += 'Priority: ' + str(self.priority) + '\n' msg += 'Category: ' + str(self.category) + '\n' diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/__init__.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/__init__.py index b799893e35..8f735f57f5 100644 --- a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/__init__.py +++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/server/notify/__init__.py @@ -21,16 +21,22 @@ # File auto-generated by PythonFileGenerator __all__ = [ + 'CombinationsFileChangedNotification', 'DBInvChangeNotification', 'GfeNotification', + 'GridHistoryUpdateNotification', 'GridUpdateNotification', 'LockNotification', + 'ServiceBackupJobStatusNotification', 'UserMessageNotification' ] +from CombinationsFileChangedNotification import CombinationsFileChangedNotification from DBInvChangeNotification import DBInvChangeNotification from GfeNotification import GfeNotification +from GridHistoryUpdateNotification import GridHistoryUpdateNotification from GridUpdateNotification import GridUpdateNotification from LockNotification import LockNotification +from ServiceBackupJobStatusNotification import ServiceBackupJobStatusNotification from UserMessageNotification import UserMessageNotification diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/svcbu/JobProgress.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/svcbu/JobProgress.py new file mode 100644 index 0000000000..d06a846bf0 --- /dev/null +++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/svcbu/JobProgress.py @@ -0,0 +1,34 @@ +## +# This software was developed and / or modified by Raytheon Company, +# pursuant to Contract DG133W-05-CQ-1067 with the US Government. +# +# U.S. EXPORT CONTROLLED TECHNICAL DATA +# This software product contains export-restricted data whose +# export/transfer/disclosure is restricted by U.S. law. Dissemination +# to non-U.S. persons whether in the United States or abroad requires +# an export license or other authorization. +# +# Contractor Name: Raytheon Company +# Contractor Address: 6825 Pine Street, Suite 340 +# Mail Stop B8 +# Omaha, NE 68106 +# 402.291.0100 +# +# See the AWIPS II Master Rights File ("Master Rights File.pdf") for +# further licensing information. +## +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# 06/22/2015 4573 randerso Initial creation (hand generated) +# +## + +class JobProgress(object): + def __init__(self): + self.value = None + + def __str__(self): + return repr(self.value) diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/svcbu/__init__.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/svcbu/__init__.py new file mode 100644 index 0000000000..117a2b2dc5 --- /dev/null +++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/gfe/svcbu/__init__.py @@ -0,0 +1,33 @@ +## +# This software was developed and / or modified by Raytheon Company, +# pursuant to Contract DG133W-05-CQ-1067 with the US Government. +# +# U.S. EXPORT CONTROLLED TECHNICAL DATA +# This software product contains export-restricted data whose +# export/transfer/disclosure is restricted by U.S. law. Dissemination +# to non-U.S. persons whether in the United States or abroad requires +# an export license or other authorization. +# +# Contractor Name: Raytheon Company +# Contractor Address: 6825 Pine Street, Suite 340 +# Mail Stop B8 +# Omaha, NE 68106 +# 402.291.0100 +# +# See the AWIPS II Master Rights File ("Master Rights File.pdf") for +# further licensing information. +## +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# 06/22/2015 4573 randerso Initial creation (hand generated) +# +## + +__all__ = [ + 'JobProgress', + ] + +from JobProgress import JobProgress diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/level/Level.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/level/Level.py index c5a71a03b5..79bf68172e 100644 --- a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/level/Level.py +++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/level/Level.py @@ -28,6 +28,8 @@ # ------------ ---------- ----------- -------------------------- # 05/29/13 2023 dgilling Initial Creation. # 02/12/14 2672 bsteffen Allow String constructor to parse floats. +# 06/29/15 4480 dgilling Implement __hash__, __eq__, +# __str__ and rich comparison operators. # @@ -58,6 +60,120 @@ class Level(object): if levelTwo: self.leveltwovalue = numpy.float64(levelTwo) + def __hash__(self): + # XOR-ing the 3 items in a tuple ensures that order of the + # values matters + hashCode = hash(self.masterLevel) ^ hash(self.levelonevalue) ^ hash(self.leveltwovalue) + hashCode ^= hash((self.masterLevel, self.levelonevalue, self.leveltwovalue)) + return hashCode + + def __eq__(self, other): + if type(self) != type(other): + return False + else: + return (self.masterLevel, self.levelonevalue, self.leveltwovalue) == \ + (other.masterLevel, other.levelonevalue, other.leveltwovalue) + + def __ne__(self, other): + return not self.__eq__(other) + + def __lt__(self, other): + if type(self) != type(other): + return NotImplemented + elif self.masterLevel.getName() != other.masterLevel.getName(): + return NotImplemented + + myLevel1 = self.levelonevalue + myLevel2 = self.leveltwovalue + otherLevel1 = other.levelonevalue + otherLevel2 = other.leveltwovalue + if myLevel1 == INVALID_VALUE and myLevel2 != INVALID_VALUE: + myLevel1 = myLevel2 + myLevel2 = INVALID_VALUE + if otherLevel1 == INVALID_VALUE and otherLevel2 != INVALID_VALUE: + otherLevel1 = otherLevel2 + otherLevel2 = INVALID_VALUE + + # We default to descending order to make sorting levels from the DAF easier + compareType = self.masterLevel.getType() if self.masterLevel.getType() else "DEC" + if myLevel1 != INVALID_VALUE and otherLevel1 != INVALID_VALUE: + level1Cmp = self.__compareLevelValues(compareType, myLevel1, otherLevel1) + if level1Cmp == -1: + if myLevel2 != INVALID_VALUE and otherLevel2 != INVALID_VALUE: + level2Cmp = self.__compareLevelValues(compareType, myLevel2, otherLevel2) + return level2Cmp == -1 + elif myLevel2 != INVALID_VALUE: + level2Cmp = self.__compareLevelValues(compareType, myLevel2, otherLevel1) + return level2Cmp == -1 + else: + return True + return False + + def __le__(self, other): + if type(self) != type(other): + return NotImplemented + elif self.masterLevel.getName() != other.masterLevel.getName(): + return NotImplemented + + return self.__lt__(other) or self.__eq__(other) + + def __gt__(self, other): + if type(self) != type(other): + return NotImplemented + elif self.masterLevel.getName() != other.masterLevel.getName(): + return NotImplemented + + myLevel1 = self.levelonevalue + myLevel2 = self.leveltwovalue + otherLevel1 = other.levelonevalue + otherLevel2 = other.leveltwovalue + if myLevel1 == INVALID_VALUE and myLevel2 != INVALID_VALUE: + myLevel1 = myLevel2 + myLevel2 = INVALID_VALUE + if otherLevel1 == INVALID_VALUE and otherLevel2 != INVALID_VALUE: + otherLevel1 = otherLevel2 + otherLevel2 = INVALID_VALUE + + # We default to descending order to make sorting levels from the DAF easier + compareType = self.masterLevel.getType() if self.masterLevel.getType() else "DEC" + if myLevel1 != INVALID_VALUE and otherLevel1 != INVALID_VALUE: + level1Cmp = self.__compareLevelValues(compareType, myLevel1, otherLevel1) + if level1Cmp == 1: + if myLevel2 != INVALID_VALUE and otherLevel2 != INVALID_VALUE: + level2Cmp = self.__compareLevelValues(compareType, myLevel2, otherLevel2) + return level2Cmp == 1 + elif otherLevel2 != INVALID_VALUE: + level2Cmp = self.__compareLevelValues(compareType, myLevel1, otherLevel2) + return level2Cmp == 1 + else: + return True + return False + + def __ge__(self, other): + if type(self) != type(other): + return NotImplemented + elif self.masterLevel.getName() != other.masterLevel.getName(): + return NotImplemented + + return self.__gt__(other) or self.__eq__(other) + + def __compareLevelValues(self, compareType, val1, val2): + returnVal = 0 + if val1 < val2: + returnVal = -1 if compareType == 'INC' else 1 + elif val2 < val1: + returnVal = 1 if compareType == 'INC' else -1 + return returnVal + + def __str__(self): + retVal = "" + if INVALID_VALUE != self.levelonevalue: + retVal += str(self.levelonevalue) + if INVALID_VALUE != self.leveltwovalue: + retVal += "_" + str(self.leveltwovalue) + retVal += str(self.masterLevel.getName()) + return retVal + def getId(self): return self.id @@ -87,4 +203,3 @@ class Level(object): def setIdentifier(self, identifier): self.identifier = identifier - diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/level/MasterLevel.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/level/MasterLevel.py index 409bae6ae3..beb0962323 100644 --- a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/level/MasterLevel.py +++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/dataplugin/level/MasterLevel.py @@ -27,6 +27,8 @@ # Date Ticket# Engineer Description # ------------ ---------- ----------- -------------------------- # 05/29/13 2023 dgilling Initial Creation. +# 06/29/15 4480 dgilling Implement __hash__, __eq__ +# and __str__. # # @@ -39,6 +41,27 @@ class MasterLevel(object): self.type = None self.identifier = None + def __hash__(self): + return hash(self.name) + + def __eq__(self, other): + if type(self) != type(other): + return False + else: + return self.name == other.name + + def __ne__(self, other): + return not self.__eq__(other) + + def __str__(self): + retVal = "MasterLevel[" + retVal += "name=" + str(self.name) + "," + retVal += "type=" + str(self.type) + "," + retVal += "unit=" + str(self.unitString) + "," + retVal += "description=" + str(self.description) + retVal += "]" + return retVal + def getName(self): return self.name diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/time/DataTime.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/time/DataTime.py index 320c5c2a69..182f17e5eb 100644 --- a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/time/DataTime.py +++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/time/DataTime.py @@ -31,6 +31,9 @@ # 01/22/14 2667 bclement preserved milliseconds in string representation # 03/03/14 2673 bsteffen allow construction using a Date for refTime # 06/24/14 3096 mnash implement __cmp__ +# 06/24/15 4480 dgilling implement __hash__ and __eq__, +# replace __cmp__ with rich comparison +# operators. # import calendar @@ -66,9 +69,7 @@ class DataTime(object): self.refTime = long(self.refTime.getTime()) else: self.refTime = long(refTime) - dateObj = Date() - dateObj.setTime(self.refTime) - self.refTime = dateObj + self.refTime = Date(self.refTime) if self.validPeriod is None: validTimeMillis = self.refTime.getTime() + long(self.fcstTime * 1000) @@ -112,38 +113,6 @@ class DataTime(object): def setLevelValue(self, levelValue): self.levelValue = numpy.float64(levelValue) - def __cmp__(self, other): - if other is None : - return 1 - - # compare the valid times, which are the ref times + forecast times - validTimeCmp = cmp(self.getRefTime().getTime() + self.getFcstTime(), - other.getRefTime().getTime() + other.getFcstTime()) - if validTimeCmp != 0 : - return validTimeCmp - - # compare the forecast times - fcstTimeCmp = cmp(self.getFcstTime(), other.getFcstTime()) - if fcstTimeCmp != 0 : - return fcstTimeCmp - - # compare the level values - levelCmp = cmp(self.getLevelValue(), other.getLevelValue()) - if levelValue != 0 : - return levelValue - - # compare the valid periods - period1 = self.getValidPeriod() - period2 = other.getValidPerid() - - if period1 is None : - return -1 - elif period2 is None : - return 1 - - return cmp(period1.getDuration(), period2.getDuration()) - - def __str__(self): buffer = StringIO.StringIO() @@ -172,3 +141,86 @@ class DataTime(object): strVal = buffer.getvalue() buffer.close() return strVal + + def __repr__(self): + return "" + + def __hash__(self): + hashCode = hash(self.refTime) ^ hash(self.fcstTime) + if self.validPeriod is not None and self.validPeriod.isValid(): + hashCode ^= hash(self.validPeriod.getStart()) + hashCode ^= hash(self.validPeriod.getEnd()) + hashCode ^= hash(self.levelValue) + return hashCode + + def __eq__(self, other): + if type(self) != type(other): + return False + + if other.getRefTime() is None: + return self.fcstTime == other.fcstTime + + dataTime1 = (self.refTime, self.fcstTime, self.validPeriod, self.levelValue) + dataTime2 = (other.refTime, other.fcstTime, other.validPeriod, other.levelValue) + return dataTime1 == dataTime2 + + def __ne__(self, other): + return not self.__eq__(other) + + def __lt__(self, other): + if type(self) != type(other): + return NotImplemented + + myValidTime = self.getRefTime().getTime() + self.getFcstTime() + otherValidTime = other.getRefTime().getTime() + other.getFcstTime() + if myValidTime < otherValidTime: + return True + + if self.fcstTime < other.fcstTime: + return True + + if self.levelValue < other.levelValue: + return True + + myValidPeriod = self.validPeriod + otherValidPeriod = other.validPeriod + if myValidPeriod != otherValidPeriod: + if myValidPeriod.duration() < otherValidPeriod.duration(): + return True + return myValidPeriod.getStartInMillis() < otherValidPeriod.getStartInMillis() + return False + + def __le__(self, other): + if type(self) != type(other): + return NotImplemented + + return self.__lt__(other) or self.__eq__(other) + + def __gt__(self, other): + if type(self) != type(other): + return NotImplemented + + myValidTime = self.getRefTime().getTime() + self.getFcstTime() + otherValidTime = other.getRefTime().getTime() + other.getFcstTime() + if myValidTime > otherValidTime: + return True + + if self.fcstTime > other.fcstTime: + return True + + if self.levelValue > other.levelValue: + return True + + myValidPeriod = self.validPeriod + otherValidPeriod = other.validPeriod + if myValidPeriod != otherValidPeriod: + if myValidPeriod.duration() > otherValidPeriod.duration(): + return True + return myValidPeriod.getStartInMillis() > otherValidPeriod.getStartInMillis() + return False + + def __ge__(self, other): + if type(self) != type(other): + return NotImplemented + + return self.__gt__(other) or self.__eq__(other) \ No newline at end of file diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/time/TimeRange.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/time/TimeRange.py index ff5819e5d9..8dbffd3898 100644 --- a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/time/TimeRange.py +++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/time/TimeRange.py @@ -28,6 +28,7 @@ # ??/??/?? xxxxxxxx Initial Creation. # 01/22/14 2667 bclement fixed millisecond support # 02/28/14 2667 bclement constructor can take extra micros for start and end +# 06/24/15 4480 dgilling fix __eq__. # # # @@ -51,7 +52,15 @@ class TimeRange(object): return "(" + self.start.strftime("%b %d %y %H:%M:%S %Z") + ", " + self.end.strftime("%b %d %y %H:%M:%S %Z") + ")" def __eq__(self, other): - return ((self.start == other.start) and (self.end == other.end)) + if type(self) != type(other): + return False + + if self.isValid() and other.isValid(): + return self.getStart() == other.getStart() and self.getEnd() == other.getEnd() + elif not self.isValid() and not other.isValid(): + return True + else: + return False def __ne__(self, other): return (not self.__eq__(other)) @@ -132,7 +141,7 @@ class TimeRange(object): return convTime == self.start def isValid(self): - return (self.start != self.end) + return bool(self.start != self.end) def overlaps(self, timeRange): return (timeRange.contains(self.start) or self.contains(timeRange.start)) diff --git a/pythonPackages/dynamicserialize/dstypes/java/sql/Timestamp.py b/pythonPackages/dynamicserialize/dstypes/java/sql/Timestamp.py index 9678759314..e55aaab7f5 100644 --- a/pythonPackages/dynamicserialize/dstypes/java/sql/Timestamp.py +++ b/pythonPackages/dynamicserialize/dstypes/java/sql/Timestamp.py @@ -18,25 +18,22 @@ # further licensing information. ## -## NOTE: This is a dummy class that is only used for deserialization -## support. Further work required if it is need in the pure Python -## environment. +# File auto-generated against equivalent DynamicSerialize Java class +# and then modified post-generation to add additional features to better +# match Java implementation. +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# ??/??/?? xxxxxxxx Initial Creation. +# 06/24/15 4480 dgilling implement based on Date class. +# -class Timestamp(object): +from dynamicserialize.dstypes.java.util import Date + + +class Timestamp(Date): def __init__(self, time=None): - self.time = time - - def getTime(self): - return self.time - - def setTime(self, timeInMillis): - self.time = timeInMillis - - def __str__(self): - return self.__repr__() - - def __repr__(self): - from time import gmtime, strftime - - return strftime("%b %d %y %H:%M:%S GMT", gmtime(self.time/1000.0)) + super(Timestamp, self).__init__(time) diff --git a/pythonPackages/dynamicserialize/dstypes/java/util/Date.py b/pythonPackages/dynamicserialize/dstypes/java/util/Date.py index 4f672631cd..97879dde70 100644 --- a/pythonPackages/dynamicserialize/dstypes/java/util/Date.py +++ b/pythonPackages/dynamicserialize/dstypes/java/util/Date.py @@ -24,14 +24,17 @@ # Date Ticket# Engineer Description # ------------ ---------- ----------- -------------------------- # 04/28/2015 4027 randerso Added optional construction parameter to set the time +# 06/26/2015 4480 dgilling Implement __eq__ and __hash__. # ## +from time import gmtime, strftime + class Date(object): def __init__(self, timeInMillis=None): - self.time = None + self.time = timeInMillis def getTime(self): return self.time @@ -43,6 +46,13 @@ class Date(object): return self.__repr__() def __repr__(self): - from time import gmtime, strftime - - return strftime("%b %d %y %H:%M:%S GMT", gmtime(self.time/1000.0)) \ No newline at end of file + return strftime("%b %d %y %H:%M:%S GMT", gmtime(self.time/1000.0)) + + def __eq__(self, other): + return self.time == other.time + + def __ne__(self, other): + return not self.__eq__(other) + + def __hash__(self): + return hash(self.time) diff --git a/pythonPackages/ufpy/DateTimeConverter.py b/pythonPackages/ufpy/DateTimeConverter.py new file mode 100644 index 0000000000..3295ac5f39 --- /dev/null +++ b/pythonPackages/ufpy/DateTimeConverter.py @@ -0,0 +1,107 @@ +# # +# This software was developed and / or modified by Raytheon Company, +# pursuant to Contract DG133W-05-CQ-1067 with the US Government. +# +# U.S. EXPORT CONTROLLED TECHNICAL DATA +# This software product contains export-restricted data whose +# export/transfer/disclosure is restricted by U.S. law. Dissemination +# to non-U.S. persons whether in the United States or abroad requires +# an export license or other authorization. +# +# Contractor Name: Raytheon Company +# Contractor Address: 6825 Pine Street, Suite 340 +# Mail Stop B8 +# Omaha, NE 68106 +# 402.291.0100 +# +# See the AWIPS II Master Rights File ("Master Rights File.pdf") for +# further licensing information. +# # + +# +# Functions for converting between the various "Java" dynamic serialize types +# used by EDEX to the native python time datetime. +# +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# 06/24/15 #4480 dgilling Initial Creation. +# + +import datetime +import time + +from dynamicserialize.dstypes.java.util import Date +from dynamicserialize.dstypes.java.sql import Timestamp +from dynamicserialize.dstypes.com.raytheon.uf.common.time import TimeRange + + +MAX_TIME = pow(2, 31) - 1 +MICROS_IN_SECOND = 1000000 + + +def convertToDateTime(timeArg): + """ + Converts the given object to a python datetime object. Supports native + python representations like datetime and struct_time, but also + the dynamicserialize types like Date and Timestamp. Raises TypeError + if no conversion can be performed. + + Args: + timeArg: a python object representing a date and time. Supported + types include datetime, struct_time, float, int, long and the + dynamicserialize types Date and Timestamp. + + Returns: + A datetime that represents the same date/time as the passed in object. + """ + if isinstance(timeArg, datetime.datetime): + return timeArg + elif isinstance(timeArg, time.struct_time): + return datetime.datetime(*timeArg[:6]) + elif isinstance(timeArg, float): + # seconds as float, should be avoided due to floating point errors + totalSecs = long(timeArg) + micros = int((timeArg - totalSecs) * MICROS_IN_SECOND) + return _convertSecsAndMicros(totalSecs, micros) + elif isinstance(timeArg, (int, long)): + # seconds as integer + totalSecs = timeArg + return _convertSecsAndMicros(totalSecs, 0) + elif isinstance(timeArg, (Date, Timestamp)): + totalSecs = timeArg.getTime() + return _convertSecsAndMicros(totalSecs, 0) + else: + objType = str(type(timeArg)) + raise TypeError("Cannot convert object of type " + objType + " to datetime.") + +def _convertSecsAndMicros(seconds, micros): + if seconds < MAX_TIME: + rval = datetime.datetime.utcfromtimestamp(seconds) + else: + extraTime = datetime.timedelta(seconds=(seconds - MAX_TIME)) + rval = datetime.datetime.utcfromtimestamp(MAX_TIME) + extraTime + return rval.replace(microsecond=micros) + +def constructTimeRange(*args): + """ + Builds a python dynamicserialize TimeRange object from the given + arguments. + + Args: + args*: must be a TimeRange or a pair of objects that can be + converted to a datetime via convertToDateTime(). + + Returns: + A TimeRange. + """ + + if len(args) == 1 and isinstance(args[0], TimeRange): + return args[0] + if len(args) != 2: + raise TypeError("constructTimeRange takes exactly 2 arguments, " + str(len(args)) + " provided.") + startTime = convertToDateTime(args[0]) + endTime = convertToDateTime(args[1]) + return TimeRange(startTime, endTime) diff --git a/pythonPackages/ufpy/dataaccess/SoundingsSupport.py b/pythonPackages/ufpy/dataaccess/SoundingsSupport.py new file mode 100644 index 0000000000..2f0bb2043e --- /dev/null +++ b/pythonPackages/ufpy/dataaccess/SoundingsSupport.py @@ -0,0 +1,283 @@ +# # +# This software was developed and / or modified by Raytheon Company, +# pursuant to Contract DG133W-05-CQ-1067 with the US Government. +# +# U.S. EXPORT CONTROLLED TECHNICAL DATA +# This software product contains export-restricted data whose +# export/transfer/disclosure is restricted by U.S. law. Dissemination +# to non-U.S. persons whether in the United States or abroad requires +# an export license or other authorization. +# +# Contractor Name: Raytheon Company +# Contractor Address: 6825 Pine Street, Suite 340 +# Mail Stop B8 +# Omaha, NE 68106 +# 402.291.0100 +# +# See the AWIPS II Master Rights File ("Master Rights File.pdf") for +# further licensing information. +# # + +# +# Classes for retrieving soundings based on gridded data from the Data Access +# Framework +# +# +# +# SOFTWARE HISTORY +# +# Date Ticket# Engineer Description +# ------------ ---------- ----------- -------------------------- +# 06/24/15 #4480 dgilling Initial Creation. +# + +from collections import defaultdict +from shapely.geometry import Point + +from ufpy import DateTimeConverter +from ufpy.dataaccess import DataAccessLayer + +from dynamicserialize.dstypes.com.raytheon.uf.common.time import DataTime +from dynamicserialize.dstypes.com.raytheon.uf.common.dataplugin.level import Level + + +def getSounding(modelName, weatherElements, levels, samplePoint, refTime=None, timeRange=None): + """" + Performs a series of Data Access Framework requests to retrieve a sounding object + based on the specified request parameters. + + Args: + modelName: the grid model datasetid to use as the basis of the sounding. + weatherElements: a list of parameters to return in the sounding. + levels: a list of levels to sample the given weather elements at + samplePoint: a lat/lon pair to perform the sampling of data at. + refTime: (optional) the grid model reference time to use for the sounding. + If not specified, the latest ref time in the system will be used. + timeRange: (optional) a TimeRange to specify which forecast hours to use. + If not specified, will default to all forecast hours. + + Returns: + A _SoundingCube instance, which acts a 3-tiered dictionary, keyed + by DataTime, then by level and finally by weather element. If no + data is available for the given request parameters, None is returned. + """ + + (locationNames, parameters, levels, envelope, refTime, timeRange) = \ + __sanitizeInputs(modelName, weatherElements, levels, samplePoint, refTime, timeRange) + + requestArgs = { 'datatype' : 'grid', + 'locationNames' : locationNames, + 'parameters' : parameters, + 'levels' : levels, + 'envelope' : envelope, + } + + req = DataAccessLayer.newDataRequest(**requestArgs) + + forecastHours = __determineForecastHours(req, refTime, timeRange) + if not forecastHours: + return None + + response = DataAccessLayer.getGeometryData(req, forecastHours) + soundingObject = _SoundingCube(response) + + return soundingObject + +def setEDEXHost(host): + """ + Changes the EDEX host the Data Access Framework is communicating with. + + Args: + host: the EDEX host to connect to + """ + + if host: + DataAccessLayer.changeEDEXHost(str(host)) + +def __sanitizeInputs(modelName, weatherElements, levels, samplePoint, refTime, timeRange): + locationNames = [str(modelName)] + parameters = __buildStringList(weatherElements) + levels = __buildStringList(levels) + envelope = Point(samplePoint) + if refTime is not None: + refTime = DataTime(refTime=DateTimeConverter.convertToDateTime(refTime)) + if timeRange is not None: + timeRange = DateTimeConverter.constructTimeRange(*timeRange) + return (locationNames, parameters, levels, envelope, refTime, timeRange) + +def __determineForecastHours(request, refTime, timeRange): + dataTimes = DataAccessLayer.getAvailableTimes(request, False) + timesGen = [(DataTime(refTime=dataTime.getRefTime()), dataTime) for dataTime in dataTimes] + dataTimesMap = defaultdict(list) + for baseTime, dataTime in timesGen: + dataTimesMap[baseTime].append(dataTime) + + if refTime is None: + refTime = max(dataTimesMap.keys()) + + forecastHours = dataTimesMap[refTime] + if timeRange is None: + return forecastHours + else: + return [forecastHour for forecastHour in forecastHours if timeRange.contains(forecastHour.getValidPeriod())] + +def __buildStringList(param): + if __notStringIter(param): + return [str(item) for item in param] + else: + return [str(param)] + +def __notStringIter(iterable): + if not isinstance(iterable, basestring): + try: + iter(iterable) + return True + except TypeError: + return False + + + +class _SoundingCube(object): + """ + The top-level sounding object returned when calling SoundingsSupport.getSounding. + + This object acts as a 3-tiered dict which is keyed by time then level + then parameter name. Calling times() will return all valid keys into this + object. + """ + + def __init__(self, geometryDataObjects): + self._dataDict = {} + self._sortedTimes = [] + if geometryDataObjects: + for geometryData in geometryDataObjects: + dataTime = geometryData.getDataTime() + level = geometryData.getLevel() + for parameter in geometryData.getParameters(): + self.__addItem(parameter, dataTime, level, geometryData.getNumber(parameter)) + + def __addItem(self, parameter, dataTime, level, value): + timeLayer = self._dataDict.get(dataTime, _SoundingTimeLayer(dataTime)) + self._dataDict[dataTime] = timeLayer + timeLayer._addItem(parameter, level, value) + if dataTime not in self._sortedTimes: + self._sortedTimes.append(dataTime) + self._sortedTimes.sort() + + def __getitem__(self, key): + return self._dataDict[key] + + def __len__(self): + return len(self._dataDict) + + def times(self): + """ + Returns the valid times for this sounding. + + Returns: + A list containing the valid DataTimes for this sounding in order. + """ + return self._sortedTimes + + +class _SoundingTimeLayer(object): + """ + The second-level sounding object returned when calling SoundingsSupport.getSounding. + + This object acts as a 2-tiered dict which is keyed by level then parameter + name. Calling levels() will return all valid keys into this + object. Calling time() will return the DataTime for this particular layer. + """ + + def __init__(self, dataTime): + self._dataTime = dataTime + self._dataDict = {} + + def _addItem(self, parameter, level, value): + asString = str(level) + levelLayer = self._dataDict.get(asString, _SoundingTimeAndLevelLayer(self._dataTime, asString)) + levelLayer._addItem(parameter, value) + self._dataDict[asString] = levelLayer + + def __getitem__(self, key): + asString = str(key) + if asString in self._dataDict: + return self._dataDict[asString] + else: + raise KeyError("Level " + str(key) + " is not a valid level for this sounding.") + + def __len__(self): + return len(self._dataDict) + + def time(self): + """ + Returns the DataTime for this sounding cube layer. + + Returns: + The DataTime for this sounding layer. + """ + return self._dataTime + + def levels(self): + """ + Returns the valid levels for this sounding. + + Returns: + A list containing the valid levels for this sounding in order of + closest to surface to highest from surface. + """ + sortedLevels = [Level(level) for level in self._dataDict.keys()] + sortedLevels.sort() + return [str(level) for level in sortedLevels] + + +class _SoundingTimeAndLevelLayer(object): + """ + The bottom-level sounding object returned when calling SoundingsSupport.getSounding. + + This object acts as a dict which is keyed by parameter name. Calling + parameters() will return all valid keys into this object. Calling time() + will return the DataTime for this particular layer. Calling level() will + return the level for this layer. + """ + + def __init__(self, time, level): + self._time = time + self._level = level + self._parameters = {} + + def _addItem(self, parameter, value): + self._parameters[parameter] = value + + def __getitem__(self, key): + return self._parameters[key] + + def __len__(self): + return len(self._parameters) + + def level(self): + """ + Returns the level for this sounding cube layer. + + Returns: + The level for this sounding layer. + """ + return self._level + + def parameters(self): + """ + Returns the valid parameters for this sounding. + + Returns: + A list containing the valid parameter names. + """ + return list(self._parameters.keys()) + + def time(self): + """ + Returns the DataTime for this sounding cube layer. + + Returns: + The DataTime for this sounding layer. + """ + return self._time diff --git a/pythonPackages/ufpy/dataaccess/ThriftClientRouter.py b/pythonPackages/ufpy/dataaccess/ThriftClientRouter.py index 6c96301604..e41d165955 100644 --- a/pythonPackages/ufpy/dataaccess/ThriftClientRouter.py +++ b/pythonPackages/ufpy/dataaccess/ThriftClientRouter.py @@ -33,11 +33,12 @@ # 07/22/14 #3185 njensen Added optional/default args to newDataRequest # 07/23/14 #3185 njensen Added new methods # 07/30/14 #3185 njensen Renamed valid identifiers to optional +# 06/30/15 #4569 nabowle Use hex WKB for geometries. # import numpy -import shapely.wkt +import shapely.wkb from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.impl import DefaultDataRequest from dynamicserialize.dstypes.com.raytheon.uf.common.dataaccess.request import GetAvailableLocationNamesRequest @@ -111,12 +112,15 @@ class ThriftClientRouter(object): geoDataRequest.setRequestedPeriod(times) response = self._client.sendRequest(geoDataRequest) geometries = [] - for wkt in response.getGeometryWKTs(): - geometries.append(shapely.wkt.loads(wkt)) - + for wkb in response.getGeometryWKBs(): + # convert the wkb to a bytearray with only positive values + byteArrWKB = bytearray(map(lambda x: x % 256,wkb.tolist())) + # convert the bytearray to a byte string and load it. + geometries.append(shapely.wkb.loads(str(byteArrWKB))) + retVal = [] for geoDataRecord in response.getGeoData(): - geom = geometries[geoDataRecord.getGeometryWKTindex()] + geom = geometries[geoDataRecord.getGeometryWKBindex()] retVal.append(PyGeometryData.PyGeometryData(geoDataRecord, geom)) return retVal @@ -125,7 +129,7 @@ class ThriftClientRouter(object): locNamesRequest.setRequestParameters(request) response = self._client.sendRequest(locNamesRequest) return response - + def getAvailableParameters(self, request): paramReq = GetAvailableParametersRequest() paramReq.setRequestParameters(request) diff --git a/rpms/awips2.core/Installer.yajsw/component.spec b/rpms/awips2.core/Installer.yajsw/component.spec deleted file mode 100644 index 99bb0fb18a..0000000000 --- a/rpms/awips2.core/Installer.yajsw/component.spec +++ /dev/null @@ -1,84 +0,0 @@ -%define _yajsw_version 11.11 - -# -# AWIPS II YAJSW Spec File -# - -Name: awips2-yajsw -Summary: AWIPS II yajsw Distribution -Version: %{_yajsw_version} -Release: %{_component_version}.%{_component_release}%{?dist} -Group: AWIPSII -BuildRoot: %{_build_root} -BuildArch: noarch -URL: N/A -License: N/A -Distribution: N/A -Vendor: Raytheon -Packager: Bryan Kowal - -AutoReq: no - -provides: awips2-yajsw -requires: awips2-java - -%description -AWIPS II yajsw Distribution - A custom compilation of yajsw ${_yajsw_version} used -by several AWIPS II components. - -# disable jar repacking -%global __os_install_post %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-java-repack-jars[[:space:]].*$!!g') - -%prep -# Ensure that a "buildroot" has been specified. -if [ "%{_build_root}" = "" ]; then - echo "ERROR: A BuildRoot has not been specified." - echo "FATAL: Unable to Continue ... Terminating." - exit 1 -fi - -if [ -d %{_build_root} ]; then - rm -rf %{_build_root} -fi -/bin/mkdir -p %{_build_root} -if [ $? -ne 0 ]; then - exit 1 -fi - -%install -DIST_DIR="%{_baseline_workspace}/foss/yajsw-%{_yajsw_version}/packaged" -YAJSW_SCRIPTS_DIR="%{_baseline_workspace}/rpms/awips2.core/Installer.yajsw/scripts" - -YAJSW_ZIP="yajsw-dist.zip" - -unzip ${DIST_DIR}/${YAJSW_ZIP} -d %{_build_root} -if [ $? -ne 0 ]; then - exit 1 -fi - -mkdir -p %{_build_root}/etc -if [ $? -ne 0 ]; then - exit 1 -fi -cp -rv ${YAJSW_SCRIPTS_DIR}/* %{_build_root}/etc -if [ $? -ne 0 ]; then - exit 1 -fi - -%clean -rm -rf ${RPM_BUILD_ROOT} - -%files -%defattr(644,awips,fxalpha,755) -%dir /awips2 -%dir /awips2/yajsw -/awips2/yajsw/*.jar -/awips2/yajsw/*.txt -%dir /awips2/yajsw/lib -/awips2/yajsw/lib/* - -%defattr(755,awips,fxalpha,755) -%dir /awips2/yajsw/scripts -/awips2/yajsw/scripts/*.sh - -%attr(744,root,root) /etc/profile.d/* diff --git a/rpms/awips2.core/Installer.yajsw/scripts/profile.d/awips2Yajsw.sh b/rpms/awips2.core/Installer.yajsw/scripts/profile.d/awips2Yajsw.sh deleted file mode 100644 index 1b911bbd3f..0000000000 --- a/rpms/awips2.core/Installer.yajsw/scripts/profile.d/awips2Yajsw.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -if [ -d /awips2/yajsw ]; then - YAJSW_INSTALL="/awips2/yajsw" -# Update The Environment - export YAJSW_HOME=${YAJSW_INSTALL} -fi diff --git a/rpms/build/common/lookupRPM.sh b/rpms/build/common/lookupRPM.sh index 14460653f0..cc33c943cb 100644 --- a/rpms/build/common/lookupRPM.sh +++ b/rpms/build/common/lookupRPM.sh @@ -256,7 +256,7 @@ function lookupRPM() return 0 fi if [ "${1}" = "awips2-yajsw" ]; then - export RPM_SPECIFICATION="${awips2_core_dir}/Installer.yajsw" + export RPM_SPECIFICATION="${installer_dir}/yajsw-11.11" return 0 fi