Merge branch 'master_14.1.1' into master_14.2.1

Conflicts:
	cave/build/static/common/cave/etc/gfe/userPython/textUtilities/headline/HazardsTable.py
	cave/com.raytheon.uf.viz.personalities.cave/src/com/raytheon/uf/viz/personalities/cave/workbench/VizWorkbenchAdvisor.java
	cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/formatterlauncher/StoreTransmitDlg.java
	cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/textformatter/CombinationsFileUtil.java
	cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/vtec/GFEVtecUtil.java
	cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/timeseries/TimeSeriesDisplayCanvas.java
	edexOsgi/com.raytheon.edex.plugin.gfe/utility/edex_static/base/gfe/isc/iscMosaic.py
	edexOsgi/com.raytheon.uf.edex.database/src/com/raytheon/uf/edex/database/dao/CoreDao.java
	rpms/awips2.core/Installer.ant/scripts/profile.d/awips2Ant.sh
	rpms/awips2.core/Installer.tools/component.spec

Change-Id: I457923a64d369b97af3d99fa6b25bf353a1f33f4

Former-commit-id: 410f956cff [formerly e7f2b6883d] [formerly 32bcf9d0d0] [formerly 410f956cff [formerly e7f2b6883d] [formerly 32bcf9d0d0] [formerly 14a082a4e9 [formerly 32bcf9d0d0 [formerly 4155b9785e0a82078db6805659146980cafc2aa7]]]]
Former-commit-id: 14a082a4e9
Former-commit-id: 8779564e3a [formerly 0135771eec] [formerly daf9f7ed0c92599e36d2d85d87483ca351cda108 [formerly d4ba9eba94]]
Former-commit-id: 55baedb811a56a020df3ba68f97e40ee6307fb4c [formerly 68e03bf02f]
Former-commit-id: 8a7af092f2
This commit is contained in:
Ron Anderson 2014-02-18 10:38:34 -06:00 committed by Steve Harris
commit c3b687b9a5
40 changed files with 1279 additions and 679 deletions

View file

@ -107,6 +107,40 @@
</max-perm>
</ini-substitutions>
</memory-setting>
<memory-setting>
<command-line-args>
<first-arg>-component</first-arg>
<second-arg>servicebackup</second-arg>
</command-line-args>
<ini-substitutions>
<max-memory>
<value>256M</value>
</max-memory>
<max-perm>
<value>128m</value>
</max-perm>
</ini-substitutions>
</memory-setting>
<memory-setting>
<command-line-args>
<first-arg>-perspective</first-arg>
<second-arg>National Centers</second-arg>
</command-line-args>
<ini-substitutions>
<max-memory>
<value>1536M</value>
</max-memory>
<max-perm>
<value>DEFAULT</value>
</max-perm>
</ini-substitutions>
</memory-setting>
</arch.x86>
<arch.x86_64>
@ -182,6 +216,40 @@
</max-perm>
</ini-substitutions>
</memory-setting>
</arch.x86_64>
<memory-setting>
<command-line-args>
<first-arg>-component</first-arg>
<second-arg>servicebackup</second-arg>
</command-line-args>
<ini-substitutions>
<max-memory>
<value>256M</value>
</max-memory>
<max-perm>
<value>128m</value>
</max-perm>
</ini-substitutions>
</memory-setting>
<memory-setting>
<command-line-args>
<first-arg>-perspective</first-arg>
<second-arg>National Centers</second-arg>
</command-line-args>
<ini-substitutions>
<max-memory>
<value>2048M</value>
</max-memory>
<max-perm>
<value>DEFAULT</value>
</max-perm>
</ini-substitutions>
</memory-setting>
</arch.x86_64>
</cave-memory-settings>

View file

@ -85,8 +85,10 @@ if [ -f /awips2/java/jre/lib/amd64/server/libjvm.so ]; then
fi
#run a loop for alertviz
while [ $exitVal -ne 0 ]
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

View file

@ -28,6 +28,8 @@
# cave sessions.
# Dec 05, 2013 #2590 dgilling Modified so gfeclient.sh can be wrapped
# around this script.
# Jan 24, 2014 #2739 bsteffen Log exit status
# Jan 30, 2014 #2593 bclement warns based on memory usage, fixed for INI files with spaces
#
#
@ -45,6 +47,8 @@ JAVA_INSTALL="/awips2/java"
PYTHON_INSTALL="/awips2/python"
export AWIPS_INSTALL_DIR="${CAVE_INSTALL}"
MAX_MEM_PROPORTION="0.9"
source ${CAVE_INSTALL}/caveUtil.sh
RC=$?
if [ ${RC} -ne 0 ]; then
@ -61,6 +65,9 @@ copyVizShutdownUtilIfNecessary
# delete any old disk caches in the background
deleteOldCaveDiskCaches &
# Enable core dumps
ulimit -c unlimited
export LD_LIBRARY_PATH=${JAVA_INSTALL}/lib:${PYTHON_INSTALL}/lib:$LD_LIBRARY_PATH
export LD_PRELOAD=libpython.so
if [[ -z "$CALLED_EXTEND_LIB_PATH" ]]; then
@ -109,20 +116,39 @@ export TEXTWS=`hostname | sed -e 's/lx/xt/g'`
hostName=`hostname -s`
if [[ $hostName =~ xt.* ]]; then
export IGNORE_NUM_CAVES=1
fi
# check number of running caves
if [[ -z $IGNORE_NUM_CAVES ]]; then
# free usually reports below on G threshold (11 instead of 12G), giving the 3 cave recommended in field
mem=( `free -g | grep "Mem:"` )
# get total memory on system in bytes
mem=( `free -b | grep "Mem:"` )
mem=${mem[1]}
let _maxCaves=mem/3
getPidsOfMyRunningCaves
if [[ "$_numPids" -ge "$_maxCaves" ]]; then
zenity --question --title "Max CAVE sessions already running" --text "$_numPids CAVE sessions already running. Starting more may impact system performance and stability.\n\nProceed?"
# get max amount of system memory used before we warn
memThreshold=$(echo "$mem * $MAX_MEM_PROPORTION" | bc)
# remove decimal
printf -v memThreshold "%.0f" "$memThreshold"
# get launcher.ini argument determined by user arguments
lookupINI "$@"
launcherRegex='--launcher.ini\s(.+\.ini)'
# default to cave.ini
targetIni="/awips2/cave/cave.ini"
if [[ $CAVE_INI_ARG =~ $launcherRegex ]]
then
targetIni="${BASH_REMATCH[1]}"
fi
# read max memory that could be used by this instance
memOfLaunchingCave=$(readMemFromIni "$targetIni")
# read total max memory of caves already running
getTotalMemOfRunningCaves
# add them together
_totalAfterStart=$(($memOfLaunchingCave + $_totalRunningMem))
if [[ "$_totalAfterStart" -ge "$memThreshold" ]]; then
# convert to megs for display
memOfLaunchingCave=$(($memOfLaunchingCave / $BYTES_IN_MB))
_totalRunningMem=$(($_totalRunningMem / $BYTES_IN_MB))
getPidsOfMyRunningCaves
memMsg="$_numPids CAVE applications already running with a combined max memory of ${_totalRunningMem}MB. "
memMsg+="The requested application has a max memory requirement of ${memOfLaunchingCave}MB. "
memMsg+="Starting may impact system performance and stability.\n\nProceed?"
zenity --question --title "Low Available Memory for Application" --text "$memMsg"
cancel="$?"
if [[ "$cancel" == "1" ]]; then
@ -172,49 +198,59 @@ if [ ! -d $LOGDIR ]; then
mkdir -p $LOGDIR
fi
export pid=$$
curTime=`date +%Y%m%d_%H%M%S`
LOGFILE="${LOGDIR}/${PROGRAM_NAME}_${curTime}_pid_${pid}_console.log"
export LOGFILE_CAVE="${LOGDIR}/${PROGRAM_NAME}_${curTime}_pid_${pid}_alertviz.log"
export LOGFILE_PERFORMANCE="${LOGDIR}/${PROGRAM_NAME}_${curTime}_pid_${pid}_perf.log"
# can we write to log directory
if [ -w ${LOGDIR} ]; then
touch ${LOGFILE}
fi
# 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.
(
export pid=`/bin/bash -c 'echo $PPID'`
# remove "-noredirect" flag from command-line if set so it doesn't confuse any
# commands we call later.
redirect="true"
USER_ARGS=()
while [[ $1 ]]
do
LOGFILE="${LOGDIR}/${PROGRAM_NAME}_${curTime}_pid_${pid}_console.log"
export LOGFILE_CAVE="${LOGDIR}/${PROGRAM_NAME}_${curTime}_pid_${pid}_alertviz.log"
export LOGFILE_PERFORMANCE="${LOGDIR}/${PROGRAM_NAME}_${curTime}_pid_${pid}_perf.log"
# can we write to log directory
if [ -w ${LOGDIR} ]; then
touch ${LOGFILE}
fi
# remove "-noredirect" flag from command-line if set so it doesn't confuse any
# commands we call later.
redirect="true"
USER_ARGS=()
while [[ $1 ]]
do
if [[ "$1" == "-noredirect" ]]
then
redirect="false"
redirect="false"
else
USER_ARGS+=("$1")
USER_ARGS+=("$1")
fi
shift
done
done
# Special instructions for the 64-bit jvm.
ARCH_ARGS=""
if [ -f /awips2/java/jre/lib/amd64/server/libjvm.so ]; then
ARCH_ARGS="-vm /awips2/java/jre/lib/amd64/server/libjvm.so"
fi
# Special instructions for the 64-bit jvm.
ARCH_ARGS=""
if [ -f /awips2/java/jre/lib/amd64/server/libjvm.so ]; then
ARCH_ARGS="-vm /awips2/java/jre/lib/amd64/server/libjvm.so"
fi
lookupINI "${USER_ARGS[@]}"
lookupINI "${USER_ARGS[@]}"
if [[ "${runMonitorThreads}" == "true" ]] ; then
# nohup to allow tar process to continue after user has logged out
nohup ${CAVE_INSTALL}/monitorThreads.sh $pid >> /dev/null 2>&1 &
fi
if [[ "${runMonitorThreads}" == "true" ]] ; then
# nohup to allow tar process to continue after user has logged out
nohup ${CAVE_INSTALL}/monitorThreads.sh $pid >> /dev/null 2>&1 &
fi
if [[ "${redirect}" == "true" ]] ; then
exec ${CAVE_INSTALL}/cave ${ARCH_ARGS} ${SWITCHES} "${CAVE_INI_ARG}" "${USER_ARGS[@]}" > ${LOGFILE} 2>&1
else
exec ${CAVE_INSTALL}/cave ${ARCH_ARGS} ${SWITCHES} "${CAVE_INI_ARG}" "${USER_ARGS[@]}" 2>&1 | tee ${LOGFILE}
fi
) &
pid=$!
LOGFILE="${LOGDIR}/${PROGRAM_NAME}_${curTime}_pid_${pid}_console.log"
logExitStatus $pid $LOGFILE
if [[ "${redirect}" == "true" ]] ; then
exec ${CAVE_INSTALL}/cave ${ARCH_ARGS} ${SWITCHES} ${CAVE_INI_ARG} "${USER_ARGS[@]}" > ${LOGFILE} 2>&1
else
exec ${CAVE_INSTALL}/cave ${ARCH_ARGS} ${SWITCHES} ${CAVE_INI_ARG} "${USER_ARGS[@]}" 2>&1 | tee ${LOGFILE}
fi

View file

@ -25,6 +25,10 @@
# Dec 05, 2013 #2593 rjpeter Fix getPidsOfMyRunningCaves
# Dec 05, 2013 #2590 dgilling Modified extendLibraryPath() to export a
# var if it's already been run.
# Jan 24, 2014 #2739 bsteffen Add method to log exit status of process.
# Jan 30, 2014 #2593 bclement extracted generic part of getPidsOfMyRunningCaves into forEachRunningCave
# added methods for reading max memory from .ini files
# fixes for INI files with spaces
#
#
@ -39,6 +43,10 @@ fi
# This script will be sourced by cave.sh.
export CAVE_INI_ARG=
BYTES_IN_KB=1024
BYTES_IN_MB=1048576
BYTES_IN_GB=1073741824
function lookupINI()
{
# Arguments:
@ -55,7 +63,7 @@ function lookupINI()
position=$(( $position + 1 ))
nextArg=${!position}
retrieveAssociatedINI ${arg} ${nextArg}
retrieveAssociatedINI ${arg} "${nextArg}"
RC=$?
if [ ${RC} -eq 0 ]; then
export CAVE_INI_ARG="--launcher.ini /awips2/cave/${ASSOCIATED_INI}"
@ -116,8 +124,8 @@ function copyVizShutdownUtilIfNecessary()
chmod a+x ${HOME}/.kde/shutdown/${VIZ_UTILITY_SCRIPT}
}
# returns _numPids and array _pids containing the pids of the currently running cave sessions.
function getPidsOfMyRunningCaves()
# takes a function as an argument and calls the function passing in the ps string of the process
function forEachRunningCave()
{
local user=`whoami`
local caveProcs=`ps -ef | grep -E "(/awips2/cave|/usr/local/viz)/cave " | grep -v "grep" | grep $user`
@ -125,17 +133,89 @@ function getPidsOfMyRunningCaves()
# preserve IFS and set it to line feed only
local PREV_IFS=$IFS
IFS=$'\n'
_numPids=0
# grab the pids for future use
for caveProc in $caveProcs
do
_pids[$_numPids]=`echo $caveProc | awk '{print $2}'`
let "_numPids+=1"
"$@" $caveProc
done
IFS=$PREV_IFS
}
# takes in ps string of cave process, stores pid in _pids and increments _numPids
function processPidOfCave()
{
_pids[$_numPids]=`echo $1 | awk '{print $2}'`
let "_numPids+=1"
}
# returns _numPids and array _pids containing the pids of the currently running cave sessions.
function getPidsOfMyRunningCaves()
{
_numPids=0
forEachRunningCave processPidOfCave
}
# takes a name of an ini file as an argument, echos the memory (in bytes) from file (or default)
function readMemFromIni()
{
local inifile="$1"
local mem
local unit
local regex='^[^#]*-Xmx([0-9]+)([bBkKmMgG])?'
# read ini file line by line looking for Xmx arg
while read -r line
do
if [[ $line =~ $regex ]]
then
mem=${BASH_REMATCH[1]}
unit=${BASH_REMATCH[2]}
break
fi
done < "$inifile"
# convert to bytes
case "$unit" in
[kK])
mem=$(($mem * $BYTES_IN_KB))
;;
[mM])
mem=$(($mem * $BYTES_IN_MB))
;;
[gG])
mem=$(($mem * $BYTES_IN_GB))
;;
esac
regex='^[0-9]+$'
if [[ ! $mem =~ $regex ]]
then
# we couldn't find a valid Xmx value
# java default is usually 1G
mem=1073741824
fi
echo $mem
}
# takes in ps string of cave process, reads Xmx from ini and adds bytes to _totalRunninMem
function addMemOfCave()
{
local inifile
# get ini file from process string
local regex='--launcher.ini\s(.+\.ini)'
if [[ $1 =~ $regex ]]
then
inifile="${BASH_REMATCH[1]}"
else
inifile="/awips2/cave/cave.ini"
fi
let "_totalRunningMem+=$(readMemFromIni "$inifile")"
}
# finds total max memory of running caves in bytes and places it in _totalRunningMem
function getTotalMemOfRunningCaves()
{
_totalRunningMem=0
forEachRunningCave addMemOfCave
}
function deleteOldCaveDiskCaches()
{
local curDir=`pwd`
@ -193,3 +273,28 @@ function deleteOldCaveDiskCaches()
cd $curDir
}
# log the exit status and time to a log file, requires 2 args pid and log file
function logExitStatus()
{
pid=$1
logFile=$2
trap 'kill $pid' SIGHUP SIGINT SIGQUIT SIGTERM
wait $pid
exitCode=$?
curTime=`date --rfc-3339=seconds`
echo Exited at $curTime with an exit status of $exitCode >> $logFile
# If a core file was generated attempt to save it to a better place
coreFile=core.$pid
if [ -f "$coreFile" ]; then
basePath="/data/fxa/cave"
hostName=`hostname -s`
hostPath="$basePath/$hostName/"
mkdir -p $hostPath
if [ -d "$hostPath" ]; then
cp $coreFile $hostPath
fi
fi
}

View file

@ -81,6 +81,7 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
* archive and category directory and
* implementation of compression.
* Oct 08, 2013 2442 rferrel Remove category directory.
* Feb 04, 2013 2270 rferrel Move HDF files to parent's directory.
*
* </pre>
*
@ -89,6 +90,10 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
*/
public class GenerateCaseDlg extends CaveSWTDialog {
/** Extension for HDF files. */
private static final String hdfExt = ".h5";
private final IUFStatusHandler statusHandler = UFStatus
.getHandler(GenerateCaseDlg.class);
@ -539,6 +544,11 @@ public class GenerateCaseDlg extends CaveSWTDialog {
new File(destination, file));
}
} else {
// DR 2270 bump HDF files up a directory.
if (destination.getName().endsWith(hdfExt)) {
destination = new File(destination.getParentFile()
.getParentFile(), destination.getName());
}
FileUtil.copyFile(source, destination);
destination.setLastModified(source.lastModified());
}
@ -652,6 +662,13 @@ public class GenerateCaseDlg extends CaveSWTDialog {
addTarFiles(file.listFiles());
}
} else {
// DR 2270 bump HDF files up a directory.
if (name.endsWith(hdfExt)) {
File destination = new File(file.getParentFile()
.getParentFile(), file.getName());
name = destination.getAbsolutePath().substring(
startRelativePath);
}
TarArchiveEntry entry = new TarArchiveEntry(file, name);
entry.setSize(file.length());
FileInputStream fileStream = null;

View file

@ -57,6 +57,7 @@ import com.raytheon.viz.ui.perspectives.VizPerspectiveListener;
* Jul 16, 2013 2158 bsteffen Allow VizGlobalsManager to work without
* accessing UI thread.
* Oct 15, 2013 2361 njensen Added startupTimer
* Jan 27, 2014 2744 njensen Add Local History pref back in
*
* </pre>
*
@ -192,8 +193,17 @@ public class VizWorkbenchAdvisor extends WorkbenchAdvisor {
for (IPreferenceNode root : topNodes) {
String rootId = root.getId();
if (rootId.equals("org.eclipse.ui.preferencePages.Workbench")) {
IPreferenceNode node = root
.findSubNode("org.eclipse.ui.preferencePages.Workspace");
if (node != null) {
node.remove("org.eclipse.ui.preferencePages.LinkedResources");
node.remove("org.eclipse.ui.preferencePages.BuildOrder");
IPreferenceNode localHistoryNode = node
.findSubNode("org.eclipse.ui.preferencePages.FileStates");
root.add(localHistoryNode);
root.remove("org.eclipse.ui.preferencePages.Workspace");
}
root.remove("org.eclipse.search.preferences.SearchPreferencePage");
root.remove("org.eclipse.ui.preferencePages.Workspace");
} else if (rootId.equals("org.python.pydev.prefs")) {
root.remove("org.python.pydev.ui.pythonpathconf.interpreterPreferencesPageJython");
root.remove("org.python.pydev.ui.pythonpathconf.interpreterPreferencesPageIronpython");
@ -325,7 +335,7 @@ public class VizWorkbenchAdvisor extends WorkbenchAdvisor {
startupTimer.stop();
System.out.println("Workbench startup time: "
+ startupTimer.getElapsedTime() + " ms");
}
}
}

View file

@ -1,5 +1,4 @@
#!/bin/bash
# CAVE startup script
# Note: CAVE will not run as 'root'
@ -25,8 +24,6 @@
# SOFTWARE HISTORY
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# Dec 04, 2013 #2589 dgilling Create command-line arg that controls
# xvfb initialization.
# Dec 05, 2013 #2593 rjpeter set IGNORE_NUM_CAVES
# Dec 05, 2013 #2590 dgilling Remove duplicated code and call to
# cave.sh.
@ -50,28 +47,12 @@ fi
PROGRAM_NAME="gfeclient"
# remove "-enablegl" flag from command-line if set so it doesn't confuse any
# commands we call later.
USER_ARGS=()
while [[ $1 ]]
do
if [ "$1" == "-enablegl" ]
then
ENABLEGL="true"
else
USER_ARGS+=("$1")
fi
shift
done
if [ -n "$ENABLEGL" ]
# if display not set
if [ -n "$DISPLAY" ]
then
# if display not set
if [ -n "$DISPLAY" ]
then
echo "Using Display set to $DISPLAY"
extendLibraryPath
else
else
echo "Display not set, creating offscreen x on port $$"
extendLibraryPath "-noX"
Xvfb :$$ -screen 0 1280x1024x24 &
@ -79,13 +60,12 @@ then
export DISPLAY="localhost:$$.0"
#don't use shader when no display set
SWITCHES="${SWITCHES} -no_shader"
fi
fi
export IGNORE_NUM_CAVES=1
source /awips2/cave/cave.sh -nosplash -noredirect -component gfeclient "${USER_ARGS[@]}" &
wait
source /awips2/cave/cave.sh -nosplash -noredirect -component gfeclient "$@" &
wait $!
if [ -n "$xvfb" ]
then

View file

@ -1,33 +1,5 @@
#!/bin/sh
# 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
# ------------ ---------- ----------- --------------------------
# Dec 04, 2013 #2589 dgilling Create command-line arg that controls
# xvfb initialization.
#
#
# get path to cave
path_to_script=`readlink -f $0`
RUN_FROM_DIR=`dirname $path_to_script`
@ -37,7 +9,6 @@ CAVE_DIR=/awips2/cave
# execute the runProcedure module
_GFECLI="${RUN_FROM_DIR}/gfeclient.sh"
_GFECLI_ARGS="-enablegl"
_MODULE="${CAVE_DIR}/etc/gfe/utility/PngWriter.py"
# quoting of '$@' is used to prevent command line interpretation
@ -46,6 +17,6 @@ then
echo "CAVE and/or gfeclient not installed on this workstation ..exiting"
exit 1
else
$_GFECLI $_GFECLI_ARGS $_MODULE "$@"
$_GFECLI $_MODULE "$@"
fi

View file

@ -29,7 +29,7 @@
# ------------ ---------- ----------- --------------------------
# 07/25/08 njensen Initial Creation.
# 09/05/13 #2329 randerso Added error handling
#
# 02/06/2014 #2591 randerso Changed log level to debug
#
import sys, traceback, os, time, LogStream
@ -55,7 +55,7 @@ def getCombinations(comboName):
with open(filename,'r') as fd:
filecontents = fd.read()
LogStream.logProblem("\nERROR loading combinations file: "+ comboName +
LogStream.logDebug("ERROR loading combinations file: "+ comboName +
"\nmd.__file__: " + md.__file__ +
"\ndir(md): " + str(dir(md)) +
"\n" + md.__file__ + " last modified: " + time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime(os.path.getmtime(md.__file__))) +

View file

@ -63,6 +63,7 @@ import com.raytheon.viz.gfe.textformatter.TextProductManager;
* DataManager instance.
* 05 SEP 2013 2329 randerso Added call to ZoneCombinerComp.applyZoneCombo when
* when run formatter button is clicked.
* 05 FEB 2014 2591 randerso Added dataManager to ZoneCombinerComp constructor
*
* </pre>
*
@ -592,7 +593,7 @@ public class ProductAreaComp extends Composite implements
*/
private void createZoneCombinerComp() {
zoneCombiner = new ZoneCombinerComp(stackGridComp, productTabCB,
productName, getTextProductManager());
productName, getTextProductManager(), this.dataMgr);
}
/**

View file

@ -152,6 +152,10 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
* 05/08/2013 #1842 dgilling Add alternate setProductText(), fix
* warnings.
* 09/03/2013 16534 ryu Refactor; sneak in a change for Ron (RM #1597).
* 01/06/2014 2649 dgilling Pass flag to StoreTransmitDlg to only
* update VTEC lines on products that
* aren't being corrected.
* 02/05/2014 17022 ryu Modified loadDraft() to fix merging of WMO heading and AWIPS ID.
*
* </pre>
*
@ -1139,7 +1143,7 @@ public class ProductEditorComp extends Composite implements
// prevent the launching of another dialog until the modal dialog is
// closed.
StoreTransmitDlg storeDlg = new StoreTransmitDlg(parent.getShell(),
showStore, this, transmissionCB, pid);
showStore, this, transmissionCB, pid, !textComp.isCorMode());
storeDlg.open();
}
}
@ -2386,10 +2390,13 @@ public class ProductEditorComp extends Composite implements
}
DraftProduct draft = DraftProduct.load(lf);
setTabColorFunc(productStateEnum.Finished);
productDefinition = draft.getProductDefinition();
clearProductText();
setProductText(draft.getProductText());
setTabColorFunc(productStateEnum.Finished);
setStatusText('R', productId + " draft loaded.");
if (productDefinition.get("brain") != null) {
brain();
String msg = "Your saved draft was loaded, but the draft is invalid "
@ -2877,7 +2884,7 @@ public class ProductEditorComp extends Composite implements
mb2.open();
return;
}
// Word-wrap the whole selection.
int curLine = styledText.getLineAtOffset(selectionRange.x);
int lastSelIdx = selectionRange.x + selectionRange.y - 1;

View file

@ -67,19 +67,24 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 21 APR 2008 ### lvenable Initial creation
* 19 FEB 2010 4132 ryu Product correction.
* 28May2010 2187 cjeanbap Added StdTextProductFactory
* functionality.
* 09 NOV 2012 1298 rferrel Changes for non-blocking dialog.
* 02apr2013 15564 mgamazaychikov Ensured awipsWanPil to be 10 characters space-padded long
* 08 MAY 2013 1842 dgilling Use VtecUtil to set product ETNs, fix
* Apr 21, 2008 ### lvenable Initial creation
* Feb 19, 2010 4132 ryu Product correction.
* May 28, 2010 2187 cjeanbap Added StdTextProductFactory
* functionality.
* Nov 09, 2012 1298 rferrel Changes for non-blocking dialog.
* Apr 02, 2013 15564 mgamazaychikov Ensured awipsWanPil to be 10 characters
* space-padded long
* May 08, 2013 1842 dgilling Use VtecUtil to set product ETNs, fix
* warnings.
* 07 Jun 2013 1981 mpduff Set user's id in OUPRequest as it is now a protected operation.
* 23 Oct 2013 1843 dgilling Ensure that dialog is always closed,
* Jun 07, 2013 1981 mduff Set user's id in OUPRequest as it is
* now a protected operation.
* Oct 23, 2013 1843 dgilling Ensure that dialog is always closed,
* even on failure, changes for error handling
* of intersite ETN assignment.
* 18 Dec 2013 2641 dgilling Support changes to GFEVtecUtil.getVtecLinesThatNeedEtn().
* Dec 18, 2013 2641 dgilling Support changes to GFEVtecUtil.getVtecLinesThatNeedEtn().
* Jan 06, 2014 2649 dgilling Make ETN assignment process optional.
* Feb 17, 2014 2774 dgilling Merge changes from 14.1 baseline to 14.2.
*
* </pre>
*
* @author lvenable
@ -142,17 +147,26 @@ public class StoreTransmitDlg extends CaveSWTDialog implements
private final String pid;
private final boolean updateVtec;
/**
* Constructor.
*
* @param parent
* Parent shell.
* @param storeDialog
* Store flag. True is store, false is transmit.
* @param editor
* Parent editor. Product will be updated in this editor after
* transmission.
* @param transmissionCB
* @param pid
* @param updateVtec
* Whether or not to update the ETNs of any VTEC lines in the
* product to be transmitted. Recommend setting this to false
* when correcting a previously transmitted product.
*/
public StoreTransmitDlg(Shell parent, boolean storeDialog,
ProductEditorComp editor, ITransmissionState transmissionCB,
String pid) {
String pid, boolean updateVtec) {
super(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL,
CAVE.DO_NOT_BLOCK);
@ -161,6 +175,7 @@ public class StoreTransmitDlg extends CaveSWTDialog implements
parentEditor = editor;
this.productText = editor.getProductText();
this.pid = pid;
this.updateVtec = updateVtec;
}
@Override
@ -344,114 +359,78 @@ public class StoreTransmitDlg extends CaveSWTDialog implements
// Store/Transmit the product...
if (!countdownThread.threadCancelled()) {
boolean retrieveEtnFailed = false;
try {
if (updateVtec) {
// With GFE VTEC products, it's possible to have multiple
// segments with NEW vtec action codes and the same phensig.
// For
// this reason, HazardsTable.py implemented a "cache" that
// would
// ensure all NEWs for the same phensig would be assigned
// the
// same ETN. This Map replicates that legacy behavior.
//
// This "cache" has two levels:
// 1. The first level is keyed by the hazard's phensig.
// 2. The second level is keyed by the valid period of the
// hazard.
// Effectively, making this a Map<Phensig, Map<ValidPeriod,
// ETN>>.
Map<String, List<VtecObject>> vtecsToAssignEtn = GFEVtecUtil
.initETNCache(productText);
Map<String, Map<TimeRange, Integer>> etnCache = new HashMap<String, Map<TimeRange, Integer>>();
List<VtecObject> vtecsToAssignEtn = GFEVtecUtil
.getVtecLinesThatNeedEtn(productText);
// With GFE VTEC products, it's possible to have multiple segments
// with
// NEW vtec action codes and the same phensig. For this reason,
// HazardsTable.py implemented a "cache" that would ensure all NEWs
// for
// the same phensig would be assigned the same ETN. This Map
// replicates
// that legacy behavior.
//
// This "cache" has two levels:
// 1. The first level is keyed by the hazard's phensig.
// 2. The second level is keyed by the valid period of the hazard.
// Effectively, making this a Map<Phensig, Map<ValidPeriod, ETN>>.
Map<String, Map<TimeRange, Integer>> etnCache = new HashMap<String, Map<TimeRange, Integer>>();
for (String phensig : vtecsToAssignEtn.keySet()) {
Map<TimeRange, Integer> l2EtnCache = new HashMap<TimeRange, Integer>();
List<VtecObject> vtecs = vtecsToAssignEtn.get(phensig);
for (VtecObject vtec : vtecsToAssignEtn) {
try {
GetNextEtnResponse serverResponse = GFEVtecUtil.getNextEtn(
vtec.getOffice(), vtec.getPhensig(), true, true);
if (!serverResponse.isOkay()) {
final VtecObject vtecToFix = vtec;
final boolean[] exitLoopContainer = { false };
final Exception[] exceptionContainer = { null };
final GetNextEtnResponse[] responseContainer = { serverResponse };
for (int i = 0; i < vtecs.size(); i++) {
VtecObject vtec = vtecs.get(i);
TimeRange validPeriod = new TimeRange(
vtec.getStartTime(), vtec.getEndTime());
Integer currentEtn = vtec.getSequence();
do {
getDisplay().syncExec(new Runnable() {
@Override
public void run() {
GetNextEtnResponse serverResponse = responseContainer[0];
ETNConfirmationDialog dlg = new ETNConfirmationDialog(
getShell(), serverResponse);
if (dlg.open() == ETNConfirmationDialog.OK) {
int etn = dlg.getProposedEtn();
statusHandler.info(String
.format("User confirmed ETN for %s: %04d",
serverResponse
.getPhensig(),
etn));
try {
GetNextEtnResponse followupResp = GFEVtecUtil.getNextEtn(
vtecToFix.getOffice(),
vtecToFix.getPhensig(),
true, true, true, etn);
responseContainer[0] = followupResp;
} catch (VizException e) {
exceptionContainer[0] = e;
exitLoopContainer[0] = true;
}
} else {
statusHandler
.info("User declined to fix ETN for %s",
serverResponse
.getPhensig());
exitLoopContainer[0] = true;
}
}
});
} while (!responseContainer[0].isOkay()
&& !exitLoopContainer[0]);
if (!responseContainer[0].isOkay()) {
String msg = "Unable to set ETN for phensig "
+ responseContainer[0].getPhensig()
+ "\nStatus: "
+ responseContainer[0].toString();
Exception e = exceptionContainer[0];
if (e == null) {
throw new VizException(msg);
// the first time we select a new, unique ETN, any
// other
// VTEC lines in the product that have the same
// phensig
// and an adjacent TimeRange can also re-use this
// ETN
if (currentEtn == 0) {
currentEtn = getNextEtn(vtec);
l2EtnCache.put(validPeriod, currentEtn);
} else {
throw new VizException(msg, e);
// BUT...once we've made our one pass through
// the
// product and re-used the ETN where
// appropriate, we
// should not check again
continue;
}
for (int j = i + 1; j < vtecs.size(); j++) {
VtecObject vtec2 = vtecs.get(j);
TimeRange validPeriod2 = new TimeRange(
vtec2.getStartTime(),
vtec2.getEndTime());
Integer currentEtn2 = vtec2.getSequence();
if ((currentEtn2 == 0)
&& (validPeriod2
.isAdjacentTo(validPeriod) || validPeriod2
.overlaps(validPeriod))) {
l2EtnCache.put(validPeriod2, currentEtn);
vtec2.setSequence(currentEtn);
}
}
} else {
serverResponse = responseContainer[0];
}
etnCache.put(phensig, l2EtnCache);
}
TimeRange validPeriod = new TimeRange(vtec.getStartTime()
.getTime(), vtec.getEndTime().getTime());
String phensig = vtec.getPhensig();
Map<TimeRange, Integer> etnsByTR = etnCache.get(phensig);
if (etnsByTR == null) {
etnsByTR = new HashMap<TimeRange, Integer>();
etnCache.put(phensig, etnsByTR);
}
etnsByTR.put(validPeriod, serverResponse.getNextEtn());
} catch (VizException e) {
statusHandler.handle(Priority.CRITICAL,
"Error setting ETNs for product", e);
retrieveEtnFailed = true;
VizApp.runAsync(new Runnable() {
@Override
public void run() {
sendTransmissionStatus(ConfigData.productStateEnum.Failed);
StoreTransmitDlg.this.parentEditor.revive();
}
});
break;
productText = GFEVtecUtil.finalizeETNs(productText,
etnCache);
}
}
if (!retrieveEtnFailed) {
productText = GFEVtecUtil.finalizeETNs(productText, etnCache);
VizApp.runSync(new Runnable() {
@ -476,6 +455,17 @@ public class StoreTransmitDlg extends CaveSWTDialog implements
}
});
} catch (VizException e) {
statusHandler.handle(Priority.CRITICAL,
"Error preparing product for transmission.", e);
VizApp.runAsync(new Runnable() {
@Override
public void run() {
sendTransmissionStatus(ConfigData.productStateEnum.Failed);
StoreTransmitDlg.this.parentEditor.revive();
}
});
}
}
@ -490,6 +480,65 @@ public class StoreTransmitDlg extends CaveSWTDialog implements
});
}
private Integer getNextEtn(VtecObject vtec) throws VizException {
GetNextEtnResponse serverResponse = GFEVtecUtil.getNextEtn(
vtec.getOffice(), vtec.getPhensig(), true, true);
if (!serverResponse.isOkay()) {
final VtecObject vtecToFix = vtec;
final boolean[] exitLoopContainer = { false };
final Exception[] exceptionContainer = { null };
final GetNextEtnResponse[] responseContainer = { serverResponse };
do {
getDisplay().syncExec(new Runnable() {
@Override
public void run() {
GetNextEtnResponse serverResponse = responseContainer[0];
ETNConfirmationDialog dlg = new ETNConfirmationDialog(
getShell(), serverResponse);
if (dlg.open() == ETNConfirmationDialog.OK) {
int etn = dlg.getProposedEtn();
statusHandler.info(String.format(
"User confirmed ETN for %s: %04d",
serverResponse.getPhensig(), etn));
try {
GetNextEtnResponse followupResp = GFEVtecUtil
.getNextEtn(vtecToFix.getOffice(),
vtecToFix.getPhensig(), true,
true, true, etn);
responseContainer[0] = followupResp;
} catch (VizException e) {
exceptionContainer[0] = e;
exitLoopContainer[0] = true;
}
} else {
statusHandler.info(
"User declined to fix ETN for %s",
serverResponse.getPhensig());
exitLoopContainer[0] = true;
}
}
});
} while (!responseContainer[0].isOkay() && !exitLoopContainer[0]);
if (!responseContainer[0].isOkay()) {
String msg = "Unable to set ETN for phensig "
+ responseContainer[0].getPhensig() + "\nStatus: "
+ responseContainer[0].toString();
Exception e = exceptionContainer[0];
if (e == null) {
throw new VizException(msg);
} else {
throw new VizException(msg, e);
}
} else {
serverResponse = responseContainer[0];
}
}
return serverResponse.getNextEtn();
}
/**
* Method to transmit the product.
*/
@ -597,4 +646,4 @@ public class StoreTransmitDlg extends CaveSWTDialog implements
transmissionCB.setTransmissionState(status);
}
}
}
}

View file

@ -58,8 +58,7 @@ import org.opengis.referencing.operation.TransformException;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GridLocation;
import com.raytheon.uf.common.dataplugin.gfe.exception.GfeException;
import com.raytheon.uf.common.localization.FileUpdatedMessage;
import com.raytheon.uf.common.localization.ILocalizationFileObserver;
import com.raytheon.uf.common.dataplugin.gfe.server.notify.CombinationsFileChangedNotification;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
@ -74,7 +73,9 @@ import com.raytheon.uf.viz.core.RGBColors;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.viz.gfe.Activator;
import com.raytheon.viz.gfe.core.DataManager;
import com.raytheon.viz.gfe.core.DataManagerUIFactory;
import com.raytheon.viz.gfe.core.internal.NotificationRouter.AbstractGFENotificationObserver;
import com.raytheon.viz.gfe.textformatter.CombinationsFileUtil;
import com.raytheon.viz.gfe.textformatter.TextProductManager;
import com.raytheon.viz.gfe.ui.zoneselector.ZoneSelector;
@ -99,6 +100,12 @@ import com.raytheon.viz.gfe.ui.zoneselector.ZoneSelector;
* not found to match A1.
* Dec 03, 2013 #2591 dgilling Ensure all change states to the combo
* file are handled.
* Jan 07, 2014 #2662 randerso Disabled zone combiner if no maps are selected
* Feb 04, 2014 #2591 randerso Forced reload of combinations file after save to ensure
* file is updated prior to running formatter
* Changed to use CombinationsFileChangedNotification instead of
* FileUpdatedMessage so we can ignore our own changes
* Moved retrieval of combinations file to CombinationsFileUtil.init
*
* </pre>
*
@ -106,8 +113,7 @@ import com.raytheon.viz.gfe.ui.zoneselector.ZoneSelector;
* @version 1.0
*
*/
public class ZoneCombinerComp extends Composite implements
ILocalizationFileObserver, IZoneCombiner {
public class ZoneCombinerComp extends Composite implements IZoneCombiner {
private final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(ZoneCombinerComp.class);
@ -190,6 +196,8 @@ public class ZoneCombinerComp extends Composite implements
protected TextProductManager textProductMgr;
protected DataManager dataManager;
protected String product;
protected boolean mapRequired;
@ -223,6 +231,8 @@ public class ZoneCombinerComp extends Composite implements
private List<String> mapNames;
private AbstractGFENotificationObserver<CombinationsFileChangedNotification> comboChangeListener;
private void initPreferences() {
IPreferenceStore prefs = Activator.getDefault().getPreferenceStore();
@ -246,7 +256,8 @@ public class ZoneCombinerComp extends Composite implements
* Product name.
*/
public ZoneCombinerComp(Composite parent, IProductTab callBack,
String productName, TextProductManager textProductMgr) {
String productName, TextProductManager textProductMgr,
DataManager dataManager) {
super(parent, SWT.NONE);
this.parent = parent;
@ -257,7 +268,13 @@ public class ZoneCombinerComp extends Composite implements
this.textProductMgr = textProductMgr;
mapRequired = textProductMgr.mapRequired(productName);
this.dataManager = dataManager;
mapRequired = this.textProductMgr.mapRequired(productName);
this.mapNames = getMapNames(productName);
if (mapNames.isEmpty()) {
mapRequired = false;
}
initPreferences();
init();
@ -267,15 +284,47 @@ public class ZoneCombinerComp extends Composite implements
LocalizationType.CAVE_STATIC, LocalizationLevel.BASE);
comboDir = pathMgr.getLocalizationFile(baseCtx,
CombinationsFileUtil.COMBO_DIR_PATH);
comboDir.addFileUpdatedObserver(this);
this.comboChangeListener = new AbstractGFENotificationObserver<CombinationsFileChangedNotification>(
CombinationsFileChangedNotification.class) {
@Override
public void notify(
CombinationsFileChangedNotification notificationMessage) {
comboFileChanged(notificationMessage);
}
};
this.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
comboDir.removeFileUpdatedObserver(ZoneCombinerComp.this);
ZoneCombinerComp.this.dataManager.getNotificationRouter()
.removeObserver(
ZoneCombinerComp.this.comboChangeListener);
}
});
dataManager.getNotificationRouter().addObserver(
this.comboChangeListener);
}
private List<String> getMapNames(String productName) {
Object obj = this.textProductMgr.getMapNameForCombinations(productName);
List<String> mapNames = new ArrayList<String>();
if (obj instanceof String) {
String s = (String) obj;
if (!s.isEmpty()) {
mapNames.add(s);
}
} else if (obj instanceof List<?>) {
@SuppressWarnings("unchecked")
List<String> list = (List<String>) obj;
mapNames.addAll(list);
}
return mapNames;
}
/**
@ -757,9 +806,14 @@ public class ZoneCombinerComp extends Composite implements
}
try {
String comboName = getCombinationsFileName();
CombinationsFileUtil.generateAutoCombinationsFile(
zoneSelector.getZoneGroupings(), getCombinationsFileName()
+ ".py");
zoneSelector.getZoneGroupings(), comboName);
// reload here forces file to be retrieved from server before
// allowing formatter to run
loadCombinationsFile(comboName);
applyButtonState(false);
} catch (Exception e) {
statusHandler.handle(Priority.PROBLEM, "Unable to save "
@ -790,21 +844,9 @@ public class ZoneCombinerComp extends Composite implements
}
Map<String, Integer> comboDict = loadCombinationsFile(comboName);
Object obj = textProductMgr.getMapNameForCombinations(productName);
mapNames = new ArrayList<String>();
if (obj instanceof String) {
String s = (String) obj;
if (!s.isEmpty()) {
mapNames.add(s);
}
} else if (obj instanceof List<?>) {
@SuppressWarnings("unchecked")
List<String> list = (List<String>) obj;
mapNames.addAll(list);
}
boolean singleComboOnly = false;
obj = textProductMgr.getDefinitionValue(productName, "singleComboOnly");
Object obj = textProductMgr.getDefinitionValue(productName,
"singleComboOnly");
if (obj != null) {
if (obj instanceof Integer) {
singleComboOnly = ((Integer) obj) != 0;
@ -915,17 +957,7 @@ public class ZoneCombinerComp extends Composite implements
public Map<String, Integer> loadCombinationsFile(String comboName) {
Map<String, Integer> dict = new HashMap<String, Integer>();
try {
File localFile = PathManagerFactory.getPathManager().getStaticFile(
FileUtil.join(CombinationsFileUtil.COMBO_DIR_PATH,
comboName + ".py"));
List<List<String>> combolist = new ArrayList<List<String>>();
if ((localFile != null) && localFile.exists()) {
combolist = CombinationsFileUtil.init(comboName);
} else {
// statusHandler
// .error("Combinations file not found: " + comboName);
}
List<List<String>> combolist = CombinationsFileUtil.init(comboName);
// reformat combinations into combo dictionary
int group = 1;
@ -941,8 +973,7 @@ public class ZoneCombinerComp extends Composite implements
return new HashMap<String, Integer>();
}
currentComboFile = FileUtil.join(CombinationsFileUtil.COMBO_DIR_PATH,
comboName + ".py");
currentComboFile = comboName;
return dict;
}
@ -977,20 +1008,14 @@ public class ZoneCombinerComp extends Composite implements
return colors;
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.localization.ILocalizationFileObserver#fileUpdated
* (com.raytheon.uf.common.localization.FileUpdatedMessage)
*/
@Override
public void fileUpdated(FileUpdatedMessage message) {
if (message.getFileName().equalsIgnoreCase(currentComboFile)) {
File file = new File(message.getFileName());
String comboName = file.getName().replace(".py", "");
private void comboFileChanged(CombinationsFileChangedNotification notif) {
String comboName = notif.getCombinationsFileName();
// if it's the same file and not changed by me update the combos
if (comboName.equalsIgnoreCase(currentComboFile)
&& !VizApp.getWsId().equals(notif.getWhoChanged())) {
statusHandler
.info("Received FileUpdatedMessage for combinations file: "
.info("Received CombinationsFileChangedNotification for combinations file: "
+ comboName);
Map<String, Integer> comboDict = loadCombinationsFile(comboName);
this.zoneSelector.updateCombos(comboDict);

View file

@ -51,6 +51,7 @@ import com.raytheon.uf.common.serialization.SerializationException;
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.util.FileUtil;
import com.raytheon.viz.gfe.core.DataManagerUIFactory;
import com.raytheon.viz.gfe.core.internal.IFPClient;
@ -68,6 +69,8 @@ import com.raytheon.viz.gfe.textformatter.CombinationsFileUtil.ComboData.Entry;
* Sep 05, 2013 #2329 randerso Moved genereateAutoCombinationsFile here
* Cleaned up error handling
* Sep 30, 2013 2361 njensen Use JAXBManager for XML
* Feb 05, 2014 #2591 randerso Forced retrieval of combinations file
* Implemented retry on error
*
* </pre>
*
@ -79,6 +82,8 @@ public class CombinationsFileUtil {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(CombinationsFileUtil.class);
private static final int MAX_TRIES = 2;
public static String COMBO_DIR_PATH = FileUtil.join("gfe", "combinations");
public static String SAVED_COMBO_DIR = FileUtil.join("gfe", "comboData");
@ -215,13 +220,20 @@ public class CombinationsFileUtil {
IPathManager pm = PathManagerFactory.getPathManager();
// retrieve combinations file if it's changed
LocalizationFile lf = pm.getStaticLocalizationFile(FileUtil.join(
COMBO_DIR_PATH, comboName + ".py"));
File pyFile;
try {
pyFile = lf.getFile(true);
} catch (LocalizationException e) {
throw new GfeException("Error retrieving combinations file: "
+ comboName, e);
}
LocalizationContext baseContext = pm.getContext(
LocalizationType.CAVE_STATIC, LocalizationLevel.BASE);
// Strip any path components from comboName
File comboFile = new File(comboName);
comboName = comboFile.getName();
String scriptPath = FileUtil.join(
GfePyIncludeUtil.getUtilitiesLF(baseContext).getFile()
.getPath(), "CombinationsInterface.py");
@ -230,21 +242,41 @@ public class CombinationsFileUtil {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("comboName", comboName);
PythonScript python = null;
for (int retryCount = 0; retryCount < MAX_TRIES; retryCount++) {
try {
python = new PythonScript(scriptPath, PyUtil.buildJepIncludePath(
python = new PythonScript(scriptPath,
PyUtil.buildJepIncludePath(
GfePyIncludeUtil.getCombinationsIncludePath(),
GfePyIncludeUtil.getCommonPythonIncludePath()),
CombinationsFileUtil.class.getClassLoader());
Object com = python.execute("getCombinations", map);
combos = (List<List<String>>) com;
// if successfully retrieved break out of the loop
break;
} catch (JepException e) {
// remove the .pyo file
new File(pyFile.getAbsolutePath() + "o").delete();
// if not last try, log and try again
if (retryCount < MAX_TRIES - 1) {
// log but don't pop up
statusHandler.handle(Priority.EVENTB,
"Error loading combinations file: " + comboName
+ ", retrying ", e);
}
// else throw exception
else {
throw new GfeException("Error loading combinations file: "
+ comboName, e);
}
} finally {
if (python != null) {
python.dispose();
}
}
}
return combos;
}

View file

@ -74,6 +74,7 @@ import com.vividsolutions.jts.geom.Envelope;
* ------------ ---------- ----------- --------------------------
* Aug 23, 2011 randerso Initial creation
* May 30, 2013 #2028 randerso Fixed date line issue with map display
* Jan 07, 2014 #2662 randerso Fixed limitZones (subDomainUGCs) support
*
* </pre>
*
@ -158,7 +159,6 @@ public abstract class AbstractZoneSelector extends PaneManager {
return this.zoomLevel;
}
// command to label the zones, calls setMap() to update the display
public void setLabelZones(boolean labelZones) {
if (labelZones == this.labelZones) {
return;
@ -182,7 +182,9 @@ public abstract class AbstractZoneSelector extends PaneManager {
return;
}
this.limitZoneNames = limitZones;
setMapInternal(this.mapRscList);
for (ZoneSelectorResource mapRsc : this.mapRscList) {
mapRsc.setLimitZones(limitZones);
}
}
/*
@ -287,7 +289,7 @@ public abstract class AbstractZoneSelector extends PaneManager {
.retrieveMap(bundlePath).getResourceData();
ZoneSelectorResource rsc = new ZoneSelectorResource(rscData,
new LoadProperties(), gloc);
new LoadProperties(), gloc, this.limitZoneNames);
mapRscList.add(rsc);
} catch (VizException e) {
statusHandler.handle(Priority.PROBLEM, "Error loading map: "

View file

@ -102,6 +102,7 @@ import com.vividsolutions.jts.io.WKBReader;
* Apr 10, 2013 #1854 randerso Fix for compatibility with PostGIS 2.0
* May 30, 2013 #2028 randerso Fixed date line issue with map display
* Jul 31, 2013 #2239 randerso Fixed scaling of maps that cross the date line
* Jan 07, 2014 #2662 randerso Fixed limitZones (subDomainUGCs) support
*
* </pre>
*
@ -230,6 +231,7 @@ public class ZoneSelectorResource extends DbMapResource {
int numPoints = 0;
int wfoPoints = 0;
List<String> limitZones = req.rsc.getLimitZones();
WKBReader wkbReader = new WKBReader();
for (int i = 0; i < mappedResult.getResultCount(); i++) {
if (canceled) {
@ -259,6 +261,12 @@ public class ZoneSelectorResource extends DbMapResource {
// TODO: what do we do with this?
// zoneName = "";
}
if (limitZones != null
&& !limitZones.contains(zoneName)) {
continue;
}
String wfo = (String) mappedResult
.getRowColumnValue(i, "wfo");
@ -532,6 +540,8 @@ public class ZoneSelectorResource extends DbMapResource {
private Map<String, ZoneInfo> zoneData;
private List<String> limitZones;
private RGB defaultFillColor;
private RGB outlineColor;
@ -559,9 +569,12 @@ public class ZoneSelectorResource extends DbMapResource {
/**
* @param data
* @param loadProperties
* @param gloc
* @param limitZones
*/
public ZoneSelectorResource(DbMapResourceData data,
LoadProperties loadProperties, GridLocation gloc) {
LoadProperties loadProperties, GridLocation gloc,
List<String> limitZones) {
super(data, loadProperties);
this.zoneData = new HashMap<String, ZoneInfo>();
this.geomFactory = new GeometryFactory();
@ -570,6 +583,7 @@ public class ZoneSelectorResource extends DbMapResource {
this.outlineColor = RGBColors.getRGBColor("white");
this.wfoOutlineColor = RGBColors.getRGBColor("yellow");
this.gloc = gloc;
this.limitZones = limitZones;
GeneralEnvelope env = new GeneralEnvelope(MapUtil.LATLON_PROJECTION);
env.setEnvelope(-180.0, -90.0, 180.0, 90.0);
@ -848,13 +862,10 @@ public class ZoneSelectorResource extends DbMapResource {
query.append(geometryField);
// add any additional columns
List<String> additionalColumns = new ArrayList<String>();
if (resourceData.getColumns() != null) {
for (ColumnDefinition column : resourceData.getColumns()) {
query.append(", ");
query.append(column);
additionalColumns.add(column.getName());
}
}
@ -915,6 +926,22 @@ public class ZoneSelectorResource extends DbMapResource {
return newShadedShape;
}
/**
* @return the limitZones
*/
public List<String> getLimitZones() {
return limitZones;
}
/**
* @param limitZones
* the limitZones to set
*/
public void setLimitZones(List<String> limitZones) {
this.limitZones = limitZones;
issueRefresh();
}
/**
* @param labelZones
*/
@ -1023,6 +1050,16 @@ public class ZoneSelectorResource extends DbMapResource {
query.append(resourceData.getGeomField());
query.append(")) as extent");
// add editarea column
if (resourceData.getColumns() != null) {
for (ColumnDefinition column : resourceData.getColumns()) {
if (column.getName().equalsIgnoreCase("editarea")) {
query.append(", ");
query.append(column);
}
}
}
// add the geometry table
query.append(" FROM ");
query.append(resourceData.getTable());
@ -1047,6 +1084,14 @@ public class ZoneSelectorResource extends DbMapResource {
WKBReader wkbReader = new WKBReader();
for (int i = 0; i < mappedResult.getResultCount(); i++) {
String zoneName = (String) mappedResult.getRowColumnValue(
i, "editarea");
if (this.limitZones != null
&& !this.limitZones.contains(zoneName)) {
continue;
}
byte[] b = (byte[]) mappedResult.getRowColumnValue(i,
"extent");
if (b != null) {

View file

@ -22,6 +22,8 @@ package com.raytheon.viz.gfe.vtec;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
@ -60,6 +62,7 @@ import com.raytheon.viz.texteditor.util.VtecUtil;
* phensig but disjoint TimeRanges.
* Dec 18, 2013 #2641 dgilling Force ordering of items returned by
* getVtecLinesThatNeedEtn().
* Feb 05, 2014 #2774 dgilling Additional correction to previous fix.
*
* </pre>
*
@ -78,6 +81,24 @@ public class GFEVtecUtil {
public static final Collection<String> IGNORE_NATIONAL_ETN = ImmutableSet
.copyOf(GFEVtecConfig.getInstance().getSitesIgnoreNationalEtn());
private static final Comparator<VtecObject> VTEC_COMPARATOR = new Comparator<VtecObject>() {
@Override
public int compare(VtecObject vtec1, VtecObject vtec2) {
TimeRange tr1 = new TimeRange(vtec1.getStartTime(),
vtec1.getEndTime());
TimeRange tr2 = new TimeRange(vtec2.getStartTime(),
vtec2.getEndTime());
int retVal = tr1.getStart().compareTo(tr2.getStart());
if (retVal == 0) {
retVal = tr1.getEnd().compareTo(tr2.getEnd());
}
return retVal;
}
};
/**
* A private constructor so that Java does not attempt to create one for us.
* As this class should not be instantiated, do not attempt to ever call
@ -194,12 +215,12 @@ public class GFEVtecUtil {
* @return A <code>Set</code> of <code>VtecObject</code>s that need to have
* a new ETN assigned to them.
*/
public static List<VtecObject> getVtecLinesThatNeedEtn(String product) {
public static Map<String, List<VtecObject>> initETNCache(String product) {
if (StringUtil.isEmptyString(product)) {
return Collections.emptyList();
return Collections.emptyMap();
}
List<VtecObject> phensigs = new ArrayList<VtecObject>();
Map<String, List<VtecObject>> cache = new HashMap<String, List<VtecObject>>();
Matcher vtecMatcher = VtecUtil.VTEC_REGEX.matcher(product);
while (vtecMatcher.find()) {
@ -208,11 +229,24 @@ public class GFEVtecUtil {
&& ((!NATIONAL_PHENSIGS.contains(vtec.getPhensig())) || (IGNORE_NATIONAL_ETN
.contains(vtec.getOffice()) && TROPICAL_PHENSIGS
.contains(vtec.getPhensig())))) {
phensigs.add(vtec);
List<VtecObject> vtecsForPhensig = cache.get(vtec.getPhensig());
if (vtecsForPhensig == null) {
vtecsForPhensig = new ArrayList<VtecObject>();
}
vtec.setSequence(0);
vtecsForPhensig.add(vtec);
cache.put(vtec.getPhensig(), vtecsForPhensig);
}
}
return phensigs;
for (String phensig : cache.keySet()) {
List<VtecObject> vtecsByTimeOrder = new ArrayList<VtecObject>(
cache.get(phensig));
Collections.sort(vtecsByTimeOrder, VTEC_COMPARATOR);
cache.put(phensig, vtecsByTimeOrder);
}
return cache;
}
/**
@ -244,46 +278,12 @@ public class GFEVtecUtil {
&& ((!NATIONAL_PHENSIGS.contains(vtec.getPhensig())) || (IGNORE_NATIONAL_ETN
.contains(vtec.getOffice()) && TROPICAL_PHENSIGS
.contains(vtec.getPhensig())))) {
// With GFE VTEC products, it's possible to have multiple
// segments with
// NEW vtec action codes and the same phensig. For this reason,
// HazardsTable.py implemented a "cache" that would ensure all
// NEWs for
// the same phensig would be assigned the same ETN. This Map
// replicates
// that legacy behavior.
//
// This "cache" has two levels:
// 1. The first level is keyed by the hazard's phensig.
// 2. The second level is keyed by the valid period of the
// hazard.
// Effectively, making this a Map<Phensig, Map<ValidPeriod,
// ETN>>.
// Some more clarification on the ETN assignment behavior: all
// NEW VTEC lines with the same phensig should be assigned the
// same ETN if the hazards' valid periods are adjacent or
// overlapping.
// If there's a discontinuity in TimeRanges we increment to the
// next ETN.
Integer newEtn = null;
String cacheKey = vtec.getPhensig();
String phensig = vtec.getPhensig();
TimeRange validPeriod = new TimeRange(vtec.getStartTime()
.getTime(), vtec.getEndTime().getTime());
Map<TimeRange, Integer> etnsByTR = etnCache.get(cacheKey);
if (etnsByTR != null) {
newEtn = etnsByTR.get(validPeriod);
for (TimeRange tr : etnsByTR.keySet()) {
if ((validPeriod.isAdjacentTo(tr))
|| (validPeriod.overlaps(tr))) {
vtec.setSequence(newEtn);
break;
}
}
}
Integer newEtn = etnCache.get(phensig).get(validPeriod);
vtec.setSequence(newEtn);
}
vtecMatcher
.appendReplacement(
finalOutput,
@ -293,4 +293,4 @@ public class GFEVtecUtil {
vtecMatcher.appendTail(finalOutput);
return finalOutput.toString();
}
}
}

View file

@ -34,6 +34,7 @@ import com.raytheon.viz.hydrocommon.data.GageData.ThreatIndex;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 21, 2008 mpduff Initial creation
* Feb 03, 2014 16843 lbousaidi add a check for index OutOfBoundsException
*
* </pre>
*
@ -101,8 +102,9 @@ public class PDCFindBasis {
} else {
currentLid = fcstReportList.get(fcstIndex).getLid();
}
} else if (obsReportList.get(obsIndex) != null) {
currentLid = obsReportList.get(obsIndex).getLid();
} else if ((obsIndex< obsReportList.size()) && (obsReportList
.get(obsIndex) != null)) {
currentLid = obsReportList.get(obsIndex).getLid();
} else {
currentLid = fcstReportList.get(fcstIndex).getLid();
}

View file

@ -138,8 +138,9 @@ import com.raytheon.viz.hydrocommon.util.DbUtils;
* 16 Jan 2013 15695 wkwock Fix popup menu
* 24 Apr 2013 1921 mpduff Fix zoom reset to only reset the "active" graph
* 06 May 2013 1976 mpduff Refactored Hydro time series data access.
* 29 May 2013 2016 mpduff Fix TS Toggle Traces.
* 29 May 2013 2016 mpduff Fix TS Toggle Traces.
* 05 Sep 2013 #2332 lvenable Fixed memory leaks.
* 24 Jan 2013 15959 lbousaidi Swap the corner points of the bounding box when zooming.
* @author lvenable
* @version 1.0
*
@ -1241,7 +1242,13 @@ public class TimeSeriesDisplayCanvas extends TimeSeriesGraphCanvas implements
}
Date xMin = pixel2x(gd, rubberBandX1 - GRAPHBORDER_LEFT);
Date xMax = pixel2x(gd, rubberBandX2 - GRAPHBORDER_LEFT);
//Swap the corner points of the bounding box when zooming
if (xMin.after(xMax)) {
Date xtmp;
xtmp= xMin;
xMin=xMax;
xMax=xtmp;
}
gd.setXMin(xMin);
gd.setXMax(xMax);
gd.setX(gd.getXMax().getTime() - gd.getXMin().getTime());
@ -1256,7 +1263,13 @@ public class TimeSeriesDisplayCanvas extends TimeSeriesGraphCanvas implements
if (ymin < gd.getYmin()) {
ymin = gd.getYmin();
}
//Swap the corner points of the bounding box when zooming
if (ymin > ymax) {
double ytmp;
ytmp= ymin;
ymin=ymax;
ymax=ytmp;
}
gd.setYmin(ymin);
gd.setYmax(ymax);
gd.setY2(gd.getYmax2() - gd.getYmin2());

View file

@ -38,7 +38,8 @@ import com.raytheon.viz.mpe.util.DailyQcUtils.Station;
* ------------ ---------- ----------- --------------------------
* Mar 11, 2009 snaples Initial creation
* May 02, 2011 8962 snaples Added render24hrPcpUsingFour6hr() method
*
* Jan 10, 2014 16976 cgobs Fixed issue on line 153.
* Changed pcp.value[row][col] to pcp.value[col][row]
* </pre>
*
* @author snaples
@ -149,7 +150,7 @@ public class RenderPcp {
for (int col = 0; col < hrap_grid.maxi; col++) {
for (int row = 0; row < hrap_grid.maxj; row++) {
value = pcp.value[row][col];
value = pcp.value[col][row];
if (value > maxValue) {
maxValue = value;

View file

@ -38,7 +38,8 @@ import com.raytheon.viz.mpe.util.DailyQcUtils.Station;
* ------------ ---------- ----------- --------------------------
* Mar 11, 2009 snaples Initial creation
* May 02, 2011 8962 snaples Added render24hrPcpUsingFour6hr() method
*
* Jan 10, 2014 16976 cgobs Fixed issue on line 290.
* Changed pcp.value[row][col] to pcp.value[col][row]
* </pre>
*
* @author snaples
@ -286,7 +287,7 @@ public class RenderPcpBlocking {
* not estimate precipitation for it.
*/
if (hrap_grid.owner[col][row] == -1) {
pcp.value[row][col] = 0;
pcp.value[col][row] = 0;
continue;
}
@ -308,7 +309,7 @@ public class RenderPcpBlocking {
resultingPrecipValue = 0.0;
}
// pcp.value[row][col] is the value of grid,
// pcp.value[col][row] is the value of grid,
// so we don't need to estimate a value for [row][col]
}

View file

@ -34,6 +34,7 @@ import java.util.regex.Pattern;
* ------------ ---------- ----------- --------------------------
* Oct 14, 2009 bwoodle Initial creation
* May 08, 2013 #1842 dgilling Add getPhensig() method.
* Feb 17, 2014 #2774 dgilling Added toString() for debugging
*
* </pre>
*
@ -315,6 +316,11 @@ public class VtecObject {
VtecUtil.formatVtecTime(this.endTime));
}
@Override
public String toString() {
return generateVtec();
}
/*
* (non-Javadoc)
*/

View file

@ -34,6 +34,9 @@ import org.opengis.metadata.spatial.PixelOrientation;
import org.opengis.referencing.operation.MathTransform;
import com.raytheon.uf.common.dataplugin.warning.util.GeometryUtil;
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.viz.core.IExtent;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.viz.core.contours.util.ContourContainer;
@ -76,6 +79,7 @@ import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory;
* 10/01/2013 DR 16632 Qinglu Lin Fixed the bug in for loop range.
* 10/17/2013 DR 16632 Qinglu Lin Updated removeOverlaidLinesegments().
* 10/18/2013 DR 16632 Qinglu Lin Catch exception thrown when coords length is less than 4 and doing createLinearRing(coords).
* 01/09/2014 DR 16974 D. Friedman Improve followup redraw-from-hatched-area polygons.
* </pre>
*
* @author mschenke
@ -83,6 +87,8 @@ import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory;
*/
public class PolygonUtil {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(PolygonUtil.class);
private WarngenLayer layer;
@ -114,6 +120,39 @@ public class PolygonUtil {
Geometry origWarningArea, Polygon oldWarningPolygon) throws VizException {
float[][] contourAreaData = toFloatData(origWarningArea);
/* If we have an oldWarningPolygon, we can take a shortcut and see
* if the intersection of the current polygon and the old polygon
* generates the same input to the contouring algorithm as the current
* hatched area. If it does, that intersection can be used instead of
* generating a new contour.
*/
if (oldWarningPolygon != null) {
try {
Geometry intersection = origPolygon.intersection(oldWarningPolygon);
if (intersection instanceof Polygon) {
Polygon polygonIntersection = (Polygon) intersection;
if (polygonIntersection.isValid() &&
polygonIntersection.getNumInteriorRing() == 0 &&
polygonIntersection.getNumPoints() - 1 <= maxVertices) {
/*
* Use buildIdealArea to clip the current polygon against the old
* polygon (actually oldWarningArea) and the CWA, using the same
* coordinate transformations that are used to generate
* origWarningArea.
*/
Geometry comparableIntersection = layer.buildIdealArea(origPolygon);
float[][] interAreaData = toFloatData(comparableIntersection);
if (areasEqual(interAreaData, contourAreaData)) {
return polygonIntersection;
}
}
}
} catch (RuntimeException e) {
statusHandler.handle(Priority.WARN,
"Error while using simple polygon redraw method. Will continue using contouring method.", e);
}
}
// Create contouring configuration
FortConConfig config = new FortConConfig();
config.generateMaxes = false;

View file

@ -194,6 +194,7 @@ import com.vividsolutions.jts.io.WKTReader;
* 10/21/2013 DR 16632 D. Friedman Modify areaPercent exception handling. Fix an NPE.
* Use A1 hatching behavior when no county passes the inclusion filter.
* 10/29/2013 DR 16734 D. Friedman If redraw-from-hatched-area fails, don't allow the pollygon the be used.
* 01/09/2014 DR 16974 D. Friedman Improve followup redraw-from-hatched-area polygons.
* </pre>
*
* @author mschenke
@ -2934,41 +2935,11 @@ public class WarngenLayer extends AbstractStormTrackResource {
state.snappedToArea = false;
if (areaHatcher != null) {
Polygon polygon = state.getWarningPolygon();
polygon = tryToIntersectWithOriginalPolygon(polygon);
areaHatcher.hatchArea(polygon, state.getWarningArea(),
state.getOldWarningPolygon());
}
}
/**
* Try to determine the intersection of the given polygon with the original
* warning polygon. If there is no original polygon, if the result of the
* intersection is not a single polygon, or if a problem occurs, just return
* the original polygon. The purpose of this is to pass the polygon that
* best represents the user's intent to the polygon redrawing algorithm.
*/
private Polygon tryToIntersectWithOriginalPolygon(Polygon polygon) {
if (state.getOldWarningPolygon() != null) {
try {
Geometry g = polygon.intersection(state.getOldWarningPolygon());
Polygon newPolygon = null;
if (g instanceof Polygon) {
newPolygon = (Polygon) g;
} else if (g instanceof GeometryCollection
&& g.getNumGeometries() == 1
&& g.getGeometryN(0) instanceof Polygon) {
newPolygon = (Polygon) g.getGeometryN(0);
}
if (newPolygon != null && newPolygon.isValid()) {
polygon = newPolygon;
}
} catch (TopologyException e) {
// ignore
}
}
return polygon;
}
private Collection<GeospatialData> getDataWithFips(String fips) {
List<GeospatialData> data = new ArrayList<GeospatialData>();
for (GeospatialData d : geoData.features) {
@ -3252,4 +3223,40 @@ public class WarngenLayer extends AbstractStormTrackResource {
}
}
}
/**
* Like buildArea, but does not take inclusion filters into account. Also
* returns a Geometry in lat/lon space.
* @param inputArea
* @return
*/
public Geometry buildIdealArea(Geometry inputArea) {
Geometry localHatchedArea = latLonToLocal(inputArea);
Geometry oldWarningArea = latLonToLocal(state.getOldWarningArea());
Geometry newHatchedArea = null;
for (GeospatialData f : geoData.features) {
// get the geometry of the county and make sure it intersects
// with our hatched area
PreparedGeometry prepGeom = (PreparedGeometry) f.attributes
.get(GeospatialDataList.LOCAL_PREP_GEOM);
Geometry intersection = null;
try {
// Get intersection between county and hatched boundary
intersection = GeometryUtil.intersection(localHatchedArea, prepGeom);
if (oldWarningArea != null) {
intersection = GeometryUtil.intersection(intersection,
oldWarningArea);
}
} catch (RuntimeException e) {
continue;
// This is a workaround for JTS 1.7.1
}
newHatchedArea = union(newHatchedArea, intersection);
}
Geometry result = newHatchedArea != null ? newHatchedArea : new GeometryFactory()
.createGeometryCollection(new Geometry[0]);
return localToLatLon(result);
}
}

View file

@ -20,21 +20,23 @@
package com.raytheon.edex.plugin.gfe.server.handler;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import com.raytheon.edex.plugin.gfe.util.SendNotifications;
import com.raytheon.uf.common.dataplugin.gfe.request.SaveCombinationsFileRequest;
import com.raytheon.uf.common.dataplugin.gfe.server.message.ServerResponse;
import com.raytheon.uf.common.dataplugin.gfe.server.notify.CombinationsFileChangedNotification;
import com.raytheon.uf.common.localization.FileUpdatedMessage;
import com.raytheon.uf.common.localization.FileUpdatedMessage.FileChangeType;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
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.serialization.comm.IRequestHandler;
import com.raytheon.uf.common.util.FileUtil;
@ -55,6 +57,7 @@ import com.raytheon.uf.edex.core.EDEXUtil;
* May 16, 2011 dgilling Initial creation
* Dec 02, 2013 #2591 dgilling Only send notification after Writer is
* flushed/closed.
* Feb 05, 2014 #2591 Added CombinationFileChangedNotification
*
* </pre>
*
@ -78,19 +81,22 @@ public class SaveCombinationsFileHandler implements
@Override
public ServerResponse<Object> handleRequest(
SaveCombinationsFileRequest request) throws Exception {
String siteID = request.getSiteID();
IPathManager pm = PathManagerFactory.getPathManager();
LocalizationContext localization = pm.getContextForSite(
LocalizationType.CAVE_STATIC, request.getSiteID());
LocalizationType.CAVE_STATIC, siteID);
File localFile = pm.getFile(localization,
FileUtil.join(COMBO_FILE_DIR, request.getFileName()));
boolean isAdded = (!localFile.exists());
String comboName = request.getFileName();
String fileName = FileUtil.join(COMBO_FILE_DIR, comboName) + ".py";
LocalizationFile lf = pm.getLocalizationFile(localization, fileName);
boolean isAdded = (!lf.exists());
Writer outWriter = null;
try {
outWriter = new BufferedWriter(new FileWriter(localFile));
outWriter = new BufferedWriter(new OutputStreamWriter(
lf.openOutputStream()));
String zoneComments = "\n# Automatically generated combinations file\n# "
+ request.getFileName() + "\n\nCombinations = [\n";
+ comboName + "\n\nCombinations = [\n";
outWriter.write(zoneComments);
NumberFormat df = new DecimalFormat("00");
@ -115,20 +121,25 @@ public class SaveCombinationsFileHandler implements
outWriter.close();
}
}
lf.save();
// placing the notification code here ensures we only send the
// notification on a successful file write operation. Otherwise we would
// have thrown an IOException and never gotten to this portion of the
// request handler.
// TODO: remove sending of FileUpdateMessage after DR #2768 is fixed
FileChangeType changeType = isAdded ? FileChangeType.ADDED
: FileChangeType.UPDATED;
EDEXUtil.getMessageProducer().sendAsync(
"utilityNotify",
new FileUpdatedMessage(localization, FileUtil.join(
COMBO_FILE_DIR, request.getFileName()), changeType,
localFile.lastModified()));
new FileUpdatedMessage(localization, fileName, changeType, lf
.getTimeStamp().getTime()));
CombinationsFileChangedNotification notif = new CombinationsFileChangedNotification(
comboName, request.getWorkstationID(), siteID);
SendNotifications.send(notif);
return new ServerResponse<Object>();
}
}

View file

@ -85,7 +85,7 @@ from com.raytheon.uf.edex.database.cluster import ClusterTask
# 11/05/13 2517 randerso Restructured logging so it coulde be used by WECache
# Changed WECache to limit the number of cached grids kept in memory
# 01/09/14 16952 randerso Fix regression made in #2517 which caused errors with overlapping grids
#
# 02/04/14 17042 ryu Check in changes for randerso.
#
BATCH_DELAY = 0.0
@ -1144,7 +1144,7 @@ class IscMosaic:
self.__storeGrid(m[1], oldGrid)
self.__dbGrid = None
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
# Get Incoming netCDF file grid valid times
# netCDFfile, var is the netCDF variable
#-------------------------------------------------------------------------
@ -1526,7 +1526,7 @@ class IscMosaic:
smsg, oldEntry, keyentry, ",".join(changedReasons))
msg = "%s %s %s [%s] -> [%s] (%s)" % \
self.__siteID, parmName, printShortTR(tr), oldEntry, keyentry, ",".join(changedReasons)
(self.__siteID, parmName, printShortTR(tr), oldEntry, keyentry, ",".join(changedReasons))
self.__adjDataMsg.append(msg)
key[idx] = keyentry #store back into list
@ -1626,7 +1626,7 @@ class IscMosaic:
smsg, oldEntry, keyentry, ",".join(changedReasons))
msg = "%s %s %s [%s] -> [%s] (%s)" % \
self.__siteID, parmName, printShortTR(tr), oldEntry, keyentry, ",".join(changedReasons)
(self.__siteID, parmName, printShortTR(tr), oldEntry, keyentry, ",".join(changedReasons))
self.__adjDataMsg.append(msg)

View file

@ -45,6 +45,10 @@ import com.raytheon.uf.common.dataplugin.binlightning.impl.LtgStrikeType;
* ------------ ---------- ----------- --------------------------
* Dec 15, 2009 3983 jsanchez Initial creation
* Feb 27, 2013 DCS 152 jgerth/elau Support for WWLLN
* Jan 27, 2014 DR 16080 M.Porricelli Changed LIGHTNING_PTRN_A
* to accommodate AK BLM
* lgtng intensities -999 to
* 999
*
* </pre>
*
@ -61,7 +65,10 @@ public class TextLightningParser {
private List<LightningStrikePoint> reports;
// 03/23/2010 13:35:01 72.00 -157.00 -14 1
private static final String LIGHTNING_PTRN_A = "(\\d{2,2}/\\d{2,2}/\\d{4,4}) (\\d{2,2}:\\d{2,2}:\\d{2,2})\\s{1,}(\\d{1,2}.\\d{2,2})\\s{1,}( |-\\d{1,3}.\\d{2,2})\\s{1,}( |-\\d{1,2})\\s{1,}(\\d{1,2})";
// 03/23/2010 13:35:01 72.00 -157.00 14 1
// 03/23/2010 13:35:01 72.00 -157.00 -142 1
// 03/23/2010 13:35:01 72.00 -157.00 142 1
private static final String LIGHTNING_PTRN_A = "(\\d{2,2}/\\d{2,2}/\\d{4,4}) (\\d{2,2}:\\d{2,2}:\\d{2,2})\\s{1,}(\\d{1,2}.\\d{2,2})\\s{1,}( |-\\d{1,3}.\\d{2,2})\\s{1,}(-?\\d{1,3})\\s{1,}(\\d{1,2})";
private static final Pattern LTG_PTRN_A = Pattern.compile(LIGHTNING_PTRN_A);
// 10:03:24:13:35:00.68 72.000 157.000 -14.2 1

View file

@ -189,6 +189,15 @@ public class ArchiveConfigManager {
public Collection<ArchiveConfig> getArchives() {
String fileName = ArchiveConstants.selectFileName(Type.Retention, null);
SelectConfig selections = loadSelection(fileName);
List<String> emptySelection = new ArrayList<String>(0);
// Clear old selections.
for (ArchiveConfig archive : archiveMap.values()) {
for (CategoryConfig category : archive.getCategoryList()) {
category.setSelectedDisplayNames(emptySelection);
}
}
if ((selections != null) && !selections.isEmpty()) {
for (ArchiveSelect archiveSelect : selections.getArchiveList()) {
String archiveName = archiveSelect.getName();
@ -325,7 +334,8 @@ public class ArchiveConfigManager {
Map<CategoryConfig, CategoryFileDateHelper> helperMap = new HashMap<CategoryConfig, CategoryFileDateHelper>();
for (CategoryConfig category : archive.getCategoryList()) {
CategoryFileDateHelper helper = new CategoryFileDateHelper(category);
CategoryFileDateHelper helper = new CategoryFileDateHelper(
archiveRootDirPath, category);
helperMap.put(category, helper);
}
@ -470,13 +480,8 @@ public class ArchiveConfigManager {
if (file.isDirectory()) {
purgeCount += purgeDir(file,
FileFilterUtils.trueFileFilter());
if (file.list().length == 0) {
purgeCount += purgeDir(file,
FileFilterUtils.trueFileFilter());
}
} else {
purgeCount += deleteFile(file);
}
purgeCount += deleteFile(file);
}
} else if (file.isDirectory()) {
purgeCount += purgeDir(file, defaultTimeFilter,

View file

@ -72,6 +72,7 @@ import javax.xml.bind.annotation.XmlRootElement;
* ------------ ---------- ----------- --------------------------
* May 1, 2013 1966 rferrel Initial creation
* Aug 03, 2013 2224 rferrel Changes to include DataSet.
* Jan 09, 2014 2603 rferrel Fix bug in setSelectedDisplayNames
*
* </pre>
*
@ -155,7 +156,7 @@ public class CategoryConfig implements Comparable<CategoryConfig> {
public void setSelectedDisplayNames(
Collection<String> selectedDisplayNameList) {
selectedDisplayNames.clear();
selectedDisplayNameList.addAll(selectedDisplayNameList);
selectedDisplayNames.addAll(selectedDisplayNameList);
}
public void addSelectedDisplayName(String displayName) {

View file

@ -125,15 +125,19 @@ public class CategoryFileDateHelper implements IFileDateHelper {
private final List<CategoryDateInfo> dateInfoList;
private final String archiveRootDirPath;
/**
* Initialization constructor.
*
* @param archiveRootDirPath
* - Assumes path ends with file separator.
* @param config
* @param rootDirPattern
* categoryTopLevelDirPattern
*/
public CategoryFileDateHelper(CategoryConfig config) {
public CategoryFileDateHelper(String archiveRootDirPath,
CategoryConfig config) {
List<CategoryDataSet> categoryDataSetList = config.getDataSetList();
this.archiveRootDirPath = archiveRootDirPath;
int size = 0;
for (CategoryDataSet dataSet : categoryDataSetList) {
size += dataSet.getDirPatterns().size();
@ -176,6 +180,9 @@ public class CategoryFileDateHelper implements IFileDateHelper {
@Override
public DataSetStatus getFileDate(File file) {
String filenamePath = file.getAbsolutePath();
if (filenamePath.indexOf(archiveRootDirPath) == 0) {
filenamePath = filenamePath.substring(archiveRootDirPath.length());
}
Long timestamp = null;
DataSetStatus result = new DataSetStatus(file);

View file

@ -0,0 +1,83 @@
/**
* 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.common.dataplugin.gfe.server.notify;
import com.raytheon.uf.common.message.WsId;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
/**
* Combinations File Changed Notification
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 5, 2014 #2591 randerso Initial creation
*
* </pre>
*
* @author randerso
* @version 1.0
*/
@DynamicSerialize
public class CombinationsFileChangedNotification extends GfeNotification {
@DynamicSerializeElement
private String combinationsFileName;
@DynamicSerializeElement
private WsId whoChanged;
/**
* default constructor for serialization
*/
public CombinationsFileChangedNotification() {
super();
}
public CombinationsFileChangedNotification(String combinationsFileName,
WsId whoChanged, String siteID) {
super();
this.siteID = siteID;
this.combinationsFileName = combinationsFileName;
this.whoChanged = whoChanged;
}
public String getCombinationsFileName() {
return combinationsFileName;
}
public void setCombinationsFileName(String combinationsFileName) {
this.combinationsFileName = combinationsFileName;
}
public WsId getWhoChanged() {
return whoChanged;
}
public void setWhoChanged(WsId whoChanged) {
this.whoChanged = whoChanged;
}
}

View file

@ -74,15 +74,17 @@ import com.raytheon.uf.edex.database.processor.IDatabaseProcessor;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec 10, 2013 2555 rjpeter Initial creation
*
* Dec 10, 2013 2555 rjpeter Initial creation.
* Jan 23, 2014 2555 rjpeter Updated to be a row at a time using ScrollableResults.
* Feb 04, 2014 2770 rferrel The dumpPdos now dumps all PluginDataObjects.
* </pre>
*
* @author rjpeter
* @version 1.0
*/
public class DatabaseArchiveProcessor implements IDatabaseProcessor {
public class DatabaseArchiveProcessor<T extends PersistableDataObject<?>>
implements IDatabaseProcessor<T> {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(DatabaseArchiveProcessor.class);
@ -110,9 +112,11 @@ public class DatabaseArchiveProcessor implements IDatabaseProcessor {
protected int fetchSize = 1000;
protected int entriesInMemory = 0;
protected Set<String> datastoreFilesToArchive = new HashSet<String>();
protected Set<String> filesCreatedThisSession = new HashSet<String>();
protected Map<String, FileStatus> filesCreatedThisSession = new HashMap<String, FileStatus>();
protected Set<File> dirsToCheckNumbering = new HashSet<File>();
@ -120,6 +124,8 @@ public class DatabaseArchiveProcessor implements IDatabaseProcessor {
protected boolean failed = false;
protected Map<String, List<PersistableDataObject<?>>> pdosByFile;
public DatabaseArchiveProcessor(String archivePath, String pluginName,
PluginDao dao, IPluginArchiveFileNameFormatter nameFormatter) {
this.archivePath = archivePath;
@ -136,46 +142,43 @@ public class DatabaseArchiveProcessor implements IDatabaseProcessor {
* .util.List)
*/
@Override
public boolean process(List<?> objects) {
if ((objects != null) && !objects.isEmpty()) {
Set<String> datastoreFiles = new HashSet<String>();
statusHandler.info(pluginName + ": Processing rows " + recordsSaved
+ " to " + (recordsSaved + objects.size()));
@SuppressWarnings("unchecked")
List<PersistableDataObject<?>> pdos = (List<PersistableDataObject<?>>) objects;
Map<String, List<PersistableDataObject<?>>> pdosByFile = new HashMap<String, List<PersistableDataObject<?>>>();
for (PersistableDataObject<?> pdo : pdos) {
String path = nameFormatter.getFilename(pluginName, dao, pdo);
if (path.endsWith(".h5")) {
datastoreFiles.add(path);
path = path.substring(0, path.length() - 3);
}
List<PersistableDataObject<?>> list = pdosByFile.get(path);
if (list == null) {
list = new LinkedList<PersistableDataObject<?>>();
pdosByFile.put(path, list);
}
list.add(pdo);
public boolean process(T object) {
if (object != null) {
if (pdosByFile == null) {
pdosByFile = new HashMap<String, List<PersistableDataObject<?>>>(
(int) (fetchSize * 1.3));
}
if (statusHandler.isPriorityEnabled(Priority.DEBUG)) {
statusHandler.debug(pluginName + ": Processed "
+ objects.size() + " rows into " + pdosByFile.size()
+ " files");
String path = nameFormatter.getFilename(pluginName, dao, object);
if (path.endsWith(".h5")) {
datastoreFilesToArchive.add(path);
path = path.substring(0, path.length() - 3);
}
try {
savePdoMap(pdosByFile);
datastoreFilesToArchive.addAll(datastoreFiles);
recordsSaved += pdos.size();
} catch (Exception e) {
statusHandler.error(pluginName
+ ": Error occurred saving data to archive", e);
failed = true;
return false;
List<PersistableDataObject<?>> list = pdosByFile.get(path);
if (list == null) {
list = new LinkedList<PersistableDataObject<?>>();
pdosByFile.put(path, list);
}
list.add(object);
entriesInMemory++;
if (entriesInMemory >= fetchSize) {
try {
savePdoMap(pdosByFile);
pdosByFile.clear();
int prev = recordsSaved;
recordsSaved += entriesInMemory;
entriesInMemory = 0;
statusHandler.info(pluginName + ": Processed rows " + prev
+ " to " + recordsSaved);
} catch (Exception e) {
statusHandler.error(pluginName
+ ": Error occurred saving data to archive", e);
failed = true;
return false;
}
}
}
@ -188,6 +191,20 @@ public class DatabaseArchiveProcessor implements IDatabaseProcessor {
*/
@Override
public void finish() {
if (entriesInMemory > 0) {
try {
savePdoMap(pdosByFile);
int prev = recordsSaved;
recordsSaved += entriesInMemory;
statusHandler.info(pluginName + ": Processed rows " + prev
+ " to " + recordsSaved);
} catch (Exception e) {
statusHandler.error(pluginName
+ ": Error occurred saving data to archive", e);
failed = true;
}
}
for (File dir : dirsToCheckNumbering) {
checkFileNumbering(dir);
}
@ -370,7 +387,10 @@ public class DatabaseArchiveProcessor implements IDatabaseProcessor {
+ fileCount);
fileMap.put(fileCount, newFile);
writeDataToDisk(newFile, pdos);
filesCreatedThisSession.add(newFile.getAbsolutePath());
FileStatus status = new FileStatus();
status.dupElimUntilIndex = 0;
status.fileFull = pdos.size() >= fetchSize;
filesCreatedThisSession.put(newFile.getAbsolutePath(), status);
// check if we have added another digit and should add a 0 to
// previous numbers
@ -404,14 +424,15 @@ public class DatabaseArchiveProcessor implements IDatabaseProcessor {
Iterator<File> fileIter = fileMap.values().iterator();
while (fileIter.hasNext()) {
File dataFile = fileIter.next();
int dupElimUntil = Integer.MAX_VALUE;
FileStatus prevFileStatus = filesCreatedThisSession
.get(dataFile.getAbsolutePath());
if (filesCreatedThisSession
.contains(dataFile.getAbsolutePath())) {
statusHandler
.debug(pluginName
+ ": Skipping dup check on data file created this session: "
+ dataFile.getName());
continue;
if (prevFileStatus != null) {
dupElimUntil = prevFileStatus.dupElimUntilIndex;
if ((dupElimUntil <= 0) && prevFileStatus.fileFull) {
continue;
}
}
List<PersistableDataObject<?>> pdosFromDisk = readDataFromDisk(dataFile);
@ -424,13 +445,17 @@ public class DatabaseArchiveProcessor implements IDatabaseProcessor {
.iterator();
boolean needsUpdate = false;
int dupsRemoved = 0;
while (pdoIter.hasNext()) {
int index = 0;
while (pdoIter.hasNext() && (index < dupElimUntil)) {
PersistableDataObject<?> pdo = pdoIter.next();
if (identifierSet.contains(pdo.getIdentifier())) {
pdoIter.remove();
needsUpdate = true;
dupsRemoved++;
}
index++;
}
if (statusHandler.isPriorityEnabled(Priority.DEBUG)
@ -443,6 +468,15 @@ public class DatabaseArchiveProcessor implements IDatabaseProcessor {
if (!fileIter.hasNext() && (pdosFromDisk.size() < fetchSize)) {
// last file, add more data to it
needsUpdate = true;
if (prevFileStatus == null) {
prevFileStatus = new FileStatus();
prevFileStatus.dupElimUntilIndex = pdosFromDisk.size();
prevFileStatus.fileFull = pdos.size() >= fetchSize;
filesCreatedThisSession.put(dataFile.getAbsolutePath(),
prevFileStatus);
}
int numToAdd = fetchSize - pdosFromDisk.size();
numToAdd = Math.min(numToAdd, pdos.size());
@ -463,6 +497,9 @@ public class DatabaseArchiveProcessor implements IDatabaseProcessor {
if (needsUpdate) {
if (!pdosFromDisk.isEmpty()) {
writeDataToDisk(dataFile, pdosFromDisk);
if (prevFileStatus != null) {
prevFileStatus.fileFull = pdosFromDisk.size() >= fetchSize;
}
} else {
dirsToCheckNumbering.add(dataFile.getParentFile());
dataFile.delete();
@ -629,8 +666,11 @@ public class DatabaseArchiveProcessor implements IDatabaseProcessor {
Iterator<PersistableDataObject<?>> pdoIter = pdos.iterator();
writer = new BufferedWriter(new FileWriter(dumpFile));
statusHandler.info(String.format("%s: Dumping records to: %s",
pluginName, dumpFile.getAbsolutePath()));
if (statusHandler.isPriorityEnabled(Priority.INFO)) {
statusHandler.info(String.format("%s: Dumping records to: %s",
pluginName, dumpFile.getAbsolutePath()));
}
while (pdoIter.hasNext()) {
PersistableDataObject<?> pdo = pdoIter.next();
@ -640,9 +680,11 @@ public class DatabaseArchiveProcessor implements IDatabaseProcessor {
// otherwise was read from file and will be recorded in
// a previous entry
writer.write("" + pluginDataObject.getId() + ":");
writer.write(pluginDataObject.getDataURI());
writer.write("\n");
} else {
writer.write("-:");
}
writer.write(pluginDataObject.getDataURI());
writer.write("\n");
} else {
writer.write(pdo.getIdentifier().toString());
writer.write("\n");
@ -736,4 +778,22 @@ public class DatabaseArchiveProcessor implements IDatabaseProcessor {
}
}
}
/**
* Inner class for tracking status of files that have been written out this
* session.
*/
private static class FileStatus {
/**
* Apply dup elim logic until this index is reached.
*/
private int dupElimUntilIndex;
/**
* Way of tracking if file is considered full. Tracked so that if the
* file doesn't need to be dup elim'd due to being written this session
* and the file is full then there is no reason to deserialize it.
*/
private boolean fileFull;
}
}

View file

@ -43,6 +43,8 @@ import net.sf.ehcache.management.ManagementService;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Criterion;
@ -95,10 +97,9 @@ import com.raytheon.uf.edex.database.query.DatabaseQuery;
* 5/14/08 1076 brockwoo Fix for distinct with multiple properties
* Oct 10, 2012 1261 djohnson Incorporate changes to DaoConfig, add generic to {@link IPersistableDataObject}.
* Apr 15, 2013 1868 bsteffen Rewrite mergeAll in PluginDao.
*
* Nov 08, 2013 2361 njensen Changed method signature of saveOrUpdate to take Objects, not PersistableDataObjects
* Dec 13, 2013 2555 rjpeter Added processByCriteria and fixed Generics warnings.
*
* Jan 23, 2014 2555 rjpeter Updated processByCriteriato be a row at a time using ScrollableResults.
* </pre>
*
* @author bphillip
@ -460,8 +461,9 @@ public class CoreDao extends HibernateDaoSupport {
* @throws DataAccessLayerException
* If the query fails
*/
public int processByCriteria(final DatabaseQuery query,
final IDatabaseProcessor processor) throws DataAccessLayerException {
public <T> int processByCriteria(final DatabaseQuery query,
final IDatabaseProcessor<T> processor)
throws DataAccessLayerException {
int rowsProcessed = 0;
try {
// Get a session and create a new criteria instance
@ -480,24 +482,29 @@ public class CoreDao extends HibernateDaoSupport {
"Error populating query", e);
}
if (processor.getBatchSize() > 0) {
hibQuery.setMaxResults(processor.getBatchSize());
} else if (query.getMaxResults() != null) {
hibQuery.setMaxResults(query.getMaxResults());
int batchSize = processor.getBatchSize();
if (batchSize <= 0) {
batchSize = 1000;
}
List<?> results = null;
boolean continueProcessing = false;
int count = 0;
hibQuery.setFetchSize(processor.getBatchSize());
do {
hibQuery.setFirstResult(count);
results = hibQuery.list();
continueProcessing = processor.process(results);
count += results.size();
int count = 0;
ScrollableResults rs = hibQuery
.scroll(ScrollMode.FORWARD_ONLY);
boolean continueProcessing = true;
while (rs.next() && continueProcessing) {
Object[] row = rs.get();
if (row.length > 0) {
continueProcessing = processor
.process((T) row[0]);
}
count++;
if ((count % batchSize) == 0) {
getSession().clear();
} while (continueProcessing && (results != null)
&& (results.size() > 0));
}
}
processor.finish();
return count;
}

View file

@ -19,12 +19,9 @@
**/
package com.raytheon.uf.edex.database.processor;
import java.util.List;
/**
* Interface for working with a batched set of results inside a database
* session. Process can be called multiple times based on the batchSize of the
* processor.
* session. Process will be called for each row.
*
* <pre>
*
@ -32,21 +29,22 @@ import java.util.List;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec 9, 2013 2555 rjpeter Initial creation
* Dec 9, 2013 2555 rjpeter Initial creation.
* Jan 23, 2014 2555 rjpeter Updated to be a row at a time using ScrollableResults.
* </pre>
*
* @author rjpeter
* @version 1.0
*/
public interface IDatabaseProcessor {
public interface IDatabaseProcessor<T> {
/**
* Perform any processing on this batch of objects.
* Perform any processing on this row.
*
* @param objects
* @param row
* @return True if should continue processing, false otherwise.
*/
public boolean process(List<?> objects);
public boolean process(T row);
/**
* Perform any post processing if necessary.

6
pythonPackages/numpy/numpy/core/numeric.py Normal file → Executable file
View file

@ -1493,10 +1493,8 @@ def set_string_function(f, repr=True):
else:
return multiarray.set_string_function(f, repr)
# randerso DR #2513 remove calls to non-threadsafe set_string_function
# https://github.com/numpy/numpy/issues/3961
# set_string_function(array_str, 0)
# set_string_function(array_repr, 1)
set_string_function(array_str, 0)
set_string_function(array_repr, 1)
little_endian = (sys.byteorder == 'little')

View file

@ -8,10 +8,7 @@ if [ ${RC} -ne 0 ]; then
fi
# Determine Where Ant Has Been Installed.
ANT_INSTALL=`rpm -q --queryformat '%{INSTPREFIXES}' awips2-ant`
if [ "${ANT_INSTALL}" = "" ]; then
return
fi
ANT_INSTALL=/awips2/ant
# Update The Environment.
export ANT_HOME="${ANT_INSTALL}"

View file

@ -409,17 +409,21 @@ fi
if [ "${1}" = "-viz" ]; then
buildRPM "awips2"
#buildRPM "awips2-common-base"
buildRPM "awips2-common-base"
#buildRPM "awips2-python-numpy"
buildRPM "awips2-ant"
#buildRPM "awips2-python-dynamicserialize"
#buildRPM "awips2-python"
buildRPM "awips2-adapt-native"
#buildRPM "awips2-adapt-native"
#unpackHttpdPypies
#if [ $? -ne 0 ]; then
# exit 1
#fi
#buildRPM "awips2-httpd-pypies"
buildRPM "awips2-hydroapps-shared"
#buildRPM "awips2-hydroapps-shared"
#buildRPM "awips2-rcm"
#buildRPM "awips2-gfesuite-client"
#buildRPM "awips2-gfesuite-server"
#buildRPM "awips2-tools"
#buildRPM "awips2-cli"
buildCAVE
@ -447,12 +451,13 @@ if [ "${1}" = "-custom" ]; then
#if [ $? -ne 0 ]; then
# exit 1
#fi
buildRPM "awips2-adapt-native"
buildRPM "awips2-hydroapps-shared"
#buildRPM "awips2-adapt-native"
#buildRPM "awips2-hydroapps-shared"
#buildRPM "awips2-alertviz"
#buildRPM "awips2-python"
#buildRPM "awips2-alertviz"
#buildRPM "awips2-eclipse"
buildRPM "awips2-python"
exit 0
fi