From 31ae7ea21888b9ccd04c7327adab48324f302d26 Mon Sep 17 00:00:00 2001 From: Steve Harris Date: Wed, 15 Aug 2012 13:59:00 -0500 Subject: [PATCH] 12.9.1-1 baseline Former-commit-id: 6601ddb09c2928754c2c3859dac284998d73ff81 --- .../rcm/server/RadarServerAvailable.java | 132 +- .../aviation/config/gui/ClimateTimeouts.xml | 3 +- .../etc/aviation/python/toolpy/AdjustTimes.py | 5 +- .../python/toolpy/UseMetarForPrevailing.py | 5 +- .../textUtilities/headline/FormatterRunner.py | 14 +- .../uf/viz/core/catalog/ScriptCreator.java | 6 +- .../uf/viz/core/requests/ThriftClient.java | 16 +- .../styleRules/d2dArrowStyleRules.xml | 2 +- .../styleRules/d2dContourStyleRules.xml | 9 + .../styleRules/d2dGraphStyleRules.xml | 9 + cave/com.raytheon.uf.viz.d2d.ui/plugin.xml | 2 +- .../viz/d2d/ui/actions/AddAWIPSProcedure.java | 2 +- .../d2d/ui/actions/OpenAWIPSProcedure.java | 21 +- .../ui/dialogs/procedures/ProcedureDlg.java | 64 +- .../dialogs/procedures/ProcedureListDlg.java | 57 +- .../derivedParameters/definitions/CCP.xml | 6 +- .../derivedParameters/definitions/Wind.xml | 2 +- .../monitor/scan/resource/ScanResource.java | 4 +- .../uf/viz/monitor/data/TableUtil.java | 398 ++--- .../monitor/ui/dialogs/StationTableComp.java | 2 +- .../uf/viz/radarapps/client/RcmClient.java | 26 +- .../rsc/AbstractCrossSectionResource.java | 4 +- .../rsc/CrossSectionImageResource.java | 10 +- .../rsc/AbstractTimeHeightResource.java | 1 + .../xy/timeseries/rsc/TimeSeriesResource.java | 31 +- .../viz/xy/varheight/util/ScaleHandler.java | 42 +- cave/com.raytheon.viz.aviation/plugin.xml | 7 + .../aviation/climatology/WindRosePlotDlg.java | 83 +- .../src/com/raytheon/viz/bcd/BCDResource.java | 10 + .../gfe/dialogs/FormatterLauncherDialog.java | 3 + .../gfe/edittool/sample/SamplePainter.java | 32 +- .../gfe/edittool/sample/SampleRenderable.java | 27 +- .../com/raytheon/viz/gfe/smarttool/Tool.java | 4 +- .../styleRules/gridImageryStyleRules.xml | 4 +- .../viz/grid/rsc/GridResourceData.java | 3 +- .../viz/grid/rsc/GridVectorResource.java | 5 +- .../grid/rsc/general/D2DGribGridResource.java | 4 +- .../FlashFloodGuidanceDlg.java | 4 +- .../hydro/resource/MultiPointResource.java | 19 +- .../timeseries/TimeSeriesDisplayDlg.java | 22 +- .../viz/hydro/timeseries/TimeSeriesDlg.java | 70 +- .../cresthistory/CrestHistoryCanvas.java | 1408 +++++++++-------- .../datamanager/RiverDataManager.java | 1354 ++++++++-------- .../hydrocommon/resource/FFGGridResource.java | 4 +- .../localization/bundles/DefaultSatellite.xml | 1 - .../bundles/DerivedPOESSatellite.xml | 1 - .../localization/bundles/DerivedSatellite.xml | 1 - .../viz/texteditor/AfosBrowserModel.java | 99 +- .../alarmalert/dialogs/AlarmAlertBell.java | 54 +- .../dialogs/AlarmAlertSaveLoadDlg.java | 55 +- .../dialogs/AlarmDisplayWindow.java | 8 +- .../alarmalert/util/AlarmAlertFunctions.java | 92 +- .../alarmalert/util/AlarmBeepJob.java | 41 +- .../dialogs/AWIPSHeaderBlockDlg.java | 33 +- .../texteditor/dialogs/AfosBrowserDlg.java | 29 +- .../texteditor/dialogs/TextEditorDialog.java | 509 +++--- .../viz/texteditor/print/PrintDisplay.java | 257 +-- .../texteditor/util/SiteAbbreviationUtil.java | 17 + .../textworkstation/TextWorkstationDlg.java | 27 +- .../raytheon/viz/ui/VizWorkbenchManager.java | 3 + .../viz/warngen/comm/WarningSender.java | 342 ++-- .../config/DbPointSourceDataAdaptor.java | 60 +- .../com/raytheon/viz/warngen/gis/Area.java | 130 +- .../com/raytheon/viz/warngen/gis/GisUtil.java | 108 +- .../src/com/raytheon/viz/warngen/gis/Wx.java | 145 +- .../viz/warngen/gui/WarngenDialog.java | 12 +- .../viz/warngen/gui/WarngenUIManager.java | 10 +- .../viz/warngen/template/TemplateRunner.java | 221 ++- .../viz/warngen/util/WarnGenMathTool.java | 21 + .../viz/warngen/util/WarningTextHandler.java | 12 +- deltaScripts/future/relocateTextUtilities.py | 95 ++ .../db/hibernateConfig/maps/hibernate.cfg.xml | 4 +- edexOsgi/build.edex/esb/conf/log4j.xml | 22 +- .../esb/conf/res/base/attributeNames.xml | 2 - .../esb/conf/res/base/environment.xml | 2 - .../base/warngen/VM_global_library.vm | 5 +- .../base/warngen/arealFloodAdvisory.xml | 1 + .../warngen/arealFloodAdvisoryFollowup.xml | 1 + .../arealFloodAdvisoryFollowup_Zones.xml | 1 + .../base/warngen/arealFloodAdvisory_Zones.xml | 1 + .../base/warngen/arealFloodWarning.xml | 1 + .../warngen/arealFloodWarningFollowup.xml | 1 + .../arealFloodWarningFollowup_Zones.xml | 1 + .../base/warngen/arealFloodWarning_Zones.xml | 1 + .../base/warngen/customTemplate.vm | 2 +- .../base/warngen/extremeWindWarning.vm | 17 +- .../warngen/extremeWindWarningFollowup.vm | 5 +- .../common_static/base/warngen/ffwfaw.xml | 1 + .../base/warngen/flashFloodWarning.xml | 1 + .../warngen/flashFloodWarningFollowup.xml | 1 + .../flashFloodWarningFollowup_Zones.xml | 1 + .../base/warngen/flashFloodWarning_Zones.xml | 1 + .../impactSevereThunderstormWarning.vm | 3 +- .../warngen/impactSevereWeatherStatement.vm | 5 +- .../base/warngen/impactTornadoWarning.vm | 3 +- .../nonConvectiveFlashFloodWarning.xml | 1 + ...nonConvectiveFlashFloodWarningFollowup.xml | 1 + ...vectiveFlashFloodWarningFollowup_Zones.xml | 1 + .../nonConvectiveFlashFloodWarning_Zones.xml | 1 + .../base/warngen/severeThunderstormWarning.vm | 3 +- .../base/warngen/severeWeatherStatement.vm | 5 +- .../warngen/significantWeatherAdvisory.vm | 3 +- .../base/warngen/specialMarineWarning.vm | 3 +- .../warngen/specialMarineWarningFollowup.vm | 7 +- .../base/warngen/tornadoWarning.vm | 3 +- .../edex_static/base/smartinit/Init.py | 13 +- .../base/textproducts/Generator.py | 220 ++- .../templates/product/Hazard_HLS.py | 16 +- .../plugin/gfe/reference/ReferenceMgr.java | 162 ++ .../edex/plugin/gfe/smartinit/IFPWE.java | 43 +- .../edex/plugin/gfe/smartinit/InitClient.java | 47 +- .../plugin/gfe/textproducts/Configurator.java | 11 +- ...f.common.serialization.ISerializableObject | 2 + .../GribPostProcessor.java | 298 ++-- .../PostProcessedModel.java | 100 ++ .../PostProcessedModelSet.java | 70 + .../postProcessModels/postProcessedModels.txt | 80 - .../postProcessModels/postProcessedModels.xml | 125 ++ .../text/impl/TextSeparatorFactory.java | 14 +- .../raytheon/uf/common/comm/HttpClient.java | 7 +- .../dataplugin/grib/util/GribModelLookup.java | 5 + .../config/PointSourceConfiguration.java | 12 + .../warning/gis/GeospatialFactory.java | 29 +- .../DestinationGeodeticCalculator.java | 233 +-- .../monitor/data/CommonTableConfig.java | 187 +-- .../META-INF/MANIFEST.MF | 1 + .../serialization/comm/RequestWrapper.java | 101 ++ .../com/raytheon/uf/common/util/SizeUtil.java | 69 + .../edex/auth/RemoteRequestRouteWrapper.java | 73 +- .../uf/edex/auth/RemoteRequestServer.java | 14 +- .../edex_static/base/roles/userRoles.xml | 10 + .../configuration/svcbu.properties | 4 +- .../cli/src/ifpservertext/ifpServerText.py | 46 +- .../META-INF/MANIFEST.MF | 1 - .../awips2.cave/setup/scripts/prepare_dist.sh | 2 +- rpms/awips2.core/Installer.rcm/component.spec | 4 +- rpms/awips2.edex/deploy.builder/build.sh | 1 + tools/scripts/commit-msg | 104 ++ tools/scripts/git-u-setup | 58 + 139 files changed, 5153 insertions(+), 3439 deletions(-) create mode 100644 deltaScripts/future/relocateTextUtilities.py create mode 100644 edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/reference/ReferenceMgr.java create mode 100644 edexOsgi/com.raytheon.edex.plugin.grib/src/com/raytheon/edex/plugin/grib/decoderpostprocessors/PostProcessedModel.java create mode 100644 edexOsgi/com.raytheon.edex.plugin.grib/src/com/raytheon/edex/plugin/grib/decoderpostprocessors/PostProcessedModelSet.java delete mode 100644 edexOsgi/com.raytheon.edex.plugin.grib/utility/edex_static/base/grib/postProcessModels/postProcessedModels.txt create mode 100644 edexOsgi/com.raytheon.edex.plugin.grib/utility/edex_static/base/grib/postProcessModels/postProcessedModels.xml create mode 100644 edexOsgi/com.raytheon.uf.common.serialization.comm/src/com/raytheon/uf/common/serialization/comm/RequestWrapper.java create mode 100644 edexOsgi/com.raytheon.uf.common.util/src/com/raytheon/uf/common/util/SizeUtil.java create mode 100644 tools/scripts/commit-msg create mode 100644 tools/scripts/git-u-setup diff --git a/RadarServer/com.raytheon.rcm.server/src/com/raytheon/rcm/server/RadarServerAvailable.java b/RadarServer/com.raytheon.rcm.server/src/com/raytheon/rcm/server/RadarServerAvailable.java index 2d6f4c98c7..a917743d28 100644 --- a/RadarServer/com.raytheon.rcm.server/src/com/raytheon/rcm/server/RadarServerAvailable.java +++ b/RadarServer/com.raytheon.rcm.server/src/com/raytheon/rcm/server/RadarServerAvailable.java @@ -21,14 +21,18 @@ package com.raytheon.rcm.server; import java.io.File; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Scanner; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; import com.raytheon.rcm.event.RadarEvent; import com.raytheon.rcm.event.RadarEventAdapter; /** - * TODO Add Description + * Send AlertViz notifications * *
  * 
@@ -37,6 +41,7 @@ import com.raytheon.rcm.event.RadarEventAdapter;
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
  * Nov 9, 2011            mnash     Initial creation
+ * 2012-07-27   DR 14896   D. Friedman  Handle multiple RPGs.
  * 
  * 
* @@ -46,13 +51,15 @@ import com.raytheon.rcm.event.RadarEventAdapter; public class RadarServerAvailable extends RadarEventAdapter { - private static boolean attempted = false; + private static final String CONNECTION_DOWN_MESSAGE = "RPG connection is down."; + private static final String CONNECTION_UP_MESSAGE = "RPG connection is back up."; + + private static final String AWIPS2_FXA_PROPERTY = "awips2_fxa"; + private static final String DEFAULT_AWIPS2_FXA = "/awips2/fxa"; + private static final String ANNOUNCER_PATH = "bin" + File.separator + "fxaAnnounce"; - private ProcessBuilder builder; + private HashSet knownFailures = new HashSet(); - /** - * - */ public RadarServerAvailable(RadarServer server) { } @@ -65,64 +72,73 @@ public class RadarServerAvailable extends RadarEventAdapter { */ @Override public void handleRadarEvent(RadarEvent event) { - Process proc = null; - String home = System.getProperty("awips2_fxa"); - if (home != null && !home.endsWith(File.separator)) { - home += File.separator; - } else if (home == null) { - Log.event("Cannot find awips2_fxa system variable"); - return; - } - List values = new ArrayList(); - values.add(home + "bin" + File.separator + "fxaAnnounce"); - try { - if (event.getType() == RadarEvent.CONNECTION_ATTEMPT_FAILED) { - if (!attempted) { - Log.event("Executing " + values.get(0)); - values.add(event.getRadarID() + " rpg connection is down."); - values.add("RADAR"); - values.add("URGENT"); - builder = new ProcessBuilder(values); - builder.redirectErrorStream(true); - - proc = builder.start(); - StringBuilder output = new StringBuilder(); - Scanner s = new Scanner(proc.getInputStream()); - while (s.hasNextLine()) { - if (output.length() > 0) - output.append('\n'); - output.append(s.nextLine()); - } - proc.waitFor(); - attempted = true; - } - } else if (event.getType() == RadarEvent.CONNECTION_UP) { - if (attempted) { - Log.event("Executing " + values.get(0)); - values.add(event.getRadarID() - + " rpg connection is back up."); - values.add("RADAR"); - values.add("URGENT"); - builder = new ProcessBuilder(values); - builder.redirectErrorStream(true); - proc = builder.start(); - StringBuilder output = new StringBuilder(); - Scanner s = new Scanner(proc.getInputStream()); - while (s.hasNextLine()) { - if (output.length() > 0) - output.append('\n'); - output.append(s.nextLine()); - } - proc.waitFor(); - attempted = false; - } + final String radarId = event.getRadarID(); + if (event.getType() == RadarEvent.CONNECTION_ATTEMPT_FAILED) { + if (! knownFailures.contains(radarId)) { + knownFailures.add(radarId); + sendNotification(radarId, CONNECTION_DOWN_MESSAGE); } + } else if (event.getType() == RadarEvent.CONNECTION_UP) { + if (knownFailures.contains(radarId)) { + knownFailures.remove(radarId); + sendNotification(radarId, CONNECTION_UP_MESSAGE); + } + } + } + + private void sendNotification(final String radarId, final String message) { + getExecutorService().submit(new Runnable() { + @Override + public void run() { + sendNotification2(radarId, message); + } + }); + } + + private void sendNotification2(String radarId, String message) { + ProcessBuilder builder; + Process proc = null; + + String fxaDir = System.getProperty(AWIPS2_FXA_PROPERTY); + if (fxaDir == null) + fxaDir = DEFAULT_AWIPS2_FXA; + + List values = new ArrayList(); + values.add(fxaDir + File.separator + ANNOUNCER_PATH); + Log.event("Executing " + values.get(0)); + values.add(radarId + ' ' + message); + values.add("RADAR"); + values.add("URGENT"); + builder = new ProcessBuilder(values); + builder.redirectErrorStream(true); + + try { + proc = builder.start(); + Scanner s = new Scanner(proc.getInputStream()); + while (s.hasNextLine()) + s.nextLine(); + proc.waitFor(); } catch (Exception e) { - e.printStackTrace(); + Log.errorf("Error running fxaAnnounce: %s", e); } finally { if (proc != null) { proc.destroy(); } } } + + // TODO: has to be daemon until there is a shutdown notification + private static ExecutorService executorService = Executors + .newSingleThreadExecutor(new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + Thread t = new Thread(r); + t.setDaemon(true); + return t; + } + }); + + private static ExecutorService getExecutorService() { + return executorService; + } } diff --git a/cave/build/static/common/cave/etc/aviation/config/gui/ClimateTimeouts.xml b/cave/build/static/common/cave/etc/aviation/config/gui/ClimateTimeouts.xml index 0796d4eaa0..27f8fd2b59 100644 --- a/cave/build/static/common/cave/etc/aviation/config/gui/ClimateTimeouts.xml +++ b/cave/build/static/common/cave/etc/aviation/config/gui/ClimateTimeouts.xml @@ -21,10 +21,11 @@ 20 - 20 + 120 90 1800 diff --git a/cave/build/static/common/cave/etc/aviation/python/toolpy/AdjustTimes.py b/cave/build/static/common/cave/etc/aviation/python/toolpy/AdjustTimes.py index 3f376783f4..db028f02d9 100644 --- a/cave/build/static/common/cave/etc/aviation/python/toolpy/AdjustTimes.py +++ b/cave/build/static/common/cave/etc/aviation/python/toolpy/AdjustTimes.py @@ -94,7 +94,7 @@ # # import logging, re, time -import Avn, AvnLib, Busy, TafDecoder, AvnParser +import Avn, AvnLib, TafDecoder, AvnParser _Logger = logging.getLogger(Avn.CATEGORY) _AmdPat = re.compile(r'(AFT|TIL)\s+(\d{6})|(\d{4}/\d{4})') @@ -175,8 +175,7 @@ def updateTafs(bbb, fcsts): badidents.append(ident) if badidents: - Busy.showwarning('Could not update times for %s' % ' '.join(badidents), - master) + _Logger.warning('Could not update times for %s' % ' '.join(badidents)) return fcsts diff --git a/cave/build/static/common/cave/etc/aviation/python/toolpy/UseMetarForPrevailing.py b/cave/build/static/common/cave/etc/aviation/python/toolpy/UseMetarForPrevailing.py index b364649806..6879506dd3 100644 --- a/cave/build/static/common/cave/etc/aviation/python/toolpy/UseMetarForPrevailing.py +++ b/cave/build/static/common/cave/etc/aviation/python/toolpy/UseMetarForPrevailing.py @@ -78,7 +78,7 @@ # # import logging, time -import Avn, AvnLib, AvnParser, Busy, Globals, TafDecoder +import Avn, AvnLib, AvnParser, TafDecoder import MetarData @@ -120,7 +120,6 @@ def updateTafs(bbb, fcsts): badidents.append(ident) if badidents: - Busy.showwarning('Could not update TAFs for %s' % ' '.join(badidents), - master) + _Logger.warning('Could not update TAFs for %s' % ' '.join(badidents)) return fcsts diff --git a/cave/build/static/common/cave/etc/gfe/userPython/textUtilities/headline/FormatterRunner.py b/cave/build/static/common/cave/etc/gfe/userPython/textUtilities/headline/FormatterRunner.py index ea82212391..62c370af65 100644 --- a/cave/build/static/common/cave/etc/gfe/userPython/textUtilities/headline/FormatterRunner.py +++ b/cave/build/static/common/cave/etc/gfe/userPython/textUtilities/headline/FormatterRunner.py @@ -18,6 +18,7 @@ # further licensing information. ## +import TimeRange, AbsTime import logging import TextFormatter import time, os, string, inspect, sys @@ -288,6 +289,17 @@ def runFormatter(databaseID, site, forecastList, cmdLineVarDict, vtecMode, logger.info("Text Formatter Finished") return forecasts +def getAbsTime(timeStr): + "Create an AbsTime from a string: YYYYMMDD_HHMM" + + year = int(timeStr[0:4]) + month = int(timeStr[4:6]) + day = int(timeStr[6:8]) + hour = int(timeStr[9:11]) + minute = int(timeStr[11:13]) + + return AbsTime.absTimeYMD(year, month, day, hour, minute) + def writeToFile(forecasts, outputFile, mode): if not outputFile is None and outputFile != "": outfile = open(outputFile, mode) @@ -427,4 +439,4 @@ def reloadModule(moduleName): except: logger.exception("Import Failed " + moduleName) - \ No newline at end of file + diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/catalog/ScriptCreator.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/catalog/ScriptCreator.java index 94052790a2..6fb89eeb6c 100644 --- a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/catalog/ScriptCreator.java +++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/catalog/ScriptCreator.java @@ -50,7 +50,10 @@ import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.localization.LocalizationManager; /** - * Creates uEngine scripts on the fly. + * Creates uEngine scripts on the fly. DEPRECATED: Requests from viz should go + * through ThriftClient to the thrift service instead of using ScriptCreator and + * then going to the uengine service. The thrift service performs faster and is + * more maintainable. Use ThriftClient. * *
  * 
@@ -73,6 +76,7 @@ import com.raytheon.uf.viz.core.localization.LocalizationManager;
  * @author brockwoo
  * @version 1
  */
+@Deprecated
 public class ScriptCreator {
     private static final transient IUFStatusHandler statusHandler = UFStatus
             .getHandler(ScriptCreator.class);
diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/requests/ThriftClient.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/requests/ThriftClient.java
index 0c81f13840..632dc092d5 100644
--- a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/requests/ThriftClient.java
+++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/requests/ThriftClient.java
@@ -4,6 +4,7 @@ import java.io.IOException;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
+import java.util.UUID;
 
 import javax.jws.WebService;
 
@@ -20,6 +21,7 @@ import com.raytheon.uf.common.serialization.SerializationException;
 import com.raytheon.uf.common.serialization.SerializationUtil;
 import com.raytheon.uf.common.serialization.comm.IServerRequest;
 import com.raytheon.uf.common.serialization.comm.RemoteServiceRequest;
+import com.raytheon.uf.common.serialization.comm.RequestWrapper;
 import com.raytheon.uf.common.serialization.comm.ServiceException;
 import com.raytheon.uf.common.serialization.comm.response.ServerErrorResponse;
 import com.raytheon.uf.common.serialization.comm.util.ExceptionWrapper;
@@ -50,9 +52,9 @@ import com.raytheon.uf.viz.core.localization.LocalizationManager;
  **/
 
 /**
- * The thrift client. used to send requests to the RemoteReqeustServer. Make
+ * The thrift client. used to send requests to the RemoteRequestServer. Make
  * sure request type has registered a handler to handle the request on the
- * server
+ * server.
  * 
  * 
  * 
@@ -60,6 +62,7 @@ import com.raytheon.uf.viz.core.localization.LocalizationManager;
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
  * Aug 3, 2009            mschenke     Initial creation
+ * Jul 24, 2012             njensen         Enhanced logging
  * 
  * 
* @@ -272,9 +275,12 @@ public class ThriftClient { private static Object sendRequest(IServerRequest request, String httpAddress, String uri) throws VizException { httpAddress += uri; + String uniqueId = UUID.randomUUID().toString(); + RequestWrapper wrapper = new RequestWrapper(request, VizApp.getWsId(), + uniqueId); byte[] message; try { - message = SerializationUtil.transformToThrift(request); + message = SerializationUtil.transformToThrift(wrapper); } catch (SerializationException e) { throw new VizException("unable to serialize request object", e); } @@ -286,8 +292,8 @@ public class ThriftClient { .postBinary(httpAddress, message); long time = System.currentTimeMillis() - t0; if (time >= SIMPLE_LOG_TIME) { - System.out.println("Took " + time + "ms to run request " - + request); + System.out.println("Took " + time + "ms to run request id[" + + uniqueId + "] " + request.toString()); } if (time >= BAD_LOG_TIME) { new Exception() { diff --git a/cave/com.raytheon.uf.viz.d2d.ui/localization/styleRules/d2dArrowStyleRules.xml b/cave/com.raytheon.uf.viz.d2d.ui/localization/styleRules/d2dArrowStyleRules.xml index 1daeeb5004..3879db62cb 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/localization/styleRules/d2dArrowStyleRules.xml +++ b/cave/com.raytheon.uf.viz.d2d.ui/localization/styleRules/d2dArrowStyleRules.xml @@ -80,9 +80,9 @@ K/m*1.0E6 --> + K/m*1.0E6 diff --git a/cave/com.raytheon.uf.viz.d2d.ui/localization/styleRules/d2dContourStyleRules.xml b/cave/com.raytheon.uf.viz.d2d.ui/localization/styleRules/d2dContourStyleRules.xml index 66a272a6c3..bab5801554 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/localization/styleRules/d2dContourStyleRules.xml +++ b/cave/com.raytheon.uf.viz.d2d.ui/localization/styleRules/d2dContourStyleRules.xml @@ -4084,4 +4084,13 @@ in | .03937 | 0 | 4 | | |..|8000F0FF| | 16 | \ + + + Wind + Gust + + + kts + + diff --git a/cave/com.raytheon.uf.viz.d2d.ui/localization/styleRules/d2dGraphStyleRules.xml b/cave/com.raytheon.uf.viz.d2d.ui/localization/styleRules/d2dGraphStyleRules.xml index 1f2f625258..55d705073b 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/localization/styleRules/d2dGraphStyleRules.xml +++ b/cave/com.raytheon.uf.viz.d2d.ui/localization/styleRules/d2dGraphStyleRules.xml @@ -498,4 +498,13 @@ + + + MTV + + + g*m/(kg*s) + + + \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.d2d.ui/plugin.xml b/cave/com.raytheon.uf.viz.d2d.ui/plugin.xml index 058f36cdb9..9618c3d2d6 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/plugin.xml +++ b/cave/com.raytheon.uf.viz.d2d.ui/plugin.xml @@ -1543,7 +1543,7 @@ diff --git a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/AddAWIPSProcedure.java b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/AddAWIPSProcedure.java index 15e570416e..056292b90f 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/AddAWIPSProcedure.java +++ b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/AddAWIPSProcedure.java @@ -57,7 +57,7 @@ public class AddAWIPSProcedure extends AbstractHandler { @Override public Object execute(ExecutionEvent event) throws ExecutionException { Procedure procedure = new Procedure(); - ProcedureDlg dlg = new ProcedureDlg(null, procedure, + ProcedureDlg dlg = ProcedureDlg.getOrCreateDialog(null, procedure, HandlerUtil.getActiveShell(event)); dlg.open(); 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 7e8183533b..7e9d075b4b 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 @@ -24,6 +24,8 @@ import java.io.File; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.handlers.HandlerUtil; import com.raytheon.uf.common.localization.LocalizationFile; @@ -53,6 +55,8 @@ import com.raytheon.viz.ui.actions.LoadSerializedXml; */ public class OpenAWIPSProcedure extends AbstractHandler { + private OpenProcedureListDlg dialog; + /* * (non-Javadoc) * @@ -62,16 +66,21 @@ public class OpenAWIPSProcedure extends AbstractHandler { */ @Override public Object execute(ExecutionEvent event) throws ExecutionException { - ProcedureListDlg listDlg = new OpenProcedureListDlg( + if(dialog != null){ + dialog.open(); + return null; + } + + dialog = new OpenProcedureListDlg( HandlerUtil.getActiveShell(event)); - listDlg.open(); - - LocalizationFile selectedFile = listDlg.getSelectedFile(); - + dialog.open(); + + LocalizationFile selectedFile = dialog.getSelectedFile(); + dialog = null; if (selectedFile != null) { File f = selectedFile.getFile(); Procedure p = (Procedure) LoadSerializedXml.deserialize(f); - ProcedureDlg dlg = new ProcedureDlg( + ProcedureDlg dlg = ProcedureDlg.getOrCreateDialog( LocalizationUtil.extractName(selectedFile.getName()), p, VizWorkbenchManager.getInstance().getCurrentWindow() .getShell()); diff --git a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureDlg.java b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureDlg.java index 3af3ceef9c..cd0eae8c30 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureDlg.java +++ b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureDlg.java @@ -23,6 +23,7 @@ package com.raytheon.uf.viz.d2d.ui.dialogs.procedures; import java.io.File; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; @@ -83,6 +84,22 @@ import com.raytheon.viz.ui.actions.SaveBundle; import com.raytheon.viz.ui.dialogs.CaveSWTDialog; import com.raytheon.viz.ui.editor.AbstractEditor; +/** + * + * Dialog for loading or modifying procedures. + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ *
+ * 
+ * + * @author unknown + * @version 1.0 + */ public class ProcedureDlg extends CaveSWTDialog { private static final transient IUFStatusHandler statusHandler = UFStatus @@ -94,6 +111,8 @@ public class ProcedureDlg extends CaveSWTDialog { public static final String PROCEDURES_DIR = "/procedures"; + private static Collection openDialogs = new ArrayList(); + private Font font; private List dataList; @@ -148,7 +167,7 @@ public class ProcedureDlg extends CaveSWTDialog { private final java.util.List bundles; - public ProcedureDlg(String fileName, Procedure p, Shell parent) { + private ProcedureDlg(String fileName, Procedure p, Shell parent) { // Win32 super(parent, SWT.DIALOG_TRIM | SWT.RESIZE, CAVE.INDEPENDENT_SHELL | CAVE.DO_NOT_BLOCK); @@ -203,6 +222,9 @@ public class ProcedureDlg extends CaveSWTDialog { @Override protected void disposed() { font.dispose(); + synchronized (openDialogs) { + openDialogs.remove(this); + } } @Override @@ -989,4 +1011,44 @@ public class ProcedureDlg extends CaveSWTDialog { }; dlg.open(); } + + /** + * If there is a procedure dialog open for the given filename, return it, + * otherwise null. + * + * @param fileName + * @return + */ + public static ProcedureDlg getDialog(String fileName) { + synchronized (openDialogs) { + if (fileName != null) { + for (ProcedureDlg dialog : openDialogs) { + if (fileName.equals(dialog.fileName)) { + return dialog; + } + } + } + return null; + } + } + + /** + * Get the ProcedureDlg for the given fileName. If the fileName is null or if there is no open dialog, create a new ProcedureDlg. + * + * @param fileName + * @param p + * @param parent + * @return + */ + public static ProcedureDlg getOrCreateDialog(String fileName, Procedure p, + Shell parent) { + synchronized (openDialogs) { + ProcedureDlg dialog = getDialog(fileName); + if (dialog == null) { + dialog = new ProcedureDlg(fileName, p, parent); + openDialogs.add(dialog); + } + return dialog; + } + } } diff --git a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureListDlg.java b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureListDlg.java index 657be9c429..baea4279c1 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureListDlg.java +++ b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureListDlg.java @@ -54,6 +54,24 @@ import com.raytheon.uf.common.localization.LocalizationUtil; import com.raytheon.uf.common.localization.PathManagerFactory; import com.raytheon.viz.ui.dialogs.CaveSWTDialog; +/** + * + * A dialog which displays a list of procedures for opening, saving, or deleting. + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * ???                                 Initial creation
+ * 07/31/2012   DR 15036   D. Friedman Ensure current user's procedures
+ *                                     are visible.
+ * 
+ * + * @author unknown + * @version 1.0 + */ public class ProcedureListDlg extends CaveSWTDialog { protected boolean oneLevel = true; @@ -317,10 +335,18 @@ public class ProcedureListDlg extends CaveSWTDialog { if (treeViewer.getContentProvider() instanceof ProcedureTreeContentProvider) { ProcedureTreeContentProvider content = (ProcedureTreeContentProvider) treeViewer .getContentProvider(); - Object find = content.findItem(user); + final Object find = content.findItem(user); if (find != null) { treeViewer.setExpandedElements(new Object[] { find }); - treeViewer.reveal(find); + treeViewer.getTree().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + TreeItem[] items = treeViewer.getTree().getItems(); + if (items != null && items.length > 0) + treeViewer.getTree().showItem(items[items.length - 1]); + treeViewer.reveal(find); + } + }); } } } @@ -449,14 +475,25 @@ public class ProcedureListDlg extends CaveSWTDialog { procedureTF.setText(procedureTF.getText().concat(".xml")); } if (dataListContains(procedureTF.getText())) { - // Pop up a warning - boolean result = MessageDialog.openQuestion(shell, - "Confirm Overwrite", - "The procedure " + procedureTF.getText() - + " already exists. Overwrite anyways?"); - if (result == true) { - fileName = procedureTF.getText(); - shell.dispose(); + if (ProcedureDlg.getDialog(procedureTF.getText()) != null) { + // User cannot save if dialog is open. + MessageDialog + .openError( + shell, + "Cannot Save Procedure", + "The procedure " + + procedureTF.getText() + + " is currently open. It cannot be overwritten until it is closed or saved under another name."); + } else { + // Pop up a warning + boolean result = MessageDialog.openQuestion(shell, + "Confirm Overwrite", + "The procedure " + procedureTF.getText() + + " already exists. Overwrite anyways?"); + if (result == true) { + fileName = procedureTF.getText(); + shell.dispose(); + } } } else { fileName = procedureTF.getText(); diff --git a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/CCP.xml b/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/CCP.xml index 427b0b177f..0286ffc47a 100644 --- a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/CCP.xml +++ b/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/CCP.xml @@ -24,15 +24,15 @@ - + - + - + diff --git a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/Wind.xml b/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/Wind.xml index 12c62202c1..550260cb4d 100644 --- a/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/Wind.xml +++ b/cave/com.raytheon.uf.viz.derivparam/localization/derivedParameters/definitions/Wind.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.monitor.scan/src/com/raytheon/uf/viz/monitor/scan/resource/ScanResource.java b/cave/com.raytheon.uf.viz.monitor.scan/src/com/raytheon/uf/viz/monitor/scan/resource/ScanResource.java index 8c29ae880c..0b314f53ec 100644 --- a/cave/com.raytheon.uf.viz.monitor.scan/src/com/raytheon/uf/viz/monitor/scan/resource/ScanResource.java +++ b/cave/com.raytheon.uf.viz.monitor.scan/src/com/raytheon/uf/viz/monitor/scan/resource/ScanResource.java @@ -79,6 +79,8 @@ import com.vividsolutions.jts.geom.Coordinate; * ------------ ---------- ----------- -------------------------- * Oct 13, 2009 dhladky Initial creation * + * Jul 24 2012 12996 Xiaochuan Compare with MidVal() + * *
* * @author dhladky @@ -359,7 +361,7 @@ public class ScanResource extends d = Double.valueOf(rank); } - if (d >= getScanDrawer().ddfc.getLowerVal()) { + if (d >= getScanDrawer().ddfc.getMidVal()) { if (!getScanDrawer().ddfc.isOverlap()) { if ((dtdr != null) && !dtdr.getOverlap()) { isOverlap = false; diff --git a/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/TableUtil.java b/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/TableUtil.java index d6938540ae..146af00d7c 100644 --- a/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/TableUtil.java +++ b/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/TableUtil.java @@ -902,192 +902,232 @@ public final class TableUtil { return null; } - private static TableRowData getSnowMetarHistTableRowData(ObReport report) { - TableRowData tblRowData = new TableRowData(8); - tblRowData.setTableCellData(0, new TableCellData(report.getObservationTime(),"HH:mm MMM dd",CellType.ObsHist)); - tblRowData.setTableCellData(1, - new TableCellData(Math.round(new Float(report.getWindDir())), - CellType.ObsHist, true)); - tblRowData.setTableCellData(2, - new TableCellData(Math.round(new Float(report.getWindSpeed())), - CellType.ObsHist, true)); - tblRowData.setTableCellData(3, - new TableCellData(Math.round(new Float(report.getWindGust())), - CellType.ObsHist, true)); - tblRowData.setTableCellData(4, new TableCellData(report.getPressure(), CellType.ObsHist, CommonTableConfig.obsHistCols.P)); - tblRowData.setTableCellData( - 5, - new TableCellData( - Math.round(new Float(report.getTemperature())), - CellType.ObsHist, true)); - tblRowData.setTableCellData(6, - new TableCellData(Math.round(new Float(report.getDewpoint())), - CellType.ObsHist, true)); - tblRowData.setTableCellData(7, new TableCellData(report.getPressureChange(), CellType.ObsHist, CommonTableConfig.obsHistCols.PTend)); - return tblRowData; - } + private static TableRowData getSnowMetarHistTableRowData(ObReport report) { + TableRowData tblRowData = new TableRowData(10); + tblRowData.setTableCellData(0, + new TableCellData(report.getObservationTime(), "HH:mm MMM dd", + CellType.ObsHist)); + tblRowData.setTableCellData(1, + new TableCellData(new Float(report.getLatitude()), + CellType.ObsHist, true)); + tblRowData.setTableCellData(2, + new TableCellData(new Float(report.getLongitude()), + CellType.ObsHist, true)); + tblRowData.setTableCellData(3, + new TableCellData(Math.round(new Float(report.getWindDir())), + CellType.ObsHist, true)); + tblRowData.setTableCellData(4, + new TableCellData(Math.round(new Float(report.getWindSpeed())), + CellType.ObsHist, true)); + tblRowData.setTableCellData(5, + new TableCellData(Math.round(new Float(report.getWindGust())), + CellType.ObsHist, true)); + tblRowData.setTableCellData(6, new TableCellData(report.getPressure(), + CellType.ObsHist, CommonTableConfig.obsHistCols.P)); + tblRowData.setTableCellData(7, + new TableCellData( + Math.round(new Float(report.getTemperature())), + CellType.ObsHist, true)); + tblRowData.setTableCellData(8, + new TableCellData(Math.round(new Float(report.getDewpoint())), + CellType.ObsHist, true)); + tblRowData.setTableCellData(9, + new TableCellData(report.getPressureChange(), CellType.ObsHist, + CommonTableConfig.obsHistCols.PTend)); + return tblRowData; + } private static TableRowData getSafeSeasMetarHistTableRowData(ObReport report) { // same as getSnowHistTableRowData return getSnowMetarHistTableRowData(report); } - private static TableRowData getSafeseasMaritimeHistTableRowData(ObReport report) { - TableRowData tblRowData = new TableRowData(15); - tblRowData.setTableCellData(0, new TableCellData(report.getObservationTime(),"HH:mm MMM dd",CellType.ObsHist)); - tblRowData.setTableCellData(1, - new TableCellData(Math.round(new Float(report.getWindSpeed())), - CellType.ObsHist, true)); - tblRowData.setTableCellData( - 2, - new TableCellData( - Math.round(new Float(report.getMaxWindSpeed())), - CellType.ObsHist, true)); - tblRowData.setTableCellData(3, - new TableCellData(Math.round(new Float(report.getWindGust())), - CellType.ObsHist, true)); - tblRowData.setTableCellData(4, - new TableCellData( - Math.round(new Float(report.getVisibility())), - CellType.ObsHist, true)); - tblRowData.setTableCellData(5, new TableCellData(report.getPressure(), CellType.ObsHist, CommonTableConfig.obsHistCols.P)); - tblRowData.setTableCellData( - 6, - new TableCellData(Math.round(new Float(report - .getPressureChange())), CellType.ObsHist, true)); - tblRowData.setTableCellData( - 7, - new TableCellData( - Math.round(new Float(report.getTemperature())), - CellType.ObsHist, true)); - tblRowData.setTableCellData(8, - new TableCellData(Math.round(new Float(report.getDewpoint())), - CellType.ObsHist, true)); - tblRowData.setTableCellData( - 9, - new TableCellData(Math.round(new Float(report - .getSeaSurfaceTemp())), CellType.ObsHist, true)); - tblRowData.setTableCellData( - 10, - new TableCellData(Math.round(new Float(report - .getHighResWaveHeight())), CellType.ObsHist, true)); - tblRowData.setTableCellData( - 11, - new TableCellData(Math.round(new Float(report - .getWaveSteepness())), CellType.ObsHist, true)); - tblRowData.setTableCellData( - 12, - new TableCellData( - Math.round(new Float(report.getPSwellHeight())), - CellType.ObsHist, true)); - tblRowData.setTableCellData( - 13, - new TableCellData( - Math.round(new Float(report.getPSwellPeriod())), - CellType.ObsHist, true)); - tblRowData.setTableCellData(14, - new TableCellData(Math.round(new Float(report.getPSwellDir())), - CellType.ObsHist, true)); - return tblRowData; - } + private static TableRowData getSafeseasMaritimeHistTableRowData( + ObReport report) { + TableRowData tblRowData = new TableRowData(17); + tblRowData.setTableCellData(0, + new TableCellData(report.getObservationTime(), "HH:mm MMM dd", + CellType.ObsHist)); + tblRowData.setTableCellData(1, + new TableCellData(new Float(report.getLatitude()), + CellType.ObsHist, true)); + tblRowData.setTableCellData(2, + new TableCellData(new Float(report.getLongitude()), + CellType.ObsHist, true)); + tblRowData.setTableCellData(3, + new TableCellData(Math.round(new Float(report.getWindSpeed())), + CellType.ObsHist, true)); + tblRowData.setTableCellData( + 4, + new TableCellData( + Math.round(new Float(report.getMaxWindSpeed())), + CellType.ObsHist, true)); + tblRowData.setTableCellData(5, + new TableCellData(Math.round(new Float(report.getWindGust())), + CellType.ObsHist, true)); + tblRowData.setTableCellData(6, + new TableCellData( + Math.round(new Float(report.getVisibility())), + CellType.ObsHist, true)); + tblRowData.setTableCellData(7, new TableCellData(report.getPressure(), + CellType.ObsHist, CommonTableConfig.obsHistCols.P)); + tblRowData.setTableCellData( + 8, + new TableCellData(Math.round(new Float(report + .getPressureChange())), CellType.ObsHist, true)); + tblRowData.setTableCellData( + 9, + new TableCellData( + Math.round(new Float(report.getTemperature())), + CellType.ObsHist, true)); + tblRowData.setTableCellData(10, + new TableCellData(Math.round(new Float(report.getDewpoint())), + CellType.ObsHist, true)); + tblRowData.setTableCellData( + 11, + new TableCellData(Math.round(new Float(report + .getSeaSurfaceTemp())), CellType.ObsHist, true)); + tblRowData.setTableCellData( + 12, + new TableCellData(Math.round(new Float(report + .getHighResWaveHeight())), CellType.ObsHist, true)); + tblRowData.setTableCellData( + 13, + new TableCellData(Math.round(new Float(report + .getWaveSteepness())), CellType.ObsHist, true)); + tblRowData.setTableCellData( + 14, + new TableCellData( + Math.round(new Float(report.getPSwellHeight())), + CellType.ObsHist, true)); + tblRowData.setTableCellData( + 15, + new TableCellData( + Math.round(new Float(report.getPSwellPeriod())), + CellType.ObsHist, true)); + tblRowData.setTableCellData(16, + new TableCellData(Math.round(new Float(report.getPSwellDir())), + CellType.ObsHist, true)); + return tblRowData; + } - private static TableRowData getFogMaritimeHistTableRowData(ObReport report) { - TableRowData tblRowData = new TableRowData(16); - tblRowData.setTableCellData(0, new TableCellData(report.getObservationTime(),"HH:mm MMM dd",CellType.ObsHist)); - tblRowData.setTableCellData(1, - new TableCellData(Math.round(new Float(report.getWindSpeed())), - CellType.ObsHist, true)); - tblRowData.setTableCellData( - 2, - new TableCellData( - Math.round(new Float(report.getMaxWindSpeed())), - CellType.ObsHist, true)); - tblRowData.setTableCellData(3, - new TableCellData(Math.round(new Float(report.getWindGust())), - CellType.ObsHist, true)); - tblRowData.setTableCellData(4, - new TableCellData( - Math.round(new Float(report.getVisibility())), - CellType.ObsHist, true)); - tblRowData.setTableCellData(5, new TableCellData(report.getPressure(), CellType.ObsHist, CommonTableConfig.obsHistCols.P)); - tblRowData.setTableCellData( - 6, - new TableCellData(Math.round(new Float(report - .getPressureChange())), CellType.ObsHist, true)); - tblRowData.setTableCellData( - 7, - new TableCellData( - Math.round(new Float(report.getTemperature())), - CellType.ObsHist, true)); - tblRowData.setTableCellData(8, - new TableCellData(Math.round(new Float(report.getDewpoint())), - CellType.ObsHist, true)); - tblRowData.setTableCellData( - 9, - new TableCellData(Math.round(new Float(report - .getSeaSurfaceTemp())), CellType.ObsHist, true)); - tblRowData.setTableCellData( - 10, - new TableCellData(Math.round(new Float(report - .getHighResWaveHeight())), CellType.ObsHist, true)); - tblRowData.setTableCellData( - 11, - new TableCellData(Math.round(new Float(report - .getWaveSteepness())), CellType.ObsHist, true)); - tblRowData.setTableCellData( - 12, - new TableCellData( - Math.round(new Float(report.getPSwellHeight())), - CellType.ObsHist, true)); - tblRowData.setTableCellData( - 13, - new TableCellData( - Math.round(new Float(report.getPSwellPeriod())), - CellType.ObsHist, true)); - tblRowData.setTableCellData(14, - new TableCellData(Math.round(new Float(report.getPSwellDir())), - CellType.ObsHist, true)); - tblRowData.setTableCellData( - 15, - new TableCellData(Math.round(new Float(report - .getRelativeHumidity())), CellType.ObsHist, true)); - return tblRowData; - } + private static TableRowData getFogMaritimeHistTableRowData(ObReport report) { + TableRowData tblRowData = new TableRowData(18); + tblRowData.setTableCellData(0, + new TableCellData(report.getObservationTime(), "HH:mm MMM dd", + CellType.ObsHist)); + tblRowData.setTableCellData(1, + new TableCellData(new Float(report.getLatitude()), + CellType.ObsHist, true)); + tblRowData.setTableCellData(2, + new TableCellData(new Float(report.getLongitude()), + CellType.ObsHist, true)); + tblRowData.setTableCellData(3, + new TableCellData(Math.round(new Float(report.getWindSpeed())), + CellType.ObsHist, true)); + tblRowData.setTableCellData( + 4, + new TableCellData( + Math.round(new Float(report.getMaxWindSpeed())), + CellType.ObsHist, true)); + tblRowData.setTableCellData(5, + new TableCellData(Math.round(new Float(report.getWindGust())), + CellType.ObsHist, true)); + tblRowData.setTableCellData(6, + new TableCellData( + Math.round(new Float(report.getVisibility())), + CellType.ObsHist, true)); + tblRowData.setTableCellData(7, new TableCellData(report.getPressure(), + CellType.ObsHist, CommonTableConfig.obsHistCols.P)); + tblRowData.setTableCellData( + 8, + new TableCellData(Math.round(new Float(report + .getPressureChange())), CellType.ObsHist, true)); + tblRowData.setTableCellData( + 9, + new TableCellData( + Math.round(new Float(report.getTemperature())), + CellType.ObsHist, true)); + tblRowData.setTableCellData(10, + new TableCellData(Math.round(new Float(report.getDewpoint())), + CellType.ObsHist, true)); + tblRowData.setTableCellData( + 11, + new TableCellData(Math.round(new Float(report + .getSeaSurfaceTemp())), CellType.ObsHist, true)); + tblRowData.setTableCellData( + 12, + new TableCellData(Math.round(new Float(report + .getHighResWaveHeight())), CellType.ObsHist, true)); + tblRowData.setTableCellData( + 13, + new TableCellData(Math.round(new Float(report + .getWaveSteepness())), CellType.ObsHist, true)); + tblRowData.setTableCellData( + 14, + new TableCellData( + Math.round(new Float(report.getPSwellHeight())), + CellType.ObsHist, true)); + tblRowData.setTableCellData( + 15, + new TableCellData( + Math.round(new Float(report.getPSwellPeriod())), + CellType.ObsHist, true)); + tblRowData.setTableCellData(16, + new TableCellData(Math.round(new Float(report.getPSwellDir())), + CellType.ObsHist, true)); + tblRowData.setTableCellData( + 17, + new TableCellData(Math.round(new Float(report + .getRelativeHumidity())), CellType.ObsHist, true)); + return tblRowData; + } - private static TableRowData getFogMetarHistTableRowData(ObReport report) { - TableRowData tblRowData = new TableRowData(12); - tblRowData.setTableCellData(0, new TableCellData(report.getObservationTime(),"HH:mm MMM dd",CellType.ObsHist)); - tblRowData.setTableCellData( - 1, - new TableCellData(Math.round(new Float(report - .getRelativeHumidity())), CellType.ObsHist, true)); - tblRowData.setTableCellData(2, - new TableCellData( - Math.round(new Float(report.getVisibility())), - CellType.ObsHist, true)); - tblRowData.setTableCellData(3, - new TableCellData(Math.round(new Float(report.getCeiling())), - CellType.ObsHist, true)); - tblRowData.setTableCellData(4, - new TableCellData(Math.round(new Float(report.getWindDir())), - CellType.ObsHist, true)); - tblRowData.setTableCellData(5, - new TableCellData(Math.round(new Float(report.getWindSpeed())), - CellType.ObsHist, true)); - tblRowData.setTableCellData(6, - new TableCellData(Math.round(new Float(report.getWindGust())), - CellType.ObsHist, true)); - tblRowData.setTableCellData(7, new TableCellData(report.getPressure(), CellType.ObsHist, CommonTableConfig.obsHistCols.P)); - int tmph = Math.round(new Float(report.getTemperature())); - int dpth = Math.round(new Float(report.getDewpoint())); - tblRowData.setTableCellData(8, new TableCellData(tmph, - CellType.ObsHist, true)); - tblRowData.setTableCellData(9, new TableCellData(dpth, - CellType.ObsHist, true)); - tblRowData.setTableCellData(10, new TableCellData(tmph - dpth, - CellType.ObsHist, true)); - tblRowData.setTableCellData(11, new TableCellData(report.getPressureChange(), CellType.ObsHist, CommonTableConfig.obsHistCols.PTend)); - return tblRowData; - } + private static TableRowData getFogMetarHistTableRowData(ObReport report) { + TableRowData tblRowData = new TableRowData(14); + tblRowData.setTableCellData(0, + new TableCellData(report.getObservationTime(), "HH:mm MMM dd", + CellType.ObsHist)); + tblRowData.setTableCellData(1, + new TableCellData(new Float(report.getLatitude()), + CellType.ObsHist, true)); + tblRowData.setTableCellData(2, + new TableCellData(new Float(report.getLongitude()), + CellType.ObsHist, true)); + tblRowData.setTableCellData( + 3, + new TableCellData(Math.round(new Float(report + .getRelativeHumidity())), CellType.ObsHist, true)); + tblRowData.setTableCellData(4, + new TableCellData( + Math.round(new Float(report.getVisibility())), + CellType.ObsHist, true)); + tblRowData.setTableCellData(5, + new TableCellData(Math.round(new Float(report.getCeiling())), + CellType.ObsHist, true)); + tblRowData.setTableCellData(6, + new TableCellData(Math.round(new Float(report.getWindDir())), + CellType.ObsHist, true)); + tblRowData.setTableCellData(7, + new TableCellData(Math.round(new Float(report.getWindSpeed())), + CellType.ObsHist, true)); + tblRowData.setTableCellData(8, + new TableCellData(Math.round(new Float(report.getWindGust())), + CellType.ObsHist, true)); + tblRowData.setTableCellData(9, new TableCellData(report.getPressure(), + CellType.ObsHist, CommonTableConfig.obsHistCols.P)); + int tmph = Math.round(new Float(report.getTemperature())); + int dpth = Math.round(new Float(report.getDewpoint())); + tblRowData.setTableCellData(10, new TableCellData(tmph, + CellType.ObsHist, true)); + tblRowData.setTableCellData(11, new TableCellData(dpth, + CellType.ObsHist, true)); + tblRowData.setTableCellData(12, new TableCellData(tmph - dpth, + CellType.ObsHist, true)); + tblRowData.setTableCellData(13, + new TableCellData(report.getPressureChange(), CellType.ObsHist, + CommonTableConfig.obsHistCols.PTend)); + return tblRowData; + } } diff --git a/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/ui/dialogs/StationTableComp.java b/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/ui/dialogs/StationTableComp.java index 0fda01f220..f15e3df3ac 100644 --- a/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/ui/dialogs/StationTableComp.java +++ b/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/ui/dialogs/StationTableComp.java @@ -301,7 +301,7 @@ public class StationTableComp extends TableComp { * @param name */ public void setIdLabel(String name) { - idLbl.setText("Zone/County: " + name); + idLbl.setText("Zone/County: "+ this.id +" - "+ name); controlComp.layout(); } diff --git a/cave/com.raytheon.uf.viz.radarapps.core/src/com/raytheon/uf/viz/radarapps/client/RcmClient.java b/cave/com.raytheon.uf.viz.radarapps.core/src/com/raytheon/uf/viz/radarapps/client/RcmClient.java index 0a8a95501d..3887a91ecc 100644 --- a/cave/com.raytheon.uf.viz.radarapps.core/src/com/raytheon/uf/viz/radarapps/client/RcmClient.java +++ b/cave/com.raytheon.uf.viz.radarapps.core/src/com/raytheon/uf/viz/radarapps/client/RcmClient.java @@ -61,7 +61,6 @@ import com.raytheon.rcm.mqsrvr.ReqObj; import com.raytheon.rcm.rmr.RmrEvent; import com.raytheon.uf.common.dataplugin.radar.request.RadarServerConnectionRequest; import com.raytheon.uf.viz.core.exception.VizException; -import com.raytheon.uf.viz.core.preferences.JMSPreferences; import com.raytheon.uf.viz.core.requests.ThriftClient; // TODO: use of queueSession outside synchronized(stateLock) could cause @@ -69,6 +68,23 @@ import com.raytheon.uf.viz.core.requests.ThriftClient; // TODO: conflicts over setting fatalMsg +/** + * Manages client connection to RadarServer + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer     Description
+ * ------------ ---------- ------------ --------------------------
+ * ????                    D. Friedman  Initial version
+ * 2012-07-27   DR 14896   D. Friedman  Fix even topic name
+ * 
+ * 
+ * + * @author dfriedma + * @version 1.0 + */ public class RcmClient implements MessageListener, ExceptionListener { private String connectionURL; @@ -211,6 +227,11 @@ public class RcmClient implements MessageListener, ExceptionListener { return; } + /* + * TODO: ActiveMQ is hard-coded. If switching to Qpid or another + * service, it may be necessary to use JMSPreferences.getPolicyString on + * the topic name below. + */ ActiveMQConnectionFactory connFac = new ActiveMQConnectionFactory(uri); // This stuff can block... try { @@ -238,8 +259,7 @@ public class RcmClient implements MessageListener, ExceptionListener { topicConn.setExceptionListener(this); topicSession = topicConn.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); - topic = topicSession.createTopic(JMSPreferences - .getPolicyString("RadarEvents")); + topic = topicSession.createTopic("RadarEvents"); queueConn.start(); topicConn.start(); diff --git a/cave/com.raytheon.uf.viz.xy.crosssection/src/com/raytheon/uf/viz/xy/crosssection/rsc/AbstractCrossSectionResource.java b/cave/com.raytheon.uf.viz.xy.crosssection/src/com/raytheon/uf/viz/xy/crosssection/rsc/AbstractCrossSectionResource.java index 00e4e60017..1f22a67fc5 100644 --- a/cave/com.raytheon.uf.viz.xy.crosssection/src/com/raytheon/uf/viz/xy/crosssection/rsc/AbstractCrossSectionResource.java +++ b/cave/com.raytheon.uf.viz.xy.crosssection/src/com/raytheon/uf/viz/xy/crosssection/rsc/AbstractCrossSectionResource.java @@ -231,11 +231,13 @@ public abstract class AbstractCrossSectionResource extends time = time.clone(); time.setLevelValue((double) i); times.add(time); + sliceMap.put(time, null); + dataRetrievalJob.times.add(time); } } dataTimes = new ArrayList(times); Collections.sort(dataTimes); - sliceMap.clear(); + dataRetrievalJob.schedule(); } protected void loadSlice(DataTime time) throws VizException { diff --git a/cave/com.raytheon.uf.viz.xy.crosssection/src/com/raytheon/uf/viz/xy/crosssection/rsc/CrossSectionImageResource.java b/cave/com.raytheon.uf.viz.xy.crosssection/src/com/raytheon/uf/viz/xy/crosssection/rsc/CrossSectionImageResource.java index ed4305482d..9a914fa082 100644 --- a/cave/com.raytheon.uf.viz.xy.crosssection/src/com/raytheon/uf/viz/xy/crosssection/rsc/CrossSectionImageResource.java +++ b/cave/com.raytheon.uf.viz.xy.crosssection/src/com/raytheon/uf/viz/xy/crosssection/rsc/CrossSectionImageResource.java @@ -136,10 +136,12 @@ public class CrossSectionImageResource extends AbstractCrossSectionResource super.initInternal(target); // defaults - ImagingCapability imageCap = getCapability(ImagingCapability.class); - imageCap.setInterpolationState(true); - imageCap.setBrightness(1.0f); - imageCap.setContrast(1.0f); + if (!hasCapability(ImagingCapability.class)) { + ImagingCapability imageCap = getCapability(ImagingCapability.class); + imageCap.setInterpolationState(true); + imageCap.setBrightness(1.0f); + imageCap.setContrast(1.0f); + } } private IImage constructImage(float[] floatData, IGraphicsTarget target) diff --git a/cave/com.raytheon.uf.viz.xy.timeheight/src/com/raytheon/uf/viz/xy/timeheight/rsc/AbstractTimeHeightResource.java b/cave/com.raytheon.uf.viz.xy.timeheight/src/com/raytheon/uf/viz/xy/timeheight/rsc/AbstractTimeHeightResource.java index b35100d512..b8cb40b58f 100644 --- a/cave/com.raytheon.uf.viz.xy.timeheight/src/com/raytheon/uf/viz/xy/timeheight/rsc/AbstractTimeHeightResource.java +++ b/cave/com.raytheon.uf.viz.xy.timeheight/src/com/raytheon/uf/viz/xy/timeheight/rsc/AbstractTimeHeightResource.java @@ -450,6 +450,7 @@ public abstract class AbstractTimeHeightResource extends secondaryResource.setDescriptor(descriptor); } super.setDescriptor(descriptor); + interpolatedData = null; loadDataJob.schedule(); } diff --git a/cave/com.raytheon.uf.viz.xy.timeseries/src/com/raytheon/uf/viz/xy/timeseries/rsc/TimeSeriesResource.java b/cave/com.raytheon.uf.viz.xy.timeseries/src/com/raytheon/uf/viz/xy/timeseries/rsc/TimeSeriesResource.java index 6be8e20194..9e8e7b17d0 100644 --- a/cave/com.raytheon.uf.viz.xy.timeseries/src/com/raytheon/uf/viz/xy/timeseries/rsc/TimeSeriesResource.java +++ b/cave/com.raytheon.uf.viz.xy.timeseries/src/com/raytheon/uf/viz/xy/timeseries/rsc/TimeSeriesResource.java @@ -26,6 +26,7 @@ import java.util.Calendar; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.ListIterator; import java.util.Set; import java.util.TimeZone; import java.util.TreeSet; @@ -76,6 +77,7 @@ import com.raytheon.viz.core.graphing.util.GraphPrefsFactory; import com.raytheon.viz.core.graphing.xy.XYData; import com.raytheon.viz.core.graphing.xy.XYDataList; import com.raytheon.viz.core.graphing.xy.XYImageData; +import com.raytheon.viz.core.graphing.xy.XYWindImageData; import com.raytheon.viz.core.rsc.ICombinedResourceData; import com.raytheon.viz.core.rsc.ICombinedResourceData.CombineOperation; import com.raytheon.viz.core.style.graph.GraphPreferences; @@ -157,10 +159,22 @@ public class TimeSeriesResource extends if (currentUnit.isCompatible(prefs.getDisplayUnits())) { UnitConverter conv = currentUnit.getConverterTo(prefs .getDisplayUnits()); - for (XYData d : data.getData()) { - double converted = conv.convert(((Number) d.getY()) - .doubleValue()); - d.setY(converted); + ListIterator it = data.getData().listIterator(); + while(it.hasNext()) { + XYData d = it.next(); + if(d instanceof XYWindImageData){ + XYWindImageData wind = (XYWindImageData) d; + double converted = conv.convert(wind.getWindSpd()); + it.remove(); + if(wind.getImage() != null){ + wind.getImage().dispose(); + } + it.add(new XYWindImageData(wind.getX(), wind.getY(), converted, wind.getWindDir())); + }else{ + double converted = conv.convert(((Number) d.getY()) + .doubleValue()); + d.setY(converted); + } } units = prefs.getDisplayUnitLabel(); } else { @@ -457,13 +471,6 @@ public class TimeSeriesResource extends String lat = nf.format(Math.abs(y)); String stnID = ""; String source = resourceData.getSource(); - String unit = ""; - - if (prefs != null && prefs.getDisplayUnits() != null) { - unit = prefs.getDisplayUnitLabel(); - } else { - unit = adapter.getDataUnit().toString(); - } if (resourceData.getMetadataMap().get("location.stationId") != null) { stnID = resourceData.getMetadataMap().get("location.stationId") @@ -488,7 +495,7 @@ public class TimeSeriesResource extends sb.append(" ").append(resourceData.getLevelKey()); } sb.append(String.format(" %s %s %s", adapter.getParameterName(), - "TSer", unit != null && unit.equals("") == false ? "(" + unit + "TSer", units != null && units.equals("") == false ? "(" + units + ")" : "")); if (secondaryResource != null) { diff --git a/cave/com.raytheon.uf.viz.xy.varheight/src/com/raytheon/uf/viz/xy/varheight/util/ScaleHandler.java b/cave/com.raytheon.uf.viz.xy.varheight/src/com/raytheon/uf/viz/xy/varheight/util/ScaleHandler.java index d1e49fe28c..a669e8f8fb 100644 --- a/cave/com.raytheon.uf.viz.xy.varheight/src/com/raytheon/uf/viz/xy/varheight/util/ScaleHandler.java +++ b/cave/com.raytheon.uf.viz.xy.varheight/src/com/raytheon/uf/viz/xy/varheight/util/ScaleHandler.java @@ -26,6 +26,7 @@ import org.eclipse.core.commands.ExecutionException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.commands.ICommandService; +import com.raytheon.uf.viz.core.IDisplayPane; import com.raytheon.uf.viz.core.IDisplayPaneContainer; import com.raytheon.uf.viz.core.globals.VizGlobalsManager; import com.raytheon.uf.viz.d2d.core.ID2DRenderableDisplay; @@ -75,30 +76,29 @@ public class ScaleHandler extends AbstractHandler { * @param scale */ static void setScale(IDisplayPaneContainer editor, String scale) { - if (editor.getActiveDisplayPane().getRenderableDisplay() instanceof ID2DRenderableDisplay) { - ID2DRenderableDisplay disp = (ID2DRenderableDisplay) editor - .getActiveDisplayPane().getRenderableDisplay(); + for (IDisplayPane pane : editor.getDisplayPanes()) { + if (pane.getRenderableDisplay() instanceof ID2DRenderableDisplay) { + ID2DRenderableDisplay disp = (ID2DRenderableDisplay) pane + .getRenderableDisplay(); + if (scale.equals(disp.getScale())) { + // don't set the scale if it is the same as the display's + // current scale + return; + } - if (scale.equals(disp.getScale())) { - // don't set the scale if it is the same as the display's - // current - // scale - return; + disp.setScale(scale); + if (pane == editor.getActiveDisplayPane()) { + VizGlobalsManager.getCurrentInstance().updateChanges( + editor.getActiveDisplayPane() + .getRenderableDisplay().getGlobalsMap()); + } } - - disp.setScale(scale); - - // update the scale button - final ICommandService service = (ICommandService) PlatformUI - .getWorkbench().getService(ICommandService.class); - - VizGlobalsManager.getCurrentInstance().updateChanges( - editor.getActiveDisplayPane().getRenderableDisplay() - .getGlobalsMap()); - - service.refreshElements( - "com.raytheon.uf.viz.xy.height.scalebutton", null); } + + ICommandService service = (ICommandService) PlatformUI.getWorkbench() + .getService(ICommandService.class); + service.refreshElements("com.raytheon.uf.viz.xy.height.scalebutton", + null); } } diff --git a/cave/com.raytheon.viz.aviation/plugin.xml b/cave/com.raytheon.viz.aviation/plugin.xml index 8d2737e59a..2a6e132304 100644 --- a/cave/com.raytheon.viz.aviation/plugin.xml +++ b/cave/com.raytheon.viz.aviation/plugin.xml @@ -87,5 +87,12 @@ value="aviation/config" recursive="true"> + + diff --git a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/climatology/WindRosePlotDlg.java b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/climatology/WindRosePlotDlg.java index bffc923418..db908b75f9 100755 --- a/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/climatology/WindRosePlotDlg.java +++ b/cave/com.raytheon.viz.aviation/src/com/raytheon/viz/aviation/climatology/WindRosePlotDlg.java @@ -55,7 +55,6 @@ import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Spinner; - import com.raytheon.viz.avncommon.AvnMessageMgr.StatusMessageType; import com.raytheon.viz.avnconfig.HelpUsageDlg; import com.raytheon.viz.avnconfig.ITafSiteConfig; @@ -80,6 +79,8 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog; * 9/12/2008 1444 grichard Accommodate separate message logs. * 3/31/2011 8774 rferrel killProcess when doing a disposed * 4/14/2011 8861 rferrel Use SaveImageDlg class + * 23JUL2012 15169 zhao Use Combo for 'Month' and 'Number of Months' + * & disabled site controls while drawing * * * @@ -101,14 +102,14 @@ public class WindRosePlotDlg extends CaveSWTDialog { private List siteList; /** - * Month spinner. + * Month */ - private Spinner monthSpnr; + private Combo monthCbo; /** * Number of months. */ - private Spinner numMonthsSpnr; + private Combo numMonthsCbo; /** * Hours spinner. @@ -427,20 +428,19 @@ public class WindRosePlotDlg extends CaveSWTDialog { Label monthLbl = new Label(monthHourComp, SWT.NONE); monthLbl.setText("Month:"); - gd = new GridData(40, SWT.DEFAULT); - monthSpnr = new Spinner(monthHourComp, SWT.BORDER); - monthSpnr.setDigits(0); - monthSpnr.setIncrement(1); - monthSpnr.setPageIncrement(3); - monthSpnr.setMinimum(1); - monthSpnr.setMaximum(12); - monthSpnr.setSelection(cal.get(Calendar.MONTH) + 1); - monthSpnr.setLayoutData(gd); - monthSpnr.addSelectionListener(new SelectionAdapter() { + gd = new GridData(66, SWT.DEFAULT); + monthCbo = new Combo(monthHourComp, SWT.DROP_DOWN | SWT.READ_ONLY); + monthCbo.setLayoutData(gd); + for ( int i = 1; i <= 12; i++ ) { + monthCbo.add(""+i, i-1); + } + monthCbo.select(cal.get(Calendar.MONTH)); + monthCbo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { + //System.out.println(" *************** monthsCbo.getText() = " + monthCbo.getText() ); if (autoRedrawChk.getSelection()) { - redrawWindRose(); + redrawWindRose(); } } }); @@ -448,20 +448,19 @@ public class WindRosePlotDlg extends CaveSWTDialog { Label numMonthLbl = new Label(monthHourComp, SWT.NONE); numMonthLbl.setText("Num Months:"); - gd = new GridData(40, SWT.DEFAULT); - numMonthsSpnr = new Spinner(monthHourComp, SWT.BORDER); - numMonthsSpnr.setDigits(0); - numMonthsSpnr.setIncrement(1); - numMonthsSpnr.setPageIncrement(3); - numMonthsSpnr.setMinimum(1); - numMonthsSpnr.setMaximum(12); - numMonthsSpnr.setSelection(1); - numMonthsSpnr.setLayoutData(gd); - numMonthsSpnr.addSelectionListener(new SelectionAdapter() { + gd = new GridData(66, SWT.DEFAULT); + numMonthsCbo = new Combo(monthHourComp, SWT.DROP_DOWN | SWT.READ_ONLY); + numMonthsCbo.setLayoutData(gd); + for ( int i = 1; i <= 12; i++ ) { + numMonthsCbo.add(""+i, i-1); + } + numMonthsCbo.select(0); + numMonthsCbo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { + //System.out.println(" *************** numMonthsCbo.getText() = " + numMonthsCbo.getText() ); if (autoRedrawChk.getSelection()) { - redrawWindRose(); + redrawWindRose(); } } }); @@ -586,8 +585,10 @@ public class WindRosePlotDlg extends CaveSWTDialog { generateWindRoseHeader(); windRoseCanvasComp.updateAndRedraw(windRoseConfigData.cloneData(), - windRoseHeader, monthSpnr.getText(), - numMonthsSpnr.getText(), hourSpnr.getText(), + windRoseHeader, + monthCbo.getText(), + numMonthsCbo.getText(), + hourSpnr.getText(), numHoursSpnr.getText(), flightCatCbo.getSelectionIndex(), siteList.getItem(siteList.getSelectionIndex()), this); } @@ -599,11 +600,21 @@ public class WindRosePlotDlg extends CaveSWTDialog { if (state == true) { ++busyCount; shell.setCursor(waitCursor); + monthCbo.setEnabled(false); + numMonthsCbo.setEnabled(false); + hourSpnr.setEnabled(false); + numHoursSpnr.setEnabled(false); + flightCatCbo.setEnabled(false); drawBtn.setEnabled(false); } else { --busyCount; if (busyCount == 0) { shell.setCursor(defaultCursor); + monthCbo.setEnabled(true); + numMonthsCbo.setEnabled(true); + hourSpnr.setEnabled(true); + numHoursSpnr.setEnabled(true); + flightCatCbo.setEnabled(true); drawBtn.setEnabled(true); } } @@ -634,23 +645,21 @@ public class WindRosePlotDlg extends CaveSWTDialog { header.append(siteList.getItem(siteList.getSelectionIndex())); header.append(" "); - header.append(MONTHS[monthSpnr.getSelection() - 1]); + header.append(MONTHS[monthCbo.getSelectionIndex()]); - if (numMonthsSpnr.getSelection() == 1) { + if ( numMonthsCbo.getSelectionIndex() == 0 ) { header.append(" "); } else { header.append("-"); int endMonth = 0; - if (((numMonthsSpnr.getSelection() - 1) + monthSpnr.getSelection()) > 12) { - endMonth = (numMonthsSpnr.getSelection() - 1) - + monthSpnr.getSelection() - 12; - header.append(MONTHS[endMonth - 1]); + if ( ( numMonthsCbo.getSelectionIndex() + monthCbo.getSelectionIndex() ) > 11 ) { + endMonth = numMonthsCbo.getSelectionIndex() + monthCbo.getSelectionIndex() - 12; + header.append(MONTHS[endMonth]); } else { - endMonth = (numMonthsSpnr.getSelection() - 1) - + monthSpnr.getSelection(); - header.append(MONTHS[endMonth - 1]); + endMonth = numMonthsCbo.getSelectionIndex() + monthCbo.getSelectionIndex(); + header.append(MONTHS[endMonth]); } header.append(" "); } diff --git a/cave/com.raytheon.viz.bcd/src/com/raytheon/viz/bcd/BCDResource.java b/cave/com.raytheon.viz.bcd/src/com/raytheon/viz/bcd/BCDResource.java index 063bebf687..ee088160f1 100644 --- a/cave/com.raytheon.viz.bcd/src/com/raytheon/viz/bcd/BCDResource.java +++ b/cave/com.raytheon.viz.bcd/src/com/raytheon/viz/bcd/BCDResource.java @@ -26,6 +26,7 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.nio.channels.FileChannel; import java.nio.channels.FileChannel.MapMode; import java.util.ArrayList; @@ -69,6 +70,7 @@ import com.vividsolutions.jts.geom.Coordinate; * 7/1/06 chammack Initial Creation. * 1/10/08 562 bphillip Modified to handle .bcx files * 02/11/09 njensen Refactored to new rsc architecture + * 07/31/12 DR 14935 D. Friedman Handle little-endian files * * * @@ -190,6 +192,14 @@ public class BCDResource extends ByteBuffer buffer = fc.map(MapMode.READ_ONLY, 0, file.length()); + // Determine byte order of data + if (buffer.remaining() >= 4) { + // Whether BCX or not, first value is an int. + // Note: Different from A1 which tests >31 or >500 + if (buffer.getInt(0) > Short.MAX_VALUE) + buffer.order(ByteOrder.LITTLE_ENDIAN); + } + int i = 0; double minLat = Double.MAX_VALUE; diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/FormatterLauncherDialog.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/FormatterLauncherDialog.java index e1d95dadb0..9f123d61a4 100755 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/FormatterLauncherDialog.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/FormatterLauncherDialog.java @@ -88,6 +88,7 @@ import com.raytheon.viz.ui.dialogs.CaveJFACEDialog; * practice and test modes * Sep 16, 2010 6831 ryu Show same product for different areas on a sub-menu * Nov 22, 2011 8781 mli remove Processor menu + * Jul 26, 2012 15165 ryu Set default db source when formatter has no db defined. * * * @@ -776,6 +777,8 @@ public class FormatterLauncherDialog extends CaveJFACEDialog implements ProductDefinition prodDef = textProductMgr .getProductDefinition(productName); String dataSource = (String) prodDef.get("database"); + if (dataSource == null) + dataSource = "Official"; if (dataSource.equals("ISC")) { selectedDataSource = getIscDataSource(); diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/edittool/sample/SamplePainter.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/edittool/sample/SamplePainter.java index bae55eb71d..03d528d974 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/edittool/sample/SamplePainter.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/edittool/sample/SamplePainter.java @@ -66,6 +66,8 @@ import com.vividsolutions.jts.geom.Coordinate; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 04/08/2008 chammack Initial Port from AWIPS I (minus ISC support) + * 07/23/2012 #936 dgilling Reinstate config-handling code to + * calcGridLabels(). * * * @@ -253,7 +255,7 @@ public class SamplePainter { private void calcGridLabels(Coordinate worldLoc, final List grids, final GridID imageGrid, List sampleLabels, List colors) { - if (grids.size() == 0) { + if (grids.isEmpty()) { return; } @@ -261,9 +263,9 @@ public class SamplePainter { // all parms List limitSamples = Arrays.asList(Activator.getDefault() .getPreferenceStore().getStringArray("SampleParms")); + // assumes all grids shared same grid location. boolean inGrid = false; - Coordinate gridCoordinate = MapUtil.latLonToGridCoordinate(worldLoc, PixelOrientation.UPPER_LEFT, grids.get(0).getParm() .getGridInfo().getGridLoc()); @@ -280,27 +282,41 @@ public class SamplePainter { inGrid = true; } - // sample label color - RGB labelColor = new RGB(255, 255, 255); - // get the list of samples that should be painted and in the // order for (GridID grid : grids) { String pName = grid.getParm().getParmID().compositeNameUI(); // do we plot this weather element? - if ((limitSamples.size() != 0) && !limitSamples.contains(pName)) { + if ((!limitSamples.isEmpty()) && !limitSamples.contains(pName)) { continue; // skip } + // calculate color + RGB labelColor = grid.getParm().getDisplayAttributes() + .getBaseColor(); + + if (grid.equals(imageGrid)) { + RGB color = new RGB(255, 255, 255); + String colorName = Activator.getDefault().getPreferenceStore() + .getString("ImageLegend_color"); + if (!colorName.isEmpty()) { + color = RGBColors.getRGBColor(colorName); + } + labelColor = color; + } + String parmColorName = Activator.getDefault().getPreferenceStore() + .getString(pName + "_Sample_color"); + if (!parmColorName.isEmpty()) { + labelColor = RGBColors.getRGBColor(parmColorName); + } + // get the data value String label = NO_DATA_LABEL; if (inGrid) { - // isc mode or grid from isc database if (showISC || grid.getParm().getParmState().isIscParm()) { label = iscSampleLabel(grid, gridCoordinate); - } else if (showDataValues) { final IGridData gridData = grid.grid(); if (gridData != null) { diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/edittool/sample/SampleRenderable.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/edittool/sample/SampleRenderable.java index 4a9f2b70e0..675a712363 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/edittool/sample/SampleRenderable.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/edittool/sample/SampleRenderable.java @@ -38,6 +38,7 @@ import com.raytheon.viz.gfe.core.msgs.Message; import com.raytheon.viz.gfe.core.msgs.Message.IMessageClient; import com.raytheon.viz.gfe.core.msgs.ShowQuickViewDataMsg; import com.raytheon.viz.gfe.core.parm.Parm; +import com.raytheon.viz.gfe.core.parm.ParmDisplayAttributes.VisMode; import com.raytheon.viz.gfe.edittool.EditToolPaintProperties; import com.raytheon.viz.gfe.edittool.GridID; import com.raytheon.viz.gfe.rsc.GFEFonts; @@ -45,16 +46,18 @@ import com.vividsolutions.jts.geom.Coordinate; /** * Handles the display for on-demand sampling capability. - * - * Roughly based on AWIPS I class of the same name. + *

+ * Roughly based on AWIPS I class SampleVisual. * *

  * SOFTWARE HISTORY
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
  * 04/08/2008              chammack    Initial Creation.
- * 11Jun2008    #1193       ebabin      Updates for toggling lat/lon for sample set.
+ * 06/11/2008   #1193      ebabin      Updates for toggling lat/lon for sample set.
  * 07/21/2009              bphillip    Removed the points field
+ * 07/23/2012   #936       dgilling    Properly retrieve imageGrid for paintMarkers()
+ *                                     and paintSamples().
  * 
  * 
* @@ -148,13 +151,17 @@ public class SampleRenderable implements IRenderable, IMessageClient { imageGrid = qvGrid; } else { Parm[] parms = sdm.getCurrentlyEnabledParms(); - Parm imageParm = sdm.getActivatedParm(); + Parm imageParm = null; Arrays.sort(parms); gids = new ArrayList(parms.length); - Date date = sdm.getSpatialEditorTime(); - for (int i = 0; i < parms.length; i++) { - gids.add(new GridID(parms[i], date)); + + for (Parm p : parms) { + gids.add(new GridID(p, date)); + + if (p.getDisplayAttributes().getVisMode() == VisMode.IMAGE) { + imageParm = p; + } } imageGrid = new GridID(imageParm, date); @@ -184,12 +191,16 @@ public class SampleRenderable implements IRenderable, IMessageClient { Date date = sdm.getSpatialEditorTime(); Parm[] parms = sdm.getCurrentlyEnabledParms(); - Parm imageParm = sdm.getActivatedParm(); + Parm imageParm = null; Arrays.sort(parms); GridID[] grids = new GridID[parms.length]; for (int i = 0; i < parms.length; i++) { grids[i] = new GridID(parms[i], date); + + if (parms[i].getDisplayAttributes().getVisMode() == VisMode.IMAGE) { + imageParm = parms[i]; + } } GridID imageGrid = new GridID(imageParm, date); diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/smarttool/Tool.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/smarttool/Tool.java index 70ed2e10ef..f5f1fbd529 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/smarttool/Tool.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/smarttool/Tool.java @@ -603,7 +603,9 @@ public class Tool { parmToEdit.startParmEdit(new Date[] { timeInfluence }); } catch (GFEOperationFailedException e) { statusHandler.handle(Priority.PROBLEM, - "Error during start parm edit", e); + "Error during start parm edit for " + toolName + " - already running." + + " Please wait for the operation to complete and try again.", + e); return; } startedParmEdit = true; diff --git a/cave/com.raytheon.viz.grid/localization/styleRules/gridImageryStyleRules.xml b/cave/com.raytheon.viz.grid/localization/styleRules/gridImageryStyleRules.xml index 3a65243be8..da570400d3 100644 --- a/cave/com.raytheon.viz.grid/localization/styleRules/gridImageryStyleRules.xml +++ b/cave/com.raytheon.viz.grid/localization/styleRules/gridImageryStyleRules.xml @@ -2422,12 +2422,12 @@ % - 5 + -1 105 Grid/warm to cold - 20 + 20 40 60 80 100 diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/GridResourceData.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/GridResourceData.java index 875a7612a2..474a6b69aa 100644 --- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/GridResourceData.java +++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/GridResourceData.java @@ -162,6 +162,7 @@ public class GridResourceData extends AbstractRequestableResourceData implements sampling = sampling == null ? false : sampling; return new GridIconResource(this, loadProperties); case BARB: + sampling = sampling == null ? false : sampling; case ARROW: case DUALARROW: case STREAMLINE: @@ -170,7 +171,7 @@ public class GridResourceData extends AbstractRequestableResourceData implements // grib data in D2D is in one location. There are only a few // products that do not work correctly, contours of vector // direction, and data mapped images. - sampling = sampling == null ? false : sampling; + sampling = sampling == null ? true : sampling; return new D2DGribGridResource(this, loadProperties); case CONTOUR: default: diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/GridVectorResource.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/GridVectorResource.java index 8fa9be7ced..816bdd558a 100644 --- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/GridVectorResource.java +++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/GridVectorResource.java @@ -108,6 +108,7 @@ import com.vividsolutions.jts.geom.Coordinate; * 05/16/2012 14993 D. Friedman Fix "blocky" contours * 06/19/2012 14988 D. Friedman Reproject based on conformality * 07/09/2012 14940 M. Porricelli Apply reprojection to streamlines + * 07/23/2012 14968 M. Porricelli Changed wording of streamline legend * * * @@ -484,7 +485,7 @@ public class GridVectorResource extends AbstractMapVectorResource implements legendParams.dataTime = getDisplayedDataTime(); if (displayType == DisplayType.STREAMLINE) { - legendParams.type = " Streamlines"; + legendParams.type = " Strmlns"; } else if (displayType == DisplayType.BARB) { legendParams.type = "Wind Barbs"; } else if (displayType == DisplayType.ARROW) { @@ -519,7 +520,7 @@ public class GridVectorResource extends AbstractMapVectorResource implements legendParams.dataTime = getDisplayedDataTime(); if (displayType == DisplayType.STREAMLINE) { - legendParams.type = " Streamlines"; + legendParams.type = " Strmlns"; } else if (displayType == DisplayType.BARB) { legendParams.type = "Wind Barbs"; } else if (displayType == DisplayType.ARROW) { diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/D2DGribGridResource.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/D2DGribGridResource.java index 1c942e2844..8dcbd1e285 100644 --- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/D2DGribGridResource.java +++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/D2DGribGridResource.java @@ -70,6 +70,8 @@ import com.vividsolutions.jts.geom.Coordinate; * ------------ ---------- ----------- -------------------------- * Mar 9, 2011 bsteffen Initial creation * 06/19/2012 14988 D. Friedman Reproject based on conformality + * 07/23/2012 14968 M. Porricelli Changed wording of streamline + * legend * * * @@ -247,7 +249,7 @@ public class D2DGribGridResource extends GribGridResource // The default type does not display in the legend legendParams.type = ""; } else if (displayType == DisplayType.STREAMLINE) { - legendParams.type = "Streamlines"; + legendParams.type = "Strmlns"; } else if (displayType == DisplayType.BARB) { legendParams.type = "Wind Barbs"; } else if (displayType == DisplayType.ARROW) { diff --git a/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/flashfloodguidance/FlashFloodGuidanceDlg.java b/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/flashfloodguidance/FlashFloodGuidanceDlg.java index 953d9b0b1b..b91ddd7bbb 100644 --- a/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/flashfloodguidance/FlashFloodGuidanceDlg.java +++ b/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/flashfloodguidance/FlashFloodGuidanceDlg.java @@ -237,7 +237,7 @@ public class FlashFloodGuidanceDlg extends CaveSWTDialog { /** * The duration in millis being displayed. */ - private int duration; + private int duration = 3600; /** * Holds the display string and insert time for later use. @@ -1126,7 +1126,7 @@ public class FlashFloodGuidanceDlg extends CaveSWTDialog { String day = parts[2]; String date = parts[3]; String hour = parts[4]; - duration = Integer.parseInt(durationStr) * FFGConstants.MILLIS_PER_HOUR; + duration = Integer.parseInt(durationStr) * FFGConstants.SECONDS_PER_HOUR; String paramAbr = "FFG" + durationStr + "24hr"; 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 6463f4d2cf..76f871ad7c 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 @@ -119,7 +119,9 @@ import com.vividsolutions.jts.index.strtree.STRtree; * Apr 5, 2011 8910 jpiatt Adjusted resource coordinates. * * May 16, 2011 9356 djingtao When timeseries is disposed, launch a new timesereis after double click - * or right click to select TimeSeries + * or right click to select TimeSeries. + * Jul 23, 2012 15167 mpduff Sampling now displays for all stations that are very close + * together or overlapping. * * * @@ -946,6 +948,8 @@ public class MultiPointResource extends @Override public String inspect(ReferencedCoordinate coord) throws VizException { try { + StringBuilder buffer = new StringBuilder(); + boolean first = true; Envelope env = new Envelope(coord.asLatLon()); List elements = strTree.query(env); if (elements.size() > 0) { @@ -953,11 +957,18 @@ public class MultiPointResource extends while (iter.hasNext()) { ArrayList list = (ArrayList) iter.next(); if (list.get(1) instanceof String) { - return (String) list.get(1); - } else { - return null; + if (!first) { + buffer.append("\n"); + } + buffer.append((String) list.get(1)); + first = false; } } + if (buffer.length() > 0) { + return buffer.toString(); + } else { + return null; + } } } catch (Exception e) { throw new VizException(e); diff --git a/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/timeseries/TimeSeriesDisplayDlg.java b/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/timeseries/TimeSeriesDisplayDlg.java index cdb7102a22..d034dafafe 100644 --- a/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/timeseries/TimeSeriesDisplayDlg.java +++ b/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/timeseries/TimeSeriesDisplayDlg.java @@ -87,8 +87,9 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog; * so that it would place the * entire time series within the * printable area of the page. - * 04 Mar 2011 7644 lbousaid fixed Zoom in feature - * 30 May 2012 14967 wkwock fix insert deleted data to rejecteddata table + * 04 Mar 2011 7644 lbousaid fixed Zoom in feature + * 30 May 2012 14967 wkwock fix insert deleted data to rejecteddata table + * 23 Jul 2012 15195 mpduff Fix dates for displaying groups * * * @@ -1360,22 +1361,9 @@ public class TimeSeriesDisplayDlg extends CaveSWTDialog { linesMI.setSelection(true); } - /* Get time data from group info */ - int pastHours = groupInfo.getPastHours(); - int futureHours = groupInfo.getFutureHours(); - - Calendar futureCal = Calendar.getInstance(TimeZone - .getTimeZone("GMT")); - Date d = SimulatedTime.getSystemTime().getTime(); - futureCal.setTime(d); - futureCal.add(Calendar.HOUR_OF_DAY, futureHours); - Calendar pastCal = Calendar.getInstance(TimeZone - .getTimeZone("GMT")); - pastCal.setTime(d); - pastCal.add(Calendar.HOUR_OF_DAY, pastHours * -1); displayCanvas = new TimeSeriesDisplayCanvas(this, - canvasComp, gd, pastCal.getTime(), - futureCal.getTime(), groupInfo.isGroupSelected()); + canvasComp, gd, beginDate, + endDate, groupInfo.isGroupSelected()); displayCanvas.setHorizontalSpan(gd.getXsize()); displayCanvas.setVerticalSpan(gd.getYsize()); displayCanvas.showGridLines(groupInfo.isGridLines()); diff --git a/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/timeseries/TimeSeriesDlg.java b/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/timeseries/TimeSeriesDlg.java index c473e39c1c..27ca9dc4d4 100644 --- a/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/timeseries/TimeSeriesDlg.java +++ b/cave/com.raytheon.viz.hydro/src/com/raytheon/viz/hydro/timeseries/TimeSeriesDlg.java @@ -111,6 +111,8 @@ import com.raytheon.viz.hydrocommon.util.StnClassSyncUtil; * be ran as a standalone application * without starting CAVE. * 01 June 2011 9499 djingtao update openGraph() + * 23 Jul 2012 15180 mpduff Auto select the first group in the predefined group list + * 23 Jul 2012 15195 mpduff Fix Group graphing to use the date widgets. * * * @author lvenable @@ -437,6 +439,9 @@ public class TimeSeriesDlg extends CaveHydroSWTDialog { /** Holds the Group Information */ private GroupInfo groupInfo; + + /** Holds the last graphed GroupInfo object */ + private GroupInfo prevGroupInfo; /** Holds the page information */ private PageInfo pageInfo = null; @@ -1365,6 +1370,20 @@ public class TimeSeriesDlg extends CaveHydroSWTDialog { endDayBtn.setText(String.valueOf(endCal.get(Calendar.DAY_OF_MONTH))); endHourBtn.setText(String.valueOf(endCal.get(Calendar.HOUR_OF_DAY))); } + + private void updateTimeButtons() { + beginYearBtn.setText(String.valueOf(beginCal.get(Calendar.YEAR))); + beginMonthBtn.setText(String.valueOf(beginCal.get(Calendar.MONTH) + 1)); + beginDayBtn + .setText(String.valueOf(beginCal.get(Calendar.DAY_OF_MONTH))); + beginHourBtn + .setText(String.valueOf(beginCal.get(Calendar.HOUR_OF_DAY))); + + endYearBtn.setText(String.valueOf(endCal.get(Calendar.YEAR))); + endMonthBtn.setText(String.valueOf(endCal.get(Calendar.MONTH) + 1)); + endDayBtn.setText(String.valueOf(endCal.get(Calendar.DAY_OF_MONTH))); + endHourBtn.setText(String.valueOf(endCal.get(Calendar.HOUR_OF_DAY))); + } /** * Populates the station list box. @@ -1962,7 +1981,12 @@ public class TimeSeriesDlg extends CaveHydroSWTDialog { } else { // TODO log error here, invalid value System.err.println("Error in Group Definition Config file: " + line); - } + } + + // select the first item in the list + if (groupDataList.getItemCount() > 0) { + groupDataList.select(0); + } } /** @@ -2225,32 +2249,26 @@ public class TimeSeriesDlg extends CaveHydroSWTDialog { GroupInfo groupInfo = groupList.get(groupDataList .getSelectionIndex()); - int pastHours = groupInfo.getPastHours(); - int futureHours = groupInfo.getFutureHours(); - -// long beginMillis = beginDate.getTime(); -// long endMillis = endDate.getTime(); -// long currentMillis = SimulatedTime.getSystemTime().getTime().getTime(); -// -// long hoursBack = (currentMillis - beginMillis) / (1000*60*60); -// long hoursAhead = (endMillis - currentMillis) / (1000*60*60); -// groupInfo.setPastHours((int) hoursBack); -// groupInfo.setFutureHours((int) hoursAhead); - groupInfo.setPastHours(pastHours); - groupInfo.setFutureHours(futureHours); - -// Calendar futureCal = Calendar.getInstance(TimeZone -// .getTimeZone("GMT")); -// Date d = SimulatedTime.getSystemTime().getTime(); -// futureCal.setTime(d); -// futureCal.add(Calendar.HOUR_OF_DAY, futureHours); -// Calendar pastCal = Calendar.getInstance(TimeZone -// .getTimeZone("GMT")); -// pastCal.setTime(d); -// pastCal.add(Calendar.HOUR_OF_DAY, pastHours * -1); - - + if (prevGroupInfo == null || !prevGroupInfo.equals(groupInfo)) { + int pastHours = groupInfo.getPastHours(); + int futureHours = groupInfo.getFutureHours(); + beginCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + beginCal.add(Calendar.HOUR_OF_DAY, pastHours * -1); + + endCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + endCal.add(Calendar.HOUR_OF_DAY, futureHours); + + beginDate = beginCal.getTime(); + endDate = endCal.getTime(); + + updateTimeButtons(); + + groupInfo.setPastHours(pastHours); + groupInfo.setFutureHours(futureHours); + } timeSeriesDisplayDlg.setGroupInfo(groupInfo); + + prevGroupInfo = groupInfo; } timeSeriesDisplayDlg.setBeginDate(beginDate); timeSeriesDisplayDlg.setEndDate(endDate); diff --git a/cave/com.raytheon.viz.hydrocommon/src/com/raytheon/viz/hydrocommon/cresthistory/CrestHistoryCanvas.java b/cave/com.raytheon.viz.hydrocommon/src/com/raytheon/viz/hydrocommon/cresthistory/CrestHistoryCanvas.java index 5179e342d3..c7bf0af623 100644 --- a/cave/com.raytheon.viz.hydrocommon/src/com/raytheon/viz/hydrocommon/cresthistory/CrestHistoryCanvas.java +++ b/cave/com.raytheon.viz.hydrocommon/src/com/raytheon/viz/hydrocommon/cresthistory/CrestHistoryCanvas.java @@ -63,684 +63,732 @@ import com.raytheon.viz.hydrocommon.HydroConstants; * @version 1.0 */ public class CrestHistoryCanvas extends Canvas { - /** - * Parent component. - */ - private Composite parentComp; - - /** - * Text font on the canvas. - */ - private Font canvasFont; - - /** - * Canvas width. - */ - private final int CANVAS_WIDTH = 700; - - /** - * Canvas height. - */ - private final int CANVAS_HEIGHT = 520; - - /** - * Y coordinate of the horizontal axis line. - */ - private final int HLINE_YCOORD = CANVAS_HEIGHT - 40; - - /** - * X coordinate of the vertical axis line. - */ - private final int VLINE_XCOORD = 80; - - private final int HLINE_LEFT_OFFSET = 20; - - /** - * Length of the horizontal axis line. - */ - private final int HLINE_LENGTH = CANVAS_WIDTH - VLINE_XCOORD - - HLINE_LEFT_OFFSET; - - /** - * Length of the vertical axis line. - */ - private final int VLINE_LENGTH = 450; - - /** - * The number of pixels the vertical lines is from the top of the canvas. - */ - private final int VLINE_PIXELS_FROM_TOP = CANVAS_HEIGHT - 40 - VLINE_LENGTH; - - /** - * "STAGE IN FEET" text. - */ - private final String STAGE_IN_FEET = "STAGE IN FEET"; - - /** - * Hash mark length. - */ - private final int HASH_MARK = 10; - - /** - * Small hash mark length. - */ - private final int SMALL_HASH_MARK = 5; - - /** - * Label Y coordinate offset. - */ - private final int LABEL_Y_OFFSET = 15; - - /** - * Label X coordinate offset. - */ - private final int LABEL_X_OFFSET = 5; - - /** - * Starting X coordinate for the year hash mark. - */ - private final int YEAR_HASH_X_COORD_START = VLINE_XCOORD + 15; - - /** - * Maximum stage value. - */ - private double stageMaxVal = 0.0; - - /** - * Minimum stage value. - */ - private double stageMinVal = 0.0; - - /** - * Number of MAJOR data items. - */ - private int majorCount = 0; - - /** - * Number of MODERATE data items. - */ - private int modCount = 0; - - /** - * Number of ACTION data items. - */ - private int actionCount = 0; - - /** - * Number of MINOR data items. - */ - private int minorCount = 0; - - /** - * Crest history data. - */ - private CrestHistoryData crestHistoryData; - - /** - * Map of the crest data (value) and the rectangle area on the canvas the - * data occupies (key). - */ - private HashMap crestDataMap; - - /** - * Callback for selecting crest data. - */ - private ISelectedCrestData selectCrestDataCB; - - /** - * Constructor. - * - * @param parent - * Parent composite. - * @param crestHistoryData - * Crest history data. - * @param callback - * Crest data selection callback. - */ - public CrestHistoryCanvas(Composite parent, - CrestHistoryData crestHistoryData, ISelectedCrestData callback) { - super(parent, SWT.DOUBLE_BUFFERED); - - parentComp = parent; - this.crestHistoryData = crestHistoryData; - // work around for missing data - if (crestHistoryData != null) { - selectCrestDataCB = callback; - stageMaxVal = crestHistoryData.getMaxStageLevel(); - stageMinVal = 0.0; - } else { - stageMaxVal = 0.0; - stageMinVal = 0.0; - } - // another work around - if ((crestHistoryData.getEndingYear() == 0) - || (crestHistoryData.getStartingYear() == 0)) { - Calendar cal = new GregorianCalendar(); - cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - Date date = SimulatedTime.getSystemTime().getTime(); - cal.setTime(date); - crestHistoryData.setStartingYear(1900); - crestHistoryData.setEndingYear(cal.get(Calendar.YEAR)); - } - - init(); - } - - /** - * Initialize method. - */ - private void init() { - if (crestHistoryData != null) { - generateCrestDataMap(); - } - - canvasFont = new Font(parentComp.getDisplay(), "Monospace", 9, - SWT.NORMAL); - - setupCanvas(); - - addMouseListener(new MouseAdapter() { - @Override - public void mouseDown(MouseEvent e) { - processMouseEvent(e); - } - }); - } - - /** - * Regenerate the Crest history canvas - * - * @param crestHistoryData - */ - public void updateCrestHistotryData(CrestHistoryData crestHistoryData) { - this.crestHistoryData = crestHistoryData; - - if (crestHistoryData != null) { - stageMaxVal = crestHistoryData.getMaxStageLevel(); - stageMinVal = 0.0; - } else { - stageMaxVal = 0.0; - stageMinVal = 0.0; - } - - generateCrestDataMap(); - redraw(); - } - - /** - * Setup the drawing canvas. - */ - private void setupCanvas() { - GridData gd = new GridData(SWT.DEFAULT, SWT.TOP, false, true); - gd.heightHint = CANVAS_HEIGHT; - gd.widthHint = CANVAS_WIDTH; - - this.setSize(CANVAS_WIDTH, CANVAS_HEIGHT); - - setLayoutData(gd); - addPaintListener(new PaintListener() { - public void paintControl(PaintEvent e) { - drawCrestHistory(e); - } - }); - - addDisposeListener(new DisposeListener() { - public void widgetDisposed(DisposeEvent e) { - canvasFont.dispose(); - } - }); - } - - /** - * Draw the crest history data and the graph lines & labels on the canvas. - * - * @param e - * Paint event. - */ - private void drawCrestHistory(PaintEvent e) { - e.gc.setFont(canvasFont); - int fontHeightMid = (e.gc.getFontMetrics().getHeight() / 2); - int fontHeight = (e.gc.getFontMetrics().getHeight()); - - e.gc.setBackground(parentComp.getDisplay().getSystemColor( - SWT.COLOR_BLACK)); - - e.gc.fillRectangle(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT); - - e.gc.setForeground(parentComp.getDisplay().getSystemColor( - SWT.COLOR_WHITE)); - - // ---------------------------------------- - // Draw horizontal and vertical axis lines - // ---------------------------------------- - - e.gc.drawLine(VLINE_XCOORD, HLINE_YCOORD, VLINE_XCOORD, HLINE_YCOORD - - VLINE_LENGTH); - - e.gc.drawLine(VLINE_XCOORD, HLINE_YCOORD, VLINE_XCOORD + HLINE_LENGTH, - HLINE_YCOORD); - - // ------------------------------------------------ - // Draw STAGE IN FEET vertical label - // ------------------------------------------------ - char[] charArray = STAGE_IN_FEET.toCharArray(); - - int tmpY = 120; - for (int i = 0; i < charArray.length; i++) { - e.gc.drawString(String.valueOf(charArray[i]), 5, tmpY, true); - tmpY += fontHeight; - } - - if (crestHistoryData != null) { - // ------------------------------------------------ - // Draw the years and the hash marks - // ------------------------------------------------ - int startyear = crestHistoryData.getStartingYear(); - int endyear = crestHistoryData.getEndingYear(); - int years = (endyear - startyear); - double pixelsPerIncX; - if (years == 0) { - pixelsPerIncX = 0; - } else { - pixelsPerIncX = HLINE_LENGTH / years; - } - - int yearXcoord = VLINE_XCOORD; - int yearHashXcoord = YEAR_HASH_X_COORD_START; - DecimalFormat df = new DecimalFormat(); - df.setMinimumIntegerDigits(1); - df.setMaximumFractionDigits(0); - df.setGroupingUsed(false); - - for (int i = 0; i <= years; i++) { - int inc = new Double(Math.rint(pixelsPerIncX * i)).intValue(); - yearXcoord = YEAR_HASH_X_COORD_START + inc - 15; - yearHashXcoord = YEAR_HASH_X_COORD_START + inc; - if (years < 75) { - if (i % 5 == 0) { - e.gc.drawString(df.format(startyear + i), yearXcoord, - CANVAS_HEIGHT - fontHeight - 3, true); - e.gc.drawLine(yearHashXcoord, HLINE_YCOORD, yearHashXcoord, - HLINE_YCOORD + HASH_MARK); - } - } else { - if (i % 10 == 0) { - e.gc.drawString(df.format(startyear + i), yearXcoord, - CANVAS_HEIGHT - fontHeight - 3, true); - e.gc.drawLine(yearHashXcoord, HLINE_YCOORD, yearHashXcoord, - HLINE_YCOORD + HASH_MARK); - } - } - } - - // ----------------------------------------- - // Draw stage hash marks - // ----------------------------------------- - - double maxPixValue = VLINE_LENGTH + VLINE_PIXELS_FROM_TOP; - double numHashsY = stageMaxVal; - double pixelsPerIncY = VLINE_LENGTH / numHashsY; - - for (int x = 0; x <= stageMaxVal; ++x) { - int yCoord = HLINE_YCOORD - - new Double(Math.round(x * pixelsPerIncY)).intValue(); - - if (x % 5 == 0) { - // draw little hash - e.gc.drawLine(VLINE_XCOORD, yCoord, VLINE_XCOORD - - SMALL_HASH_MARK, yCoord); - - String recStr = String.format("%5.1f", new Float(x) - .floatValue()); - e.gc.drawString(recStr, 35, yCoord - fontHeightMid, true); - } - } - - // ----------------------------------------- - // Draw MAJOR line and label - // ----------------------------------------- - - double majorLevel = crestHistoryData.getMajorLevel(); - - e.gc.setForeground(parentComp.getDisplay().getSystemColor( - SWT.COLOR_MAGENTA)); - - int majorYCoord = (int) (maxPixValue - Math - .round(((majorLevel - stageMinVal) * pixelsPerIncY))); - - e.gc.drawLine(VLINE_XCOORD + 1, majorYCoord, VLINE_XCOORD - + HLINE_LENGTH, majorYCoord); - - String majorLabel = String.format("%5.1f MAJOR (%d)", majorLevel, - majorCount); - e.gc.drawString(majorLabel, VLINE_XCOORD + LABEL_X_OFFSET, - majorYCoord - LABEL_Y_OFFSET, true); - - // ----------------------------------------- - // Draw MODERATE line and label - // ----------------------------------------- - - double moderateLevel = crestHistoryData.getModerateLevel(); - - e.gc.setForeground(parentComp.getDisplay().getSystemColor( - SWT.COLOR_BLUE)); - - int modYCoord = (int) (maxPixValue - Math - .round(((moderateLevel - stageMinVal) * pixelsPerIncY))); - - e.gc.drawLine(VLINE_XCOORD + 1, modYCoord, VLINE_XCOORD - + HLINE_LENGTH, modYCoord); - - String modLabel = String.format("%5.1f MODERATE (%d)", - moderateLevel, modCount); - e.gc.drawString(modLabel, VLINE_XCOORD + LABEL_X_OFFSET, modYCoord - - LABEL_Y_OFFSET, true); - - // ----------------------------------------- - // Draw MINOR line and label - // ----------------------------------------- - - double minorLevel = crestHistoryData.getMinorLevel(); - - e.gc.setForeground(parentComp.getDisplay().getSystemColor( - SWT.COLOR_RED)); - - int minorYCoord = (int) (maxPixValue - Math - .round(((minorLevel - stageMinVal) * pixelsPerIncY))); - - e.gc.drawLine(VLINE_XCOORD + 1, minorYCoord, VLINE_XCOORD - + HLINE_LENGTH, minorYCoord); - - String minorLabel = String.format("%5.1f MINOR (%d)", minorLevel, - minorCount); - e.gc.drawString(minorLabel, VLINE_XCOORD + LABEL_X_OFFSET, - minorYCoord - LABEL_Y_OFFSET, true); - - e.gc.drawString("FLOOD", VLINE_XCOORD + HLINE_LENGTH - 40, - minorYCoord - LABEL_Y_OFFSET, true); - - // ----------------------------------------- - // Draw ACTION line and label - // ----------------------------------------- - - double actionLevel = crestHistoryData.getActionLevel(); - - e.gc.setForeground(parentComp.getDisplay().getSystemColor( - SWT.COLOR_YELLOW)); - - int actionYCoord = (int) (maxPixValue - Math - .round(((actionLevel - stageMinVal) * pixelsPerIncY))); - - e.gc.drawLine(VLINE_XCOORD + 1, actionYCoord, VLINE_XCOORD - + HLINE_LENGTH, actionYCoord); - - String actionLabel = String.format("%5.1f ACTION (%d)", - actionLevel, actionCount); - e.gc.drawString(actionLabel, VLINE_XCOORD + LABEL_X_OFFSET, - actionYCoord - LABEL_Y_OFFSET, true); - - // ------------------------------------------- - // Draw crest data - // ------------------------------------------- - - CrestDrawData drawData; - Rectangle rec; - - Set keys = crestDataMap.keySet(); - - for (Iterator iterator = keys.iterator(); iterator - .hasNext();) { - rec = iterator.next(); - drawData = crestDataMap.get(rec); - - if (drawData.getDrawData() == false) { - continue; - } - - if (drawData.isSelected() == true) { - e.gc.setBackground(parentComp.getDisplay().getSystemColor( - SWT.COLOR_WHITE)); - } else { - e.gc.setBackground(drawData.getColor()); - } - - e.gc.fillRectangle(rec.x, rec.y, rec.width, rec.height); - } - } - } - - /** - * Generate the map of crest data (value) and the rectangle areas on the - * canvas (key). - */ - private void generateCrestDataMap() { - crestDataMap = new HashMap(); - CrestDrawData drawData; - Rectangle rec; - - int circleWidth = 8; - int circleHeight = 8; - - double maxPixValue = VLINE_LENGTH + VLINE_PIXELS_FROM_TOP; - double numHashs = crestHistoryData.getMaxStageLevel(); - double pixelsPerIncY = VLINE_LENGTH / numHashs; - int startyear = crestHistoryData.getStartingYear(); - int endyear = crestHistoryData.getEndingYear(); - int years = endyear - startyear; - int pixelsPerIncX; - if (years == 0) { - pixelsPerIncX = 0; - } else { - pixelsPerIncX = HLINE_LENGTH / years; - } - - //Init the counts - this.majorCount=0; - this.minorCount=0; - this.actionCount=0; - this.modCount=0; - - for (CrestData crestData : crestHistoryData.getCrestDataArray()) { - - int yCoord = (int) (maxPixValue - Math - .round((crestData.getStage() * pixelsPerIncY))); - - double yearXOffset = crestData.getYear() - startyear; - int xCoord = YEAR_HASH_X_COORD_START - + new Double(Math.round(yearXOffset * pixelsPerIncX)) - .intValue(); - - rec = new Rectangle(xCoord - circleWidth / 2, yCoord - circleHeight - / 2, circleWidth, circleHeight); - - drawData = new CrestDrawData(crestData.getStage(), crestData - .getYear(), calculateDataColor(crestData.getStage())); - - crestDataMap.put(rec, drawData); - } - } - - /** - * Calculate color of the crest data. - * - * @param stage - * Stage (in feet). - * @return The color associated with the data. - */ - private Color calculateDataColor(double stage) { - if ((stage > crestHistoryData.getMajorLevel()) && - (crestHistoryData.getMajorLevel() != HydroConstants.MISSING_VALUE)) { - ++majorCount; - return parentComp.getDisplay().getSystemColor(SWT.COLOR_MAGENTA); - } else if ((stage > crestHistoryData.getModerateLevel()) && - (crestHistoryData.getModerateLevel() != HydroConstants.MISSING_VALUE)) { - ++modCount; - return parentComp.getDisplay().getSystemColor(SWT.COLOR_BLUE); - } else if ((stage > crestHistoryData.getMinorLevel()) && - (crestHistoryData.getMinorLevel() != HydroConstants.MISSING_VALUE)) { - ++minorCount; - return parentComp.getDisplay().getSystemColor(SWT.COLOR_RED); - } else if ((stage > crestHistoryData.getActionLevel()) && - (crestHistoryData.getActionLevel() != HydroConstants.MISSING_VALUE)) { - ++actionCount; - return parentComp.getDisplay().getSystemColor(SWT.COLOR_YELLOW); - } - - return parentComp.getDisplay().getSystemColor(SWT.COLOR_GREEN); - } - - /** - * Select the crest data if the mouse click is in the data rectangle. - * - * @param e - * Mouse event. - */ - public void processMouseEvent(MouseEvent e) { - Rectangle rec; - Rectangle foundRec = null; - Rectangle selectedRec = null; - - Set keys = crestDataMap.keySet(); - - for (Iterator iterator = keys.iterator(); iterator.hasNext();) { - rec = iterator.next(); - - // Check if the mouse's x & y coords is in the rectangle area or on - // the - // edge of the rectangle - if (recContains(e.x, e.y, rec)) { - foundRec = rec; - // crestDataMap.get(rec).setSelected(true); - } else if (crestDataMap.get(rec).isSelected() == true) { - selectedRec = rec; - } - - if (foundRec != null) { - crestDataMap.get(foundRec).setSelected(true); - - if (selectedRec != null) { - crestDataMap.get(selectedRec).setSelected(false); - } - - if (selectCrestDataCB != null) { - selectCrestDataCB.crestDataSelected(crestDataMap.get( - foundRec).getStage(), crestDataMap.get(foundRec) - .getYear()); - } - } - } - this.redraw(); - } - - /** - * This method is used in place of the Rectangle.contains() method. The - * contains method only checks if the x,y is inside the rectangle area. This - * method accounts for the x,y being on the edges of the rectangle. - * - * @param x - * Mouse's x coordinate. - * @param y - * Mouse's y coordinate. - * @param rec - * Rectangle the mouse coordinates will be checked against. - * @return True if the mouse's x & y coordinates are in/on the rectangle. - */ - private boolean recContains(int x, int y, Rectangle rec) { - if ((x < rec.x) || (x > (rec.x + rec.width))) { - return false; - } - - if ((y < rec.y) || (y > (rec.y + rec.height))) { - return false; - } - - return true; - } - - /** - * Select the crest data based on the stage nad year passed in. - * - * @param stage - * Stage in feet. - * @param year - * Year. - */ - public void selectCrestData(double stage, int year) { - Rectangle rec; - - Set keys = crestDataMap.keySet(); - - for (Iterator iterator = keys.iterator(); iterator.hasNext();) { - rec = iterator.next(); - - crestDataMap.get(rec).setSelected(false); - - if ((crestDataMap.get(rec).getStage() == stage) - && (crestDataMap.get(rec).getYear() == year)) { - crestDataMap.get(rec).setSelected(true); - } - } - this.redraw(); - } - - /** - * Draw all of the crest data on the canvas. - */ - public void drawAllCrestData() { - Rectangle rec; - - Set keys = crestDataMap.keySet(); - - for (Iterator iterator = keys.iterator(); iterator.hasNext();) { - rec = iterator.next(); - - crestDataMap.get(rec).setDrawData(true); - } - - this.redraw(); - } - - /** - * Draw only the crest data below the action stage. - */ - public void drawDataBelowActionStage() { - Rectangle rec; - - Set keys = crestDataMap.keySet(); - - for (Iterator iterator = keys.iterator(); iterator.hasNext();) { - rec = iterator.next(); - - if (crestDataMap.get(rec).getStage() > crestHistoryData - .getActionLevel()) { - crestDataMap.get(rec).setDrawData(false); - } else { - crestDataMap.get(rec).setDrawData(true); - } - } - - this.redraw(); - } - - /** - * Draw only the crest data above the action stage. - */ - public void drawDataAboveActionStage() { - Rectangle rec; - - Set keys = crestDataMap.keySet(); - - for (Iterator iterator = keys.iterator(); iterator.hasNext();) { - rec = iterator.next(); - - if (crestDataMap.get(rec).getStage() < crestHistoryData - .getActionLevel()) { - crestDataMap.get(rec).setDrawData(false); - } else { - crestDataMap.get(rec).setDrawData(true); - } - } - - this.redraw(); - } + /** + * Parent component. + */ + private Composite parentComp; + + /** + * Text font on the canvas. + */ + private Font canvasFont; + + /** + * Canvas width. + */ + private final int CANVAS_WIDTH = 700; + + /** + * Canvas height. + */ + private final int CANVAS_HEIGHT = 520; + + /** + * Y coordinate of the horizontal axis line. + */ + private final int HLINE_YCOORD = CANVAS_HEIGHT - 40; + + /** + * X coordinate of the vertical axis line. + */ + private final int VLINE_XCOORD = 80; + + private final int HLINE_LEFT_OFFSET = 20; + + /** + * Length of the horizontal axis line. + */ + private final int HLINE_LENGTH = CANVAS_WIDTH - VLINE_XCOORD + - HLINE_LEFT_OFFSET; + + /** + * Length of the vertical axis line. + */ + private final int VLINE_LENGTH = 450; + + /** + * The number of pixels the vertical lines is from the top of the canvas. + */ + private final int VLINE_PIXELS_FROM_TOP = CANVAS_HEIGHT - 40 - VLINE_LENGTH; + + /** + * "STAGE IN FEET" text. + */ + private final String STAGE_IN_FEET = "STAGE IN FEET"; + + /** + * Hash mark length. + */ + private final int HASH_MARK = 10; + + /** + * Small hash mark length. + */ + private final int SMALL_HASH_MARK = 5; + + /** + * Label Y coordinate offset. + */ + private final int LABEL_Y_OFFSET = 15; + + /** + * Label X coordinate offset. + */ + private final int LABEL_X_OFFSET = 5; + + /** + * Starting X coordinate for the year hash mark. + */ + private final int YEAR_HASH_X_COORD_START = VLINE_XCOORD + 15; + + /** + * number of intervals on the y-axis + */ + private final int NUM_VERTICAL_INTERVALS = 5; + /** + * Maximum stage value. + */ + private double stageMaxVal = 0.0; + + /** + * Minimum stage value. + */ + private double stageMinVal = 0.0; + + /** + * Number of MAJOR data items. + */ + private int majorCount = 0; + + /** + * Number of MODERATE data items. + */ + private int modCount = 0; + + /** + * Number of ACTION data items. + */ + private int actionCount = 0; + + /** + * Number of MINOR data items. + */ + private int minorCount = 0; + + /** + * Crest history data. + */ + private CrestHistoryData crestHistoryData; + + /** + * Map of the crest data (value) and the rectangle area on the canvas the + * data occupies (key). + */ + private HashMap crestDataMap; + + /** + * Callback for selecting crest data. + */ + private ISelectedCrestData selectCrestDataCB; + + /** + * Constructor. + * + * @param parent + * Parent composite. + * @param crestHistoryData + * Crest history data. + * @param callback + * Crest data selection callback. + */ + public CrestHistoryCanvas(Composite parent, + CrestHistoryData crestHistoryData, ISelectedCrestData callback) { + super(parent, SWT.DOUBLE_BUFFERED); + + parentComp = parent; + this.crestHistoryData = crestHistoryData; + // work around for missing data + if (crestHistoryData != null) { + selectCrestDataCB = callback; + stageMaxVal = crestHistoryData.getMaxStageLevel(); + stageMinVal = crestHistoryData.getMinStageLevel(); + } else { + stageMaxVal = 0.0; + stageMinVal = 0.0; + } + setYAxisMaxMin(); + // another work around + if ((crestHistoryData.getEndingYear() == 0) + || (crestHistoryData.getStartingYear() == 0)) { + Calendar cal = new GregorianCalendar(); + cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + Date date = SimulatedTime.getSystemTime().getTime(); + cal.setTime(date); + crestHistoryData.setStartingYear(1900); + crestHistoryData.setEndingYear(cal.get(Calendar.YEAR)); + } + + init(); + } + + /** + * Initialize method. + */ + private void init() { + if (crestHistoryData != null) { + generateCrestDataMap(); + } + + canvasFont = new Font(parentComp.getDisplay(), "Monospace", 9, + SWT.NORMAL); + + setupCanvas(); + + addMouseListener(new MouseAdapter() { + @Override + public void mouseDown(MouseEvent e) { + processMouseEvent(e); + } + }); + } + + /** + * Regenerate the Crest history canvas + * + * @param crestHistoryData + */ + public void updateCrestHistotryData(CrestHistoryData crestHistoryData) { + this.crestHistoryData = crestHistoryData; + + if (crestHistoryData != null) { + stageMaxVal = crestHistoryData.getMaxStageLevel(); + stageMinVal = crestHistoryData.getMinStageLevel(); + } else { + stageMaxVal = 0.0; + stageMinVal = 0.0; + } + + setYAxisMaxMin(); + generateCrestDataMap(); + redraw(); + } + + /** + * Setup the drawing canvas. + */ + private void setupCanvas() { + GridData gd = new GridData(SWT.DEFAULT, SWT.TOP, false, true); + gd.heightHint = CANVAS_HEIGHT; + gd.widthHint = CANVAS_WIDTH; + + this.setSize(CANVAS_WIDTH, CANVAS_HEIGHT); + + setLayoutData(gd); + addPaintListener(new PaintListener() { + public void paintControl(PaintEvent e) { + drawCrestHistory(e); + } + }); + + addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + canvasFont.dispose(); + } + }); + } + + /** + * Calculate for the max. and min. Y axis value + */ + private void setYAxisMaxMin() { + int roundFactor = 5; + long lmax, lmin; + + /* + * Round min down. If the original min data > 0, then don't round below + * 0. + */ + lmin = (long) (stageMinVal / roundFactor); + + if (lmin >= 0) { + stageMinVal = (lmin - 1) * roundFactor; + if (stageMinVal < 0) + stageMinVal = 0; + } else /* lmin < 0 */ + { + stageMinVal = (lmin - 1) * roundFactor; + } + + /* + * Round max up. + */ + lmax = (long) (stageMaxVal / roundFactor); + + /* + * If the difference between max_y and min_y < 10, round max_y up again. + */ + if ((stageMaxVal - stageMaxVal) < 10) { + stageMaxVal = (lmax + 2) * roundFactor; + } + + if (stageMinVal < 0) { + stageMinVal=0; + } + + } + + /** + * Draw the crest history data and the graph lines & labels on the canvas. + * + * @param e + * Paint event. + */ + private void drawCrestHistory(PaintEvent e) { + e.gc.setFont(canvasFont); + int fontHeightMid = (e.gc.getFontMetrics().getHeight() / 2); + int fontHeight = (e.gc.getFontMetrics().getHeight()); + + e.gc.setBackground(parentComp.getDisplay().getSystemColor( + SWT.COLOR_BLACK)); + + e.gc.fillRectangle(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT); + + e.gc.setForeground(parentComp.getDisplay().getSystemColor( + SWT.COLOR_WHITE)); + + // ---------------------------------------- + // Draw horizontal and vertical axis lines + // ---------------------------------------- + + e.gc.drawLine(VLINE_XCOORD, HLINE_YCOORD, VLINE_XCOORD, HLINE_YCOORD + - VLINE_LENGTH); + + e.gc.drawLine(VLINE_XCOORD, HLINE_YCOORD, VLINE_XCOORD + HLINE_LENGTH, + HLINE_YCOORD); + + // ------------------------------------------------ + // Draw STAGE IN FEET vertical label + // ------------------------------------------------ + char[] charArray = STAGE_IN_FEET.toCharArray(); + + int tmpY = 120; + for (int i = 0; i < charArray.length; i++) { + e.gc.drawString(String.valueOf(charArray[i]), 5, tmpY, true); + tmpY += fontHeight; + } + + if (crestHistoryData != null) { + // ------------------------------------------------ + // Draw the years and the hash marks + // ------------------------------------------------ + int startyear = crestHistoryData.getStartingYear(); + int endyear = crestHistoryData.getEndingYear(); + int years = (endyear - startyear); + double pixelsPerIncX; + if (years == 0) { + pixelsPerIncX = 0; + } else { + pixelsPerIncX = HLINE_LENGTH / years; + } + + int yearXcoord = VLINE_XCOORD; + int yearHashXcoord = YEAR_HASH_X_COORD_START; + DecimalFormat df = new DecimalFormat(); + df.setMinimumIntegerDigits(1); + df.setMaximumFractionDigits(0); + df.setGroupingUsed(false); + + for (int i = 0; i <= years; i++) { + int inc = new Double(Math.rint(pixelsPerIncX * i)).intValue(); + yearXcoord = YEAR_HASH_X_COORD_START + inc - 15; + yearHashXcoord = YEAR_HASH_X_COORD_START + inc; + if (years < 75) { + if (i % 5 == 0) { + e.gc.drawString(df.format(startyear + i), yearXcoord, + CANVAS_HEIGHT - fontHeight - 3, true); + e.gc.drawLine(yearHashXcoord, HLINE_YCOORD, + yearHashXcoord, HLINE_YCOORD + HASH_MARK); + } + } else { + if (i % 10 == 0) { + e.gc.drawString(df.format(startyear + i), yearXcoord, + CANVAS_HEIGHT - fontHeight - 3, true); + e.gc.drawLine(yearHashXcoord, HLINE_YCOORD, + yearHashXcoord, HLINE_YCOORD + HASH_MARK); + } + } + } + + // ----------------------------------------- + // Draw stage hash marks + // ----------------------------------------- + + double maxPixValue = VLINE_LENGTH + VLINE_PIXELS_FROM_TOP; + double numHashsY = stageMaxVal - stageMinVal; + double valInc = (stageMaxVal - stageMinVal) + / NUM_VERTICAL_INTERVALS; + + double pixelsPerIncY = VLINE_LENGTH / numHashsY; + + for (int x = (int) (stageMinVal); x <= stageMaxVal; x += valInc) { + int yCoord = HLINE_YCOORD + - new Double(Math.round((x - stageMinVal) + * pixelsPerIncY)).intValue(); + + e.gc.drawLine(VLINE_XCOORD, yCoord, VLINE_XCOORD + - SMALL_HASH_MARK, yCoord); + + String recStr = String.format("%5.1f", + new Float(x).floatValue()); + e.gc.drawString(recStr, 35, yCoord - fontHeightMid, true); + } + + // ----------------------------------------- + // Draw MAJOR line and label + // ----------------------------------------- + + double majorLevel = crestHistoryData.getMajorLevel(); + + e.gc.setForeground(parentComp.getDisplay().getSystemColor( + SWT.COLOR_MAGENTA)); + + int majorYCoord = (int) (maxPixValue - Math + .round(((majorLevel - stageMinVal) * pixelsPerIncY))); + + e.gc.drawLine(VLINE_XCOORD + 1, majorYCoord, VLINE_XCOORD + + HLINE_LENGTH, majorYCoord); + + String majorLabel = String.format("%5.1f MAJOR (%d)", majorLevel, + majorCount); + e.gc.drawString(majorLabel, VLINE_XCOORD + LABEL_X_OFFSET, + majorYCoord - LABEL_Y_OFFSET, true); + + // ----------------------------------------- + // Draw MODERATE line and label + // ----------------------------------------- + + double moderateLevel = crestHistoryData.getModerateLevel(); + + e.gc.setForeground(parentComp.getDisplay().getSystemColor( + SWT.COLOR_BLUE)); + + int modYCoord = (int) (maxPixValue - Math + .round(((moderateLevel - stageMinVal) * pixelsPerIncY))); + + e.gc.drawLine(VLINE_XCOORD + 1, modYCoord, VLINE_XCOORD + + HLINE_LENGTH, modYCoord); + + String modLabel = String.format("%5.1f MODERATE (%d)", + moderateLevel, modCount); + e.gc.drawString(modLabel, VLINE_XCOORD + LABEL_X_OFFSET, modYCoord + - LABEL_Y_OFFSET, true); + + // ----------------------------------------- + // Draw MINOR line and label + // ----------------------------------------- + + double minorLevel = crestHistoryData.getMinorLevel(); + + e.gc.setForeground(parentComp.getDisplay().getSystemColor( + SWT.COLOR_RED)); + + int minorYCoord = (int) (maxPixValue - Math + .round(((minorLevel - stageMinVal) * pixelsPerIncY))); + + e.gc.drawLine(VLINE_XCOORD + 1, minorYCoord, VLINE_XCOORD + + HLINE_LENGTH, minorYCoord); + + String minorLabel = String.format("%5.1f MINOR (%d)", minorLevel, + minorCount); + e.gc.drawString(minorLabel, VLINE_XCOORD + LABEL_X_OFFSET, + minorYCoord - LABEL_Y_OFFSET, true); + + e.gc.drawString("FLOOD", VLINE_XCOORD + HLINE_LENGTH - 40, + minorYCoord - LABEL_Y_OFFSET, true); + + // ----------------------------------------- + // Draw ACTION line and label + // ----------------------------------------- + + double actionLevel = crestHistoryData.getActionLevel(); + + e.gc.setForeground(parentComp.getDisplay().getSystemColor( + SWT.COLOR_YELLOW)); + + int actionYCoord = (int) (maxPixValue - Math + .round(((actionLevel - stageMinVal) * pixelsPerIncY))); + + e.gc.drawLine(VLINE_XCOORD + 1, actionYCoord, VLINE_XCOORD + + HLINE_LENGTH, actionYCoord); + + String actionLabel = String.format("%5.1f ACTION (%d)", + actionLevel, actionCount); + e.gc.drawString(actionLabel, VLINE_XCOORD + LABEL_X_OFFSET, + actionYCoord - LABEL_Y_OFFSET, true); + + // ------------------------------------------- + // Draw crest data + // ------------------------------------------- + + CrestDrawData drawData; + Rectangle rec; + + Set keys = crestDataMap.keySet(); + + for (Iterator iterator = keys.iterator(); iterator + .hasNext();) { + rec = iterator.next(); + drawData = crestDataMap.get(rec); + + if (drawData.getDrawData() == false) { + continue; + } + + if (drawData.isSelected() == true) { + e.gc.setBackground(parentComp.getDisplay().getSystemColor( + SWT.COLOR_WHITE)); + } else { + e.gc.setBackground(drawData.getColor()); + } + + e.gc.fillRectangle(rec.x, rec.y, rec.width, rec.height); + } + } + } + + /** + * Generate the map of crest data (value) and the rectangle areas on the + * canvas (key). + */ + private void generateCrestDataMap() { + crestDataMap = new HashMap(); + CrestDrawData drawData; + Rectangle rec; + + int circleWidth = 8; + int circleHeight = 8; + + double maxPixValue = VLINE_LENGTH + VLINE_PIXELS_FROM_TOP; + double numHashs = stageMaxVal - stageMinVal; + double pixelsPerIncY = VLINE_LENGTH / numHashs; + int startyear = crestHistoryData.getStartingYear(); + int endyear = crestHistoryData.getEndingYear(); + int years = endyear - startyear; + int pixelsPerIncX; + if (years == 0) { + pixelsPerIncX = 0; + } else { + pixelsPerIncX = HLINE_LENGTH / years; + } + + // Init the counts + this.majorCount = 0; + this.minorCount = 0; + this.actionCount = 0; + this.modCount = 0; + + for (CrestData crestData : crestHistoryData.getCrestDataArray()) { + + int yCoord = (int) (maxPixValue - Math + .round(((crestData.getStage() - stageMinVal) * pixelsPerIncY))); + + double yearXOffset = crestData.getYear() - startyear; + int xCoord = YEAR_HASH_X_COORD_START + + new Double(Math.round(yearXOffset * pixelsPerIncX)) + .intValue(); + + rec = new Rectangle(xCoord - circleWidth / 2, yCoord - circleHeight + / 2, circleWidth, circleHeight); + + drawData = new CrestDrawData(crestData.getStage(), + crestData.getYear(), + calculateDataColor(crestData.getStage())); + + crestDataMap.put(rec, drawData); + } + } + + /** + * Calculate color of the crest data. + * + * @param stage + * Stage (in feet). + * @return The color associated with the data. + */ + private Color calculateDataColor(double stage) { + if ((stage > crestHistoryData.getMajorLevel()) + && (crestHistoryData.getMajorLevel() != HydroConstants.MISSING_VALUE)) { + ++majorCount; + return parentComp.getDisplay().getSystemColor(SWT.COLOR_MAGENTA); + } else if ((stage > crestHistoryData.getModerateLevel()) + && (crestHistoryData.getModerateLevel() != HydroConstants.MISSING_VALUE)) { + ++modCount; + return parentComp.getDisplay().getSystemColor(SWT.COLOR_BLUE); + } else if ((stage > crestHistoryData.getMinorLevel()) + && (crestHistoryData.getMinorLevel() != HydroConstants.MISSING_VALUE)) { + ++minorCount; + return parentComp.getDisplay().getSystemColor(SWT.COLOR_RED); + } else if ((stage > crestHistoryData.getActionLevel()) + && (crestHistoryData.getActionLevel() != HydroConstants.MISSING_VALUE)) { + ++actionCount; + return parentComp.getDisplay().getSystemColor(SWT.COLOR_YELLOW); + } + + return parentComp.getDisplay().getSystemColor(SWT.COLOR_GREEN); + } + + /** + * Select the crest data if the mouse click is in the data rectangle. + * + * @param e + * Mouse event. + */ + public void processMouseEvent(MouseEvent e) { + Rectangle rec; + Rectangle foundRec = null; + Rectangle selectedRec = null; + + Set keys = crestDataMap.keySet(); + + for (Iterator iterator = keys.iterator(); iterator.hasNext();) { + rec = iterator.next(); + + // Check if the mouse's x & y coords is in the rectangle area or on + // the + // edge of the rectangle + if (recContains(e.x, e.y, rec)) { + foundRec = rec; + // crestDataMap.get(rec).setSelected(true); + } else if (crestDataMap.get(rec).isSelected() == true) { + selectedRec = rec; + } + + if (foundRec != null) { + crestDataMap.get(foundRec).setSelected(true); + + if (selectedRec != null) { + crestDataMap.get(selectedRec).setSelected(false); + } + + if (selectCrestDataCB != null) { + selectCrestDataCB.crestDataSelected( + crestDataMap.get(foundRec).getStage(), crestDataMap + .get(foundRec).getYear()); + } + } + } + this.redraw(); + } + + /** + * This method is used in place of the Rectangle.contains() method. The + * contains method only checks if the x,y is inside the rectangle area. This + * method accounts for the x,y being on the edges of the rectangle. + * + * @param x + * Mouse's x coordinate. + * @param y + * Mouse's y coordinate. + * @param rec + * Rectangle the mouse coordinates will be checked against. + * @return True if the mouse's x & y coordinates are in/on the rectangle. + */ + private boolean recContains(int x, int y, Rectangle rec) { + if ((x < rec.x) || (x > (rec.x + rec.width))) { + return false; + } + + if ((y < rec.y) || (y > (rec.y + rec.height))) { + return false; + } + + return true; + } + + /** + * Select the crest data based on the stage nad year passed in. + * + * @param stage + * Stage in feet. + * @param year + * Year. + */ + public void selectCrestData(double stage, int year) { + Rectangle rec; + + Set keys = crestDataMap.keySet(); + + for (Iterator iterator = keys.iterator(); iterator.hasNext();) { + rec = iterator.next(); + + crestDataMap.get(rec).setSelected(false); + + if ((crestDataMap.get(rec).getStage() == stage) + && (crestDataMap.get(rec).getYear() == year)) { + crestDataMap.get(rec).setSelected(true); + } + } + this.redraw(); + } + + /** + * Draw all of the crest data on the canvas. + */ + public void drawAllCrestData() { + Rectangle rec; + + Set keys = crestDataMap.keySet(); + + for (Iterator iterator = keys.iterator(); iterator.hasNext();) { + rec = iterator.next(); + + crestDataMap.get(rec).setDrawData(true); + } + + this.redraw(); + } + + /** + * Draw only the crest data below the action stage. + */ + public void drawDataBelowActionStage() { + Rectangle rec; + + Set keys = crestDataMap.keySet(); + + for (Iterator iterator = keys.iterator(); iterator.hasNext();) { + rec = iterator.next(); + + if (crestDataMap.get(rec).getStage() > crestHistoryData + .getActionLevel()) { + crestDataMap.get(rec).setDrawData(false); + } else { + crestDataMap.get(rec).setDrawData(true); + } + } + + this.redraw(); + } + + /** + * Draw only the crest data above the action stage. + */ + public void drawDataAboveActionStage() { + Rectangle rec; + + Set keys = crestDataMap.keySet(); + + for (Iterator iterator = keys.iterator(); iterator.hasNext();) { + rec = iterator.next(); + + if (crestDataMap.get(rec).getStage() < crestHistoryData + .getActionLevel()) { + crestDataMap.get(rec).setDrawData(false); + } else { + crestDataMap.get(rec).setDrawData(true); + } + } + + this.redraw(); + } } diff --git a/cave/com.raytheon.viz.hydrocommon/src/com/raytheon/viz/hydrocommon/datamanager/RiverDataManager.java b/cave/com.raytheon.viz.hydrocommon/src/com/raytheon/viz/hydrocommon/datamanager/RiverDataManager.java index 64d9492796..691aa82a6f 100644 --- a/cave/com.raytheon.viz.hydrocommon/src/com/raytheon/viz/hydrocommon/datamanager/RiverDataManager.java +++ b/cave/com.raytheon.viz.hydrocommon/src/com/raytheon/viz/hydrocommon/datamanager/RiverDataManager.java @@ -66,683 +66,679 @@ import com.raytheon.viz.hydrocommon.data.RiverDataPoint; public class RiverDataManager { - /** Singleton instance of this class */ - private static RiverDataManager riverManager = null; - - /* Private Constructor */ - private RiverDataManager() { - } - - /** - * Get an instance of this singleton. - * - * @return Instance of this class - */ - public static synchronized RiverDataManager getInstance() { - if (riverManager == null) { - riverManager = new RiverDataManager(); - } - return riverManager; - } - - private static final transient IUFStatusHandler statusHandler = UFStatus - .getHandler(RiverDataManager.class); - - private LinkedHashMap crestData = null; - - private LinkedHashMap> riverData = null; - - private static String locationQuery = "SELECT name, county, state, elev, hsa, lat, lon, rb from location WHERE lid ="; - - private static String riverStatQuery = "SELECT stream, mile, zd, tide, bf, wstg, fs, fq, action_flow, primary_pe FROM riverstat WHERE lid ="; - - private static String descriptionQuery = "SELECT proximity, reach FROM descrip WHERE lid ="; - - private static String crestQuery = "select stage, q, datcrst, timcrst, cremark, hw, jam, olddatum, suppress, prelim from crest where lid = '"; - - private static String floodCatQuery = "SELECT minor_stage, moderate_stage, major_stage, minor_flow, moderate_flow, major_flow from floodcat WHERE lid = "; - - private static String riverInfoQuery = "SELECT rivermonlocation.group_id, rivermongroup.group_name FROM rivermongroup, rivermonlocation WHERE rivermongroup.group_id = rivermonlocation.group_id AND rivermonlocation.lid = "; - - private static String riverPointQuery = "SELECT l.lid, l.name, l.county, l.state, l.elev, l.hsa, l.lat, l.lon, " - + "rml.group_id, " - + "rmg.group_name, " - + "r.stream, r.mile, r.zd AS zero, r.tide, r.bf AS bankfull, r.wstg AS action_stage, r.fs AS flood_stage, r.fq AS flood_flow, r.action_flow, r.primary_pe, " - + "d.proximity, d.reach, " - + "f.minor_stage AS minor, f.moderate_stage AS moderate, f.major_stage AS major, f.minor_flow AS minor, f.moderate_flow AS moderate, f.major_flow AS major " - + "FROM location l " - + "LEFT JOIN floodcat f ON l.lid::text = f.lid::text " - + "LEFT JOIN descrip d ON l.lid::text = d.lid::text, riverstat r, rivermonlocation rml " - + "LEFT JOIN rivermongroup rmg ON rml.group_id::text = rmg.group_id::text " - + "WHERE l.lid::text = r.lid::text and r.lid::text = rml.lid::text " - + "ORDER BY rml.group_id, r.mile desc"; - - private static String riverObsvalueQueryFront = "SELECT distinct(foo.lid), foo.value, foo.maxtime from " - + "(SELECT distinct height.lid, height.value, max(height.obstime) as maxtime " - + "FROM height " - + "WHERE height.lid in " - + "(select distinct(lid) " - + "from rivermonlocation " - + "where rivermonlocation.group_id = "; - - private static String riverObsvalueQueryBack = ") GROUP BY height.lid, height.value) " - + "AS foo " - + "GROUP BY foo.lid, foo.value, foo.maxtime order by foo.lid, foo.maxtime desc"; - - private static String riverFcstvalueQueryFront = "SELECT distinct(foo.lid), foo.value, foo.maxtime from " - + "(SELECT distinct fcstheight.lid, fcstheight.value, max(fcstheight.validtime) as maxtime " - + "FROM fcstheight " - + "WHERE fcstheight.lid in " - + "(select distinct(lid) " - + "from rivermonlocation " - + "where rivermonlocation.group_id = "; - - private static String riverFcstvalueQueryBack = ") GROUP BY fcstheight.lid, fcstheight.value) " - + "AS foo " - + "GROUP BY foo.lid, foo.value, foo.maxtime order by foo.lid, foo.maxtime desc"; - - private static String riverIDQuery = "SELECT group_id FROM rivermonlocation where lid ="; - - /** - * River Query Crest - * - * @param lid - * @return CrestHistoryData - */ - public CrestHistoryData getRiverCrests(RiverDataPoint rdp, int allFlag) { - CrestHistoryData crests = null; - - if (crestData == null) { - crestData = new LinkedHashMap(); - } - - crests = new CrestHistoryData(); - String query = null; - - /* get crest data depending on action stage */ - if (rdp != null) { - String sql = "select stage, q, datcrst, timcrst, cremark, hw, jam, olddatum, suppress, prelim " - + "from crest where lid = '" + rdp.getLid(); - - if (allFlag == 1) { - query = sql + "' and stage >'" + rdp.getActionStage() - + "' ORDER BY stage, q"; - } else if (allFlag == 2) { - query = sql + "' and stage <'" + rdp.getActionStage() - + "' ORDER BY stage, q"; - } else { - query = sql + "' ORDER BY stage, q"; - } - - ArrayList objects = null; - - try { - objects = (ArrayList) DirectDbQuery.executeQuery( - query, HydroConstants.IHFS, QueryLanguage.SQL); - if (objects != null) { - for (Object[] crestob : objects) { - crests.addCrestData(new CrestData(crestob)); - } - } - } catch (Exception e) { - statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), - e); - } - } - - if (crests.getCrestDataArray().size() > 0) { - // max stage level, default sort mode - // There is a problem when the stage is not set in the db. - // Added this work around here to manually find the max stage value - double maxStag = 0; - for (int i = 0; i < crests.getCrestDataArray().size(); i++) { - if (crests.getCrestDataArray().get(i).getStage() > maxStag) { - maxStag = crests.getCrestDataArray().get(i).getStage(); - } - } - crests.setMaxStageLevel(maxStag); - - // set the values to gage by - crests.setActionLevel(rdp.getActionStage()); - crests.setMajorLevel(rdp.getMajorStage()); - crests.setMinorLevel(rdp.getMinorStage()); - crests.setModerateLevel(rdp.getModerateStage()); - - // we assume a top of zero at all times, find oldest record - crests.sortByDate(); - CrestData cd5 = crests.getCrestDataArray().get( - crests.getCrestDataArray().size() - 1); - - Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - Date now = SimulatedTime.getSystemTime().getTime(); - cal.setTime(now); - - if (cd5.getCrestDate() != null) { - crests.setStartingYear(cd5.getCrestDate().get(Calendar.YEAR)); - } else { - crests.setStartingYear(HydroConstants.DEFAULT_YEAR); - } - crests.setEndingYear(cal.get(Calendar.YEAR)); - - crests.sortByStage(); - - crestData.put(rdp.getLid(), crests); - } - - return crests; - } - - /** - * Gets the crest data for just the record flood, flow - * - * @param rdp - * @return - */ - public RiverDataPoint getRiverCrest(RiverDataPoint rdp) { - Date date = SimulatedTime.getSystemTime().getTime(); - int allFlag = 0; - CrestHistoryData crests = getRiverCrests(rdp, allFlag); - ArrayList temp = crests.getCrestDataArray(); - if (temp.size() > 0) { - // maximum stage value - crests.sortByStage(); - CrestData cd = temp.get(0); - rdp.setCrestValue(cd.getStage()); - - // maximum flow (q) value for max stage value - rdp.setCrestFlow(cd.getFlow()); - - // Stage Crest date - rdp.setCrestTime(cd.getCrestDate()); - - } else { - // maximum stage value - rdp.setCrestValue(HydroConstants.MISSING_VALUE); - - // maximum flow value - rdp.setCrestFlow(HydroConstants.MISSING_VALUE); - - // sort by date - Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - cal.setTime(date); - rdp.setCrestTime(cal); - } - - return rdp; - } - - /** - * data structure to house the river water shed data - * - * @return HashMap> - */ - public LinkedHashMap> getRiverSummaryData() { - ArrayList data = null; - - try { - data = (ArrayList) DirectDbQuery.executeQuery( - riverPointQuery, HydroConstants.IHFS, QueryLanguage.SQL); - if (data != null) { - riverData = new LinkedHashMap>(); - String riverID = null; - LinkedHashMap riverPoints = null; - for (Object[] point : data) { - RiverDataPoint rdp = new RiverDataPoint(point); - // start - if (riverID == null) { - riverID = rdp.getRiverID(); - riverPoints = new LinkedHashMap(); - riverPoints.put(rdp.getLid(), rdp); - } - // new river switch - else if (!rdp.getRiverID().equals(riverID)) { - // sock away the old one - riverData.put(riverID, riverPoints); - // rename Name - riverID = rdp.getRiverID(); - // create new - riverPoints = new LinkedHashMap(); - riverPoints.put(rdp.getLid(), rdp); - } - // in river run - else { - riverPoints.put(rdp.getLid(), rdp); - } - } - // take care of last river - riverData.put(riverID, riverPoints); - } - } catch (VizException e) { - statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), - e); - } - - return riverData; - } - - /** - * Populate the Data for time and point obs and fcst, really not pretty - * avert your eyes. - * - * @param riverPoints - * @param riverID - * @return HashMap - */ - public LinkedHashMap populateRiverData( - String riverID, LinkedHashMap riverPoints) { - - ArrayList obsdata = null; - ArrayList fcstdata = null; - - try { - String obsquery = riverObsvalueQueryFront + "'" + riverID + "'" - + riverObsvalueQueryBack; - String fcstquery = riverFcstvalueQueryFront + "'" + riverID + "'" - + riverFcstvalueQueryBack; - obsdata = (ArrayList) DirectDbQuery.executeQuery( - obsquery, HydroConstants.IHFS, QueryLanguage.SQL); - fcstdata = (ArrayList) DirectDbQuery.executeQuery( - fcstquery, HydroConstants.IHFS, QueryLanguage.SQL); - if (obsdata != null) { - String lid = null; - Calendar obstime = null; - - for (Object[] obspoint : obsdata) { - if (obspoint[0] != null) { - String newlid = (String) obspoint[0]; - // into - if (!newlid.equals(lid) || (lid == null)) { - lid = newlid; - // we care about this data - if (obspoint[1] != null) { - riverPoints.get(lid).setObsValue( - (Double) obspoint[1]); - } - if (obspoint[2] != null) { - obstime = Calendar.getInstance(TimeZone - .getTimeZone("GMT")); - obstime.setTimeInMillis(((Timestamp) obspoint[2]) - .getTime()); - riverPoints.get(lid).setObsTime(obstime); - } - } - } - } - } - if (fcstdata != null) { - String lid = null; - Calendar fcsttime = null; - - for (Object[] fcstpoint : fcstdata) { - if (fcstpoint[0] != null) { - String newlid = (String) fcstpoint[0]; - // into - if (!newlid.equals(lid) || (lid == null)) { - lid = newlid; - // we care about this data - if (fcstpoint[1] != null) { - riverPoints.get(lid).setFcstValue( - (Double) fcstpoint[1]); - } - if (fcstpoint[2] != null) { - fcsttime = Calendar.getInstance(TimeZone - .getTimeZone("GMT")); - fcsttime.setTimeInMillis(((Timestamp) fcstpoint[2]) - .getTime()); - riverPoints.get(lid).setFcstTime(fcsttime); - } - } - } - } - } - } catch (VizException e) { - statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), - e); - } - - return riverPoints; - } - - /** - * Gets the RiverID for the GageData - * - * @param lid - * @return - */ - public String getRiverID(String lid) { - String riverID = null; - - try { - ArrayList riverObject = (ArrayList) DirectDbQuery - .executeQuery(riverIDQuery + "'" + lid + "'", - HydroConstants.IHFS, QueryLanguage.SQL); - - if (riverObject.size() > 0) { - riverID = (String) (riverObject.get(0))[0]; - } - } catch (VizException e) { - statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), - e); - } - - return riverID; - } - - /** - * Get an individual River Data Point - * - * @param lid - * @return - */ - public RiverDataPoint getRiverDataPoint(String lid) { - - // Get the location information first - RiverDataPoint rdp = new RiverDataPoint(lid); - try { - ArrayList locationObject = (ArrayList) DirectDbQuery - .executeQuery(locationQuery + "'" + lid + "'", - HydroConstants.IHFS, QueryLanguage.SQL); - if (locationObject.size() == 1) { - Object[] location = locationObject.get(0); - if ((String) location[0] != null) { - rdp.setLocName((String) location[0]); - } - if ((String) location[1] != null) { - rdp.setCounty((String) location[1]); - } - if ((String) location[2] != null) { - rdp.setState((String) location[2]); - } - if ((Double) location[3] != null) { - rdp.setElevation((Double) location[3]); - } - if ((String) location[4] != null) { - rdp.setHsa((String) location[4]); - } - if ((Double) location[5] != null) { - rdp.setLat((Double) location[5]); - } - if ((Double) location[6] != null) { - rdp.setLon((Double) location[6]); - } - if ((String) location[7] != null) { - rdp.setRiverName((String) location[7]); - } - } - } catch (VizException e) { - statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), - e); - } - // next find the river stat values - try { - ArrayList statObject = (ArrayList) DirectDbQuery - .executeQuery(riverStatQuery + "'" + lid + "'", - HydroConstants.IHFS, QueryLanguage.SQL); - if (statObject.size() == 1) { - Object[] stat = statObject.get(0); - if ((String) stat[0] != null) { - rdp.setStreamName((String) stat[0]); - } - if ((Double) stat[1] != null) { - rdp.setMile((Double) stat[1]); - } - if ((Double) stat[2] != null) { - rdp.setZeroDatum((Double) stat[2]); - } - if ((String) stat[3] != null) { - rdp.setTide((String) stat[3]); - } - if ((Double) stat[4] != null) { - rdp.setBankFull((Double) stat[4]); - } - if ((Double) stat[5] != null) { - rdp.setActionStage((Double) stat[5]); - } - if ((Double) stat[6] != null) { - rdp.setFloodStage((Double) stat[6]); - } - if ((Double) stat[7] != null) { - rdp.setFloodFlow((Double) stat[7]); - } - if ((Double) stat[8] != null) { - rdp.setActionFlow((Double) stat[8]); - } - if ((String) stat[9] != null) { - rdp.setPrimaryPE((String) stat[9]); - } - } - } catch (VizException e) { - statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), - e); - } - // next find the description values - try { - ArrayList descripObject = (ArrayList) DirectDbQuery - .executeQuery(descriptionQuery + "'" + lid + "'", - HydroConstants.IHFS, QueryLanguage.SQL); - if (descripObject.size() == 1) { - Object[] descrip = descripObject.get(0); - if ((String) descrip[0] != null) { - rdp.setProximity((String) descrip[0]); - } - if ((String) descrip[1] != null) { - rdp.setReach((String) descrip[1]); - } - } - } catch (VizException e) { - statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), - e); - } - // get data for the flood categories - try { - ArrayList floodObject = (ArrayList) DirectDbQuery - .executeQuery(floodCatQuery + "'" + lid + "'", - HydroConstants.IHFS, QueryLanguage.SQL); - if (floodObject.size() == 1) { - Object[] flood = floodObject.get(0); - if ((Double) flood[0] != null) { - rdp.setMinorStage((Double) flood[0]); - } - if ((Double) flood[1] != null) { - rdp.setModerateStage((Double) flood[1]); - } - if ((Double) flood[2] != null) { - rdp.setMajorStage((Double) flood[2]); - } - if ((Double) flood[3] != null) { - rdp.setMinorFlow((Double) flood[3]); - } - if ((Double) flood[4] != null) { - rdp.setModerateFlow((Double) flood[4]); - } - if ((Double) flood[5] != null) { - rdp.setMajorFlow((Double) flood[5]); - } - } - } catch (Exception e) { - statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), - e); - } - // Get data for Crest information - try { - CrestHistoryData crests = new CrestHistoryData(); - ArrayList crestList = crests.getCrestDataArray(); - - ArrayList crestObject = (ArrayList) DirectDbQuery - .executeQuery(crestQuery + lid + "' ORDER BY stage, q", - HydroConstants.IHFS, QueryLanguage.SQL); - - if (crestObject != null) { - for (Object[] crestob : crestObject) { - crests.addCrestData(new CrestData(crestob)); - } - } - if (crestList.size() > 0) { - crests.sortByStage(); - CrestData cd = crestList.get(0); - - rdp.setCrestValue(cd.getStage()); - rdp.setCrestFlow(cd.getFlow()); - rdp.setCrestTime(cd.getCrestDate()); - } - - } catch (Exception e) { - statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), - e); - } - // get data for the river information - try { - ArrayList riverInfoObject = (ArrayList) DirectDbQuery - .executeQuery(riverInfoQuery + "'" + lid + "'", - HydroConstants.IHFS, QueryLanguage.SQL); - if (riverInfoObject.size() == 1) { - Object[] riverInfo = riverInfoObject.get(0); - if ((String) riverInfo[0] != null) { - rdp.setRiverID((String) riverInfo[0]); - } - } - } catch (Exception e) { - statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), - e); - } - - return rdp; - } - - public String getStreamName(String lid) { - List results = null; - String stream = null; - try { - results = DirectDbQuery.executeQuery( - "select stream from riverstat where lid = '" + lid + "'", - HydroConstants.IHFS, QueryLanguage.SQL); - if ((results != null) && (results.size() > 0)) { - stream = (String) results.get(0)[0]; - } - } catch (VizException e) { - statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), - e); - } - - return stream; - } - - /** - * Get the Statprof data for the specified stream. - * - * @param stream - * The stream - * @return The statprof data for the stream. - */ - public List getStatProf(String stream) { -// String query = "from " -// + com.raytheon.edex.plugin.shef.objects.Statprof.class -// .getName(); -// query += " where stream = '" + stream + "' order by mile desc"; - String query = "select lid, name, primary_pe, stream, fs, wstg, fq, " + - "action_flow, zd, mile, reach, proximity from statprof " + - "where stream = '" + stream + "' order by mile desc"; - - List dataList = new ArrayList(); - try { - List results = DirectDbQuery.executeQuery(query, - HydroConstants.IHFS, QueryLanguage.SQL); - if ((results != null) && (results.size() > 0)) { - for (Object[] oa : results) { - if (oa[0] != null) { -// dataList.add((Statprof) oa[0]); - Statprof sp = new Statprof(); - StatprofId spid = new StatprofId(); - spid.setLid((String) oa[0]); - spid.setName((String) oa[1]); - spid.setPrimaryPe((String) oa[2]); - spid.setStream((String) oa[3]); - spid.setFs((Double) oa[4]); - spid.setWstg((Double) oa[5]); - spid.setFq((Double) oa[6]); - spid.setActionFlow((Double) oa[7]); - spid.setZd((Double) oa[8]); - spid.setMile((Double) oa[9]); - spid.setReach((String) oa[10]); - spid.setProximity((String) oa[11]); - sp.setId(spid); - - // Check for missing data values - if (spid.getPrimaryPe() == null) { - continue; - } else if (spid.getPrimaryPe().startsWith("H")) { - if ((spid.getFs() == null) || (spid.getWstg() == null)) { - continue; - } - } else { - if ((spid.getFq() == null) || (spid.getActionFlow() == null)) { - continue; - } - } - dataList.add(sp); - } - } - } - } catch (VizException e) { - statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), - e); - } - - return dataList; - } - - public ArrayList getRiverStatus(String lid, String pe, - long validTime, long basisTime) { - - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - Date validTimeDate = new Date(); - validTimeDate.setTime(validTime); - String validTimeStr = sdf.format(validTimeDate); - Date basisTimeDate = new Date(); - basisTimeDate.setTime(basisTime); - String basisTimeStr = sdf.format(basisTimeDate); - - String where = " where lid = '" + lid + "' " + "and pe = '" + pe - + "' and (validTime > '" + validTimeStr - + "' or ts like 'F%%') and " - + "basisTime is null or basistime >= '" + basisTimeStr + "')"; - - String query = "from " - + com.raytheon.uf.common.dataplugin.shef.tables.Riverstatus.class - .getName(); - query += where; - - ArrayList dataList = null; - try { - List results = DirectDbQuery.executeQuery(query, - HydroConstants.IHFS, QueryLanguage.HQL); - if ((results != null) && (results.size() > 0)) { - dataList = new ArrayList(); - for (Object[] oa : results) { - dataList.add((Riverstatus) oa[0]); - } - } - } catch (VizException e) { - statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), - e); - } - - return dataList; - } - - public List getTsList() { - List rs = null; - - String query = "select distinct(ts), ts_rank from ingestfilter"; - - try { - rs = DirectDbQuery.executeQuery(query, HydroConstants.IHFS, - QueryLanguage.SQL); - } catch (VizException e) { - statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), - e); - } - - return rs; - } + /** Singleton instance of this class */ + private static RiverDataManager riverManager = null; + + /* Private Constructor */ + private RiverDataManager() { + } + + /** + * Get an instance of this singleton. + * + * @return Instance of this class + */ + public static synchronized RiverDataManager getInstance() { + if (riverManager == null) { + riverManager = new RiverDataManager(); + } + return riverManager; + } + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(RiverDataManager.class); + + private LinkedHashMap crestData = null; + + private LinkedHashMap> riverData = null; + + private static String locationQuery = "SELECT name, county, state, elev, hsa, lat, lon, rb from location WHERE lid ="; + + private static String riverStatQuery = "SELECT stream, mile, zd, tide, bf, wstg, fs, fq, action_flow, primary_pe FROM riverstat WHERE lid ="; + + private static String descriptionQuery = "SELECT proximity, reach FROM descrip WHERE lid ="; + + private static String crestQuery = "select stage, q, datcrst, timcrst, cremark, hw, jam, olddatum, suppress, prelim from crest where lid = '"; + + private static String floodCatQuery = "SELECT minor_stage, moderate_stage, major_stage, minor_flow, moderate_flow, major_flow from floodcat WHERE lid = "; + + private static String riverInfoQuery = "SELECT rivermonlocation.group_id, rivermongroup.group_name FROM rivermongroup, rivermonlocation WHERE rivermongroup.group_id = rivermonlocation.group_id AND rivermonlocation.lid = "; + + private static String riverPointQuery = "SELECT l.lid, l.name, l.county, l.state, l.elev, l.hsa, l.lat, l.lon, " + + "rml.group_id, " + + "rmg.group_name, " + + "r.stream, r.mile, r.zd AS zero, r.tide, r.bf AS bankfull, r.wstg AS action_stage, r.fs AS flood_stage, r.fq AS flood_flow, r.action_flow, r.primary_pe, " + + "d.proximity, d.reach, " + + "f.minor_stage AS minor, f.moderate_stage AS moderate, f.major_stage AS major, f.minor_flow AS minor, f.moderate_flow AS moderate, f.major_flow AS major " + + "FROM location l " + + "LEFT JOIN floodcat f ON l.lid::text = f.lid::text " + + "LEFT JOIN descrip d ON l.lid::text = d.lid::text, riverstat r, rivermonlocation rml " + + "LEFT JOIN rivermongroup rmg ON rml.group_id::text = rmg.group_id::text " + + "WHERE l.lid::text = r.lid::text and r.lid::text = rml.lid::text " + + "ORDER BY rml.group_id, r.mile desc"; + + private static String riverObsvalueQueryFront = "SELECT distinct(foo.lid), foo.value, foo.maxtime from " + + "(SELECT distinct height.lid, height.value, max(height.obstime) as maxtime " + + "FROM height " + + "WHERE height.lid in " + + "(select distinct(lid) " + + "from rivermonlocation " + + "where rivermonlocation.group_id = "; + + private static String riverObsvalueQueryBack = ") GROUP BY height.lid, height.value) " + + "AS foo " + + "GROUP BY foo.lid, foo.value, foo.maxtime order by foo.lid, foo.maxtime desc"; + + private static String riverFcstvalueQueryFront = "SELECT distinct(foo.lid), foo.value, foo.maxtime from " + + "(SELECT distinct fcstheight.lid, fcstheight.value, max(fcstheight.validtime) as maxtime " + + "FROM fcstheight " + + "WHERE fcstheight.lid in " + + "(select distinct(lid) " + + "from rivermonlocation " + + "where rivermonlocation.group_id = "; + + private static String riverFcstvalueQueryBack = ") GROUP BY fcstheight.lid, fcstheight.value) " + + "AS foo " + + "GROUP BY foo.lid, foo.value, foo.maxtime order by foo.lid, foo.maxtime desc"; + + private static String riverIDQuery = "SELECT group_id FROM rivermonlocation where lid ="; + + /** + * River Query Crest + * + * @param lid + * @return CrestHistoryData + */ + public CrestHistoryData getRiverCrests(RiverDataPoint rdp, int allFlag) { + CrestHistoryData crests = null; + + if (crestData == null) { + crestData = new LinkedHashMap(); + } + + crests = new CrestHistoryData(); + String query = null; + + /* get crest data depending on action stage */ + if (rdp != null) { + String sql = "select stage, q, datcrst, timcrst, cremark, hw, jam, olddatum, suppress, prelim " + + "from crest where lid = '" + rdp.getLid(); + + if (allFlag == 1) { + query = sql + "' and stage >'" + rdp.getActionStage() + + "' ORDER BY stage, q"; + } else if (allFlag == 2) { + query = sql + "' and stage <'" + rdp.getActionStage() + + "' ORDER BY stage, q"; + } else { + query = sql + "' ORDER BY stage, q"; + } + + ArrayList objects = null; + + try { + objects = (ArrayList) DirectDbQuery.executeQuery( + query, HydroConstants.IHFS, QueryLanguage.SQL); + if (objects != null) { + for (Object[] crestob : objects) { + crests.addCrestData(new CrestData(crestob)); + } + } + } catch (Exception e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), + e); + } + } + + if (crests.getCrestDataArray().size() > 0) { + // max stage level, default sort mode + // There is a problem when the stage is not set in the db. + // Added this work around here to manually find the max stage value + double maxStag = 0; + double minStag = Double.MAX_VALUE; + for (int i = 0; i < crests.getCrestDataArray().size(); i++) { + if (crests.getCrestDataArray().get(i).getStage() > maxStag) { + maxStag = crests.getCrestDataArray().get(i).getStage(); + } + if (crests.getCrestDataArray().get(i).getStage() < minStag && + crests.getCrestDataArray().get(i).getStage() >= 0) { + minStag = crests.getCrestDataArray().get(i).getStage(); + } + + } + crests.setMaxStageLevel(maxStag); + crests.setMinStageLevel(minStag); + + // set the values to gage by + crests.setActionLevel(rdp.getActionStage()); + crests.setMajorLevel(rdp.getMajorStage()); + crests.setMinorLevel(rdp.getMinorStage()); + crests.setModerateLevel(rdp.getModerateStage()); + + // we assume a top of zero at all times, find oldest record + crests.sortByDate(); + CrestData cd5 = crests.getCrestDataArray().get( + crests.getCrestDataArray().size() - 1); + + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + Date now = SimulatedTime.getSystemTime().getTime(); + cal.setTime(now); + + if (cd5.getCrestDate() != null) { + crests.setStartingYear(cd5.getCrestDate().get(Calendar.YEAR)); + } else { + crests.setStartingYear(HydroConstants.DEFAULT_YEAR); + } + crests.setEndingYear(cal.get(Calendar.YEAR)); + + crests.sortByStage(); + + crestData.put(rdp.getLid(), crests); + } + + return crests; + } + + /** + * Gets the crest data for just the record flood, flow + * + * @param rdp + * @return + */ + public RiverDataPoint getRiverCrest(RiverDataPoint rdp) { + Date date = SimulatedTime.getSystemTime().getTime(); + int allFlag = 0; + CrestHistoryData crests = getRiverCrests(rdp, allFlag); + ArrayList temp = crests.getCrestDataArray(); + if (temp.size() > 0) { + // maximum stage value + crests.sortByStage(); + CrestData cd = temp.get(0); + rdp.setCrestValue(cd.getStage()); + + // maximum flow (q) value for max stage value + rdp.setCrestFlow(cd.getFlow()); + + // Stage Crest date + rdp.setCrestTime(cd.getCrestDate()); + + } else { + // maximum stage value + rdp.setCrestValue(HydroConstants.MISSING_VALUE); + + // maximum flow value + rdp.setCrestFlow(HydroConstants.MISSING_VALUE); + + // sort by date + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + cal.setTime(date); + rdp.setCrestTime(cal); + } + + return rdp; + } + + /** + * data structure to house the river water shed data + * + * @return HashMap> + */ + public LinkedHashMap> getRiverSummaryData() { + ArrayList data = null; + + try { + data = (ArrayList) DirectDbQuery.executeQuery( + riverPointQuery, HydroConstants.IHFS, QueryLanguage.SQL); + if (data != null) { + riverData = new LinkedHashMap>(); + String riverID = null; + LinkedHashMap riverPoints = null; + for (Object[] point : data) { + RiverDataPoint rdp = new RiverDataPoint(point); + // start + if (riverID == null) { + riverID = rdp.getRiverID(); + riverPoints = new LinkedHashMap(); + riverPoints.put(rdp.getLid(), rdp); + } + // new river switch + else if (!rdp.getRiverID().equals(riverID)) { + // sock away the old one + riverData.put(riverID, riverPoints); + // rename Name + riverID = rdp.getRiverID(); + // create new + riverPoints = new LinkedHashMap(); + riverPoints.put(rdp.getLid(), rdp); + } + // in river run + else { + riverPoints.put(rdp.getLid(), rdp); + } + } + // take care of last river + riverData.put(riverID, riverPoints); + } + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); + } + + return riverData; + } + + /** + * Populate the Data for time and point obs and fcst, really not pretty + * avert your eyes. + * + * @param riverPoints + * @param riverID + * @return HashMap + */ + public LinkedHashMap populateRiverData( + String riverID, LinkedHashMap riverPoints) { + + ArrayList obsdata = null; + ArrayList fcstdata = null; + + try { + String obsquery = riverObsvalueQueryFront + "'" + riverID + "'" + + riverObsvalueQueryBack; + String fcstquery = riverFcstvalueQueryFront + "'" + riverID + "'" + + riverFcstvalueQueryBack; + obsdata = (ArrayList) DirectDbQuery.executeQuery( + obsquery, HydroConstants.IHFS, QueryLanguage.SQL); + fcstdata = (ArrayList) DirectDbQuery.executeQuery( + fcstquery, HydroConstants.IHFS, QueryLanguage.SQL); + if (obsdata != null) { + String lid = null; + Calendar obstime = null; + + for (Object[] obspoint : obsdata) { + if (obspoint[0] != null) { + String newlid = (String) obspoint[0]; + // into + if (!newlid.equals(lid) || (lid == null)) { + lid = newlid; + // we care about this data + if (obspoint[1] != null) { + riverPoints.get(lid).setObsValue( + (Double) obspoint[1]); + } + if (obspoint[2] != null) { + obstime = Calendar.getInstance(TimeZone + .getTimeZone("GMT")); + obstime.setTimeInMillis(((Timestamp) obspoint[2]) + .getTime()); + riverPoints.get(lid).setObsTime(obstime); + } + } + } + } + } + if (fcstdata != null) { + String lid = null; + Calendar fcsttime = null; + + for (Object[] fcstpoint : fcstdata) { + if (fcstpoint[0] != null) { + String newlid = (String) fcstpoint[0]; + // into + if (!newlid.equals(lid) || (lid == null)) { + lid = newlid; + // we care about this data + if (fcstpoint[1] != null) { + riverPoints.get(lid).setFcstValue( + (Double) fcstpoint[1]); + } + if (fcstpoint[2] != null) { + fcsttime = Calendar.getInstance(TimeZone + .getTimeZone("GMT")); + fcsttime.setTimeInMillis(((Timestamp) fcstpoint[2]) + .getTime()); + riverPoints.get(lid).setFcstTime(fcsttime); + } + } + } + } + } + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); + } + + return riverPoints; + } + + /** + * Gets the RiverID for the GageData + * + * @param lid + * @return + */ + public String getRiverID(String lid) { + String riverID = null; + + try { + ArrayList riverObject = (ArrayList) DirectDbQuery + .executeQuery(riverIDQuery + "'" + lid + "'", + HydroConstants.IHFS, QueryLanguage.SQL); + + if (riverObject.size() > 0) { + riverID = (String) (riverObject.get(0))[0]; + } + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); + } + + return riverID; + } + + /** + * Get an individual River Data Point + * + * @param lid + * @return + */ + public RiverDataPoint getRiverDataPoint(String lid) { + + // Get the location information first + RiverDataPoint rdp = new RiverDataPoint(lid); + try { + ArrayList locationObject = (ArrayList) DirectDbQuery + .executeQuery(locationQuery + "'" + lid + "'", + HydroConstants.IHFS, QueryLanguage.SQL); + if (locationObject.size() == 1) { + Object[] location = locationObject.get(0); + if ((String) location[0] != null) { + rdp.setLocName((String) location[0]); + } + if ((String) location[1] != null) { + rdp.setCounty((String) location[1]); + } + if ((String) location[2] != null) { + rdp.setState((String) location[2]); + } + if ((Double) location[3] != null) { + rdp.setElevation((Double) location[3]); + } + if ((String) location[4] != null) { + rdp.setHsa((String) location[4]); + } + if ((Double) location[5] != null) { + rdp.setLat((Double) location[5]); + } + if ((Double) location[6] != null) { + rdp.setLon((Double) location[6]); + } + if ((String) location[7] != null) { + rdp.setRiverName((String) location[7]); + } + } + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); + } + // next find the river stat values + try { + ArrayList statObject = (ArrayList) DirectDbQuery + .executeQuery(riverStatQuery + "'" + lid + "'", + HydroConstants.IHFS, QueryLanguage.SQL); + if (statObject.size() == 1) { + Object[] stat = statObject.get(0); + if ((String) stat[0] != null) { + rdp.setStreamName((String) stat[0]); + } + if ((Double) stat[1] != null) { + rdp.setMile((Double) stat[1]); + } + if ((Double) stat[2] != null) { + rdp.setZeroDatum((Double) stat[2]); + } + if ((String) stat[3] != null) { + rdp.setTide((String) stat[3]); + } + if ((Double) stat[4] != null) { + rdp.setBankFull((Double) stat[4]); + } + if ((Double) stat[5] != null) { + rdp.setActionStage((Double) stat[5]); + } + if ((Double) stat[6] != null) { + rdp.setFloodStage((Double) stat[6]); + } + if ((Double) stat[7] != null) { + rdp.setFloodFlow((Double) stat[7]); + } + if ((Double) stat[8] != null) { + rdp.setActionFlow((Double) stat[8]); + } + if ((String) stat[9] != null) { + rdp.setPrimaryPE((String) stat[9]); + } + } + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); + } + // next find the description values + try { + ArrayList descripObject = (ArrayList) DirectDbQuery + .executeQuery(descriptionQuery + "'" + lid + "'", + HydroConstants.IHFS, QueryLanguage.SQL); + if (descripObject.size() == 1) { + Object[] descrip = descripObject.get(0); + if ((String) descrip[0] != null) { + rdp.setProximity((String) descrip[0]); + } + if ((String) descrip[1] != null) { + rdp.setReach((String) descrip[1]); + } + } + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); + } + // get data for the flood categories + try { + ArrayList floodObject = (ArrayList) DirectDbQuery + .executeQuery(floodCatQuery + "'" + lid + "'", + HydroConstants.IHFS, QueryLanguage.SQL); + if (floodObject.size() == 1) { + Object[] flood = floodObject.get(0); + if ((Double) flood[0] != null) { + rdp.setMinorStage((Double) flood[0]); + } + if ((Double) flood[1] != null) { + rdp.setModerateStage((Double) flood[1]); + } + if ((Double) flood[2] != null) { + rdp.setMajorStage((Double) flood[2]); + } + if ((Double) flood[3] != null) { + rdp.setMinorFlow((Double) flood[3]); + } + if ((Double) flood[4] != null) { + rdp.setModerateFlow((Double) flood[4]); + } + if ((Double) flood[5] != null) { + rdp.setMajorFlow((Double) flood[5]); + } + } + } catch (Exception e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); + } + // Get data for Crest information + try { + CrestHistoryData crests = new CrestHistoryData(); + ArrayList crestList = crests.getCrestDataArray(); + + ArrayList crestObject = (ArrayList) DirectDbQuery + .executeQuery(crestQuery + lid + "' ORDER BY stage, q", + HydroConstants.IHFS, QueryLanguage.SQL); + + if (crestObject != null) { + for (Object[] crestob : crestObject) { + crests.addCrestData(new CrestData(crestob)); + } + } + if (crestList.size() > 0) { + crests.sortByStage(); + CrestData cd = crestList.get(0); + + rdp.setCrestValue(cd.getStage()); + rdp.setCrestFlow(cd.getFlow()); + rdp.setCrestTime(cd.getCrestDate()); + } + + } catch (Exception e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); + } + // get data for the river information + try { + ArrayList riverInfoObject = (ArrayList) DirectDbQuery + .executeQuery(riverInfoQuery + "'" + lid + "'", + HydroConstants.IHFS, QueryLanguage.SQL); + if (riverInfoObject.size() == 1) { + Object[] riverInfo = riverInfoObject.get(0); + if ((String) riverInfo[0] != null) { + rdp.setRiverID((String) riverInfo[0]); + } + } + } catch (Exception e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); + } + + return rdp; + } + + public String getStreamName(String lid) { + List results = null; + String stream = null; + try { + results = DirectDbQuery.executeQuery( + "select stream from riverstat where lid = '" + lid + "'", + HydroConstants.IHFS, QueryLanguage.SQL); + if ((results != null) && (results.size() > 0)) { + stream = (String) results.get(0)[0]; + } + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); + } + + return stream; + } + + /** + * Get the Statprof data for the specified stream. + * + * @param stream + * The stream + * @return The statprof data for the stream. + */ + public List getStatProf(String stream) { + // String query = "from " + // + com.raytheon.edex.plugin.shef.objects.Statprof.class + // .getName(); + // query += " where stream = '" + stream + "' order by mile desc"; + String query = "select lid, name, primary_pe, stream, fs, wstg, fq, " + + "action_flow, zd, mile, reach, proximity from statprof " + + "where stream = '" + stream + "' order by mile desc"; + + List dataList = new ArrayList(); + try { + List results = DirectDbQuery.executeQuery(query, + HydroConstants.IHFS, QueryLanguage.SQL); + if ((results != null) && (results.size() > 0)) { + for (Object[] oa : results) { + if (oa[0] != null) { + // dataList.add((Statprof) oa[0]); + Statprof sp = new Statprof(); + StatprofId spid = new StatprofId(); + spid.setLid((String) oa[0]); + spid.setName((String) oa[1]); + spid.setPrimaryPe((String) oa[2]); + spid.setStream((String) oa[3]); + spid.setFs((Double) oa[4]); + spid.setWstg((Double) oa[5]); + spid.setFq((Double) oa[6]); + spid.setActionFlow((Double) oa[7]); + spid.setZd((Double) oa[8]); + spid.setMile((Double) oa[9]); + spid.setReach((String) oa[10]); + spid.setProximity((String) oa[11]); + sp.setId(spid); + + // Check for missing data values + if (spid.getPrimaryPe() == null) { + continue; + } else if (spid.getPrimaryPe().startsWith("H")) { + if ((spid.getFs() == null) + || (spid.getWstg() == null)) { + continue; + } + } else { + if ((spid.getFq() == null) + || (spid.getActionFlow() == null)) { + continue; + } + } + dataList.add(sp); + } + } + } + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); + } + + return dataList; + } + + public ArrayList getRiverStatus(String lid, String pe, + long validTime, long basisTime) { + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date validTimeDate = new Date(); + validTimeDate.setTime(validTime); + String validTimeStr = sdf.format(validTimeDate); + Date basisTimeDate = new Date(); + basisTimeDate.setTime(basisTime); + String basisTimeStr = sdf.format(basisTimeDate); + + String where = " where lid = '" + lid + "' " + "and pe = '" + pe + + "' and (validTime > '" + validTimeStr + + "' or ts like 'F%%') and " + + "basisTime is null or basistime >= '" + basisTimeStr + "')"; + + String query = "from " + + com.raytheon.uf.common.dataplugin.shef.tables.Riverstatus.class + .getName(); + query += where; + + ArrayList dataList = null; + try { + List results = DirectDbQuery.executeQuery(query, + HydroConstants.IHFS, QueryLanguage.HQL); + if ((results != null) && (results.size() > 0)) { + dataList = new ArrayList(); + for (Object[] oa : results) { + dataList.add((Riverstatus) oa[0]); + } + } + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); + } + + return dataList; + } + + public List getTsList() { + List rs = null; + + String query = "select distinct(ts), ts_rank from ingestfilter"; + + try { + rs = DirectDbQuery.executeQuery(query, HydroConstants.IHFS, + QueryLanguage.SQL); + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); + } + + return rs; + } } diff --git a/cave/com.raytheon.viz.hydrocommon/src/com/raytheon/viz/hydrocommon/resource/FFGGridResource.java b/cave/com.raytheon.viz.hydrocommon/src/com/raytheon/viz/hydrocommon/resource/FFGGridResource.java index 4afad9088b..6d12ba1311 100644 --- a/cave/com.raytheon.viz.hydrocommon/src/com/raytheon/viz/hydrocommon/resource/FFGGridResource.java +++ b/cave/com.raytheon.viz.hydrocommon/src/com/raytheon/viz/hydrocommon/resource/FFGGridResource.java @@ -141,7 +141,7 @@ public class FFGGridResource extends String user_id = System.getProperty("user.name"); this.duration = data.getDuration(); colorSet = HydroDisplayManager.getInstance().getFFGColorMap(user_id, - "FFG", duration * 60 * 1000); + "FFG", duration); loadData(); } @@ -260,7 +260,7 @@ public class FFGGridResource extends sdf.setTimeZone(TimeZone.getTimeZone("GMT")); int hours = this.resourceData.getDuration() - / HydroConstants.MILLIS_PER_HOUR; + / HydroConstants.SECONDS_PER_HOUR; String hourStr = "hour"; if (hours != 1) { hourStr = hourStr.concat("s"); diff --git a/cave/com.raytheon.viz.satellite/localization/bundles/DefaultSatellite.xml b/cave/com.raytheon.viz.satellite/localization/bundles/DefaultSatellite.xml index f484bc9e18..378e53b0e6 100644 --- a/cave/com.raytheon.viz.satellite/localization/bundles/DefaultSatellite.xml +++ b/cave/com.raytheon.viz.satellite/localization/bundles/DefaultSatellite.xml @@ -34,7 +34,6 @@ - 12 diff --git a/cave/com.raytheon.viz.satellite/localization/bundles/DerivedPOESSatellite.xml b/cave/com.raytheon.viz.satellite/localization/bundles/DerivedPOESSatellite.xml index 9eb5f9b308..7c19d6c02e 100644 --- a/cave/com.raytheon.viz.satellite/localization/bundles/DerivedPOESSatellite.xml +++ b/cave/com.raytheon.viz.satellite/localization/bundles/DerivedPOESSatellite.xml @@ -31,7 +31,6 @@ - 12 diff --git a/cave/com.raytheon.viz.satellite/localization/bundles/DerivedSatellite.xml b/cave/com.raytheon.viz.satellite/localization/bundles/DerivedSatellite.xml index fc3f481e85..5898a9cc83 100644 --- a/cave/com.raytheon.viz.satellite/localization/bundles/DerivedSatellite.xml +++ b/cave/com.raytheon.viz.satellite/localization/bundles/DerivedSatellite.xml @@ -37,7 +37,6 @@ - 12 diff --git a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/AfosBrowserModel.java b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/AfosBrowserModel.java index 5df303dc08..0c9b3c9f1c 100755 --- a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/AfosBrowserModel.java +++ b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/AfosBrowserModel.java @@ -64,7 +64,10 @@ import com.raytheon.uf.viz.core.localization.LocalizationManager; * 11/8/2007 520 grichard Implemented build 11 features. * 11/26/2007 520 grichard Implemented SuperSite in preparation for JiBX'ng. * 12/14/2007 582 grichard Implemented build 12 features. - * + * ====================================== + * AWIPS2 DR Work + * 07/24/2012 939 jkorman Modified parseAfosMasterPil() handle blank lines as well + * as lines with trailing whitespace. * * * @author grichard @@ -73,6 +76,21 @@ public final class AfosBrowserModel { private static final transient IUFStatusHandler statusHandler = UFStatus .getHandler(AfosBrowserModel.class); + // Need at least this many characters in an afosMasterPIL entry + // Need the CCCNNN and at least a 1 character XXX + private static final int MIN_MASTPIL_LEN = 7; + // but no more than 9 characters. + private static final int MAX_MASTPIL_LEN = 9; + + private static final int CCC_PIL_POS = 0; + + private static final int NNN_PIL_POS = 3; + + private static final int XXX_PIL_POS = 6; + + private static final String SITE_WILDCARD = "@@@"; + + private static final String COMMENT_DELIM = "#"; /** * The VTEC Afos Product enumeration */ @@ -265,7 +283,7 @@ public final class AfosBrowserModel { br = new BufferedReader(new FileReader(fileToParse)); while ((line = br.readLine()) != null) { // skip comments. - if (line.startsWith("#")) { + if (line.startsWith(COMMENT_DELIM)) { continue; } @@ -294,7 +312,7 @@ public final class AfosBrowserModel { br = new BufferedReader(new FileReader(fileToParse)); while ((line = br.readLine()) != null) { // skip comments. - if (line.startsWith("#")) { + if (line.startsWith(COMMENT_DELIM)) { continue; } @@ -324,7 +342,7 @@ public final class AfosBrowserModel { br = new BufferedReader(new FileReader(fileToParse)); while ((line = br.readLine()) != null) { // skip comments. - if (line.startsWith("#")) { + if (line.startsWith(COMMENT_DELIM)) { continue; } @@ -351,42 +369,69 @@ public final class AfosBrowserModel { return cccOriginMap; } + /** + * Read and parse an afos PIL list. In the event of processing multiple + * files, the most recent entry overwrites a current entry. + * + * @param fileToParse + * File reference containing the PIL list. + */ private void parseAfosMasterPil(File fileToParse) { if (fileToParse != null && fileToParse.exists()) { BufferedReader br = null; String line = null; + String localCCC = SiteMap.getInstance() + .getCCCFromXXXCode(localSite); try { br = new BufferedReader(new FileReader(fileToParse)); while ((line = br.readLine()) != null) { - // skip comments. - if (line.startsWith("#")) { + // Remove any trailing spaces. + line = line.trim(); + // skip blank lines or comments. + if ((line.length() == 0) || line.startsWith(COMMENT_DELIM)) { continue; } - String ccc = line.substring(0, 3); + if (line.length() >= MIN_MASTPIL_LEN) { + String ccc = line.substring(CCC_PIL_POS, NNN_PIL_POS); + if (ccc.equals(SITE_WILDCARD)) { + ccc = localCCC; + } + String nnn = line.substring(NNN_PIL_POS, XXX_PIL_POS); + String xxx; + if(line.length() > MAX_MASTPIL_LEN) { + // Only take the first 9 characters of the line. + // Trim in case there are any internal spaces. + xxx = line.substring(XXX_PIL_POS, MAX_MASTPIL_LEN + 1).trim(); + } else { + // Just grab the remainder of the input line. + // Its already been trimmed. + xxx = line.substring(6); + } - if (ccc.equals("@@@")) { - ccc = SiteMap.getInstance() - .getCCCFromXXXCode(localSite); + Map> nnnxxx = masterPil + .get(ccc); + if (nnnxxx == null) { + nnnxxx = new HashMap>(); + masterPil.put(ccc, nnnxxx); + } + + SortedSet xxxList = nnnxxx.get(nnn); + if (xxxList == null) { + xxxList = new TreeSet(); + nnnxxx.put(nnn, xxxList); + } + + xxxList.add(xxx); + } else { + String msg = String.format( + "Line [%s] in file %s incorrect", line, + fileToParse.getPath()); + + statusHandler.handle(Priority.SIGNIFICANT, msg); } - String nnn = line.substring(3, 6); - String xxx = line.substring(6); - - Map> nnnxxx = masterPil.get(ccc); - if (nnnxxx == null) { - nnnxxx = new HashMap>(); - masterPil.put(ccc, nnnxxx); - } - - SortedSet xxxList = nnnxxx.get(nnn); - if (xxxList == null) { - xxxList = new TreeSet(); - nnnxxx.put(nnn, xxxList); - } - - xxxList.add(xxx); } // while } catch (IOException e) { statusHandler.handle(Priority.PROBLEM, @@ -519,7 +564,7 @@ public final class AfosBrowserModel { public boolean contains(String ccc, String nnn, String xxx) { boolean rval = false; Map> catMap = masterPil.get(ccc); - if (catMap != null) { + if ((catMap != null) && (xxx != null)) { SortedSet desList = catMap.get(nnn); if (desList != null) { rval = desList.contains(xxx); diff --git a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/dialogs/AlarmAlertBell.java b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/dialogs/AlarmAlertBell.java index 18d5075f78..099e8c73c6 100644 --- a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/dialogs/AlarmAlertBell.java +++ b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/dialogs/AlarmAlertBell.java @@ -67,6 +67,7 @@ import com.raytheon.viz.texteditor.alarmalert.util.FlashBellJob; * Dec 23, 2010 7375 cjeanbap Force dialog ON TOP of over Dialog/Windows. * 03/19/2012 D. Friedman Fix alarming. Disable runloop in open(). * May 18, 2012 jkorman Added flashing alarm image. + * Jul 25, 2012 15122 rferrel Add sound delay interval. * * * @author mnash @@ -75,10 +76,15 @@ import com.raytheon.viz.texteditor.alarmalert.util.FlashBellJob; public class AlarmAlertBell extends Dialog implements MouseMoveListener, MouseListener { - + // delay in milliseconds - flash every 1 1/2 seconds private static final int FLASH_DELAY = 1500; - + + /** + * Repeat the alarm sound every minute. + */ + private static final long SOUND_DELAY = 60 * 1000L; + private Shell parentShell; private Shell alarmShell; @@ -90,15 +96,15 @@ public class AlarmAlertBell extends Dialog implements MouseMoveListener, private String bellPath; private FlashBellJob flasher; - + private Image norm_bell; private Image revs_bell; private boolean invert = false; - + private boolean active = false; - + private Button button; private AlarmBeepJob abj = null; @@ -196,9 +202,9 @@ public class AlarmAlertBell extends Dialog implements MouseMoveListener, } public Object open(boolean alarm) { - if (alarm) { + if (alarm && abj == null) { // provides the beep to alert the user that an alarm has come in - abj = new AlarmBeepJob("AlarmBeepJob"); + abj = new AlarmBeepJob("AlarmBeepJob", SOUND_DELAY); abj.schedule(); } @@ -216,28 +222,33 @@ public class AlarmAlertBell extends Dialog implements MouseMoveListener, alarmShell.setActive(); active = true; // Start a new flash job only if one isn't currently running! - if(flasher == null) { + if (flasher == null) { invert = false; flasher = new FlashBellJob("FlashBell", this, FLASH_DELAY); } + return null; } /** - * Close the AlarmAlertBell and turn off the "flasher" job - * if running. + * Close the AlarmAlertBell and turn off the "flasher" and "abj" job if + * running. */ public void close() { - if(!alarmShell.isDisposed()) { + if (!alarmShell.isDisposed()) { alarmShell.setVisible(false); } active = false; - if(flasher != null) { + if (flasher != null) { flasher.cancel(); flasher = null; } + if (abj != null) { + abj.cancel(); + abj = null; + } } - + private void setInitialDialogLocation() { if (locationX < 0) { Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); @@ -263,7 +274,7 @@ public class AlarmAlertBell extends Dialog implements MouseMoveListener, bellPath = imageFile.getFile().getAbsolutePath(); norm_bell = new Image(display, bellPath); button = new Button(alarmShell, SWT.IMAGE_GIF); - if(norm_bell != null) { + if (norm_bell != null) { createInvertImage(bellPath); button.setImage(norm_bell); } @@ -330,12 +341,12 @@ public class AlarmAlertBell extends Dialog implements MouseMoveListener, private void createInvertImage(String path) { if (norm_bell != null) { ImageData id = new ImageData(path); - for(int i = 0;i < id.width;i++) { - for(int j = 0;j < id.height;j++) { - if(id.getPixel(i,j) == 0) { - id.setPixel(i,j,1); + for (int i = 0; i < id.width; i++) { + for (int j = 0; j < id.height; j++) { + if (id.getPixel(i, j) == 0) { + id.setPixel(i, j, 1); } else { - id.setPixel(i,j,0); + id.setPixel(i, j, 0); } } } @@ -345,17 +356,18 @@ public class AlarmAlertBell extends Dialog implements MouseMoveListener, /** * Check to see if the dialog is active. + * * @return */ public boolean isActive() { return active; } - + /** * Alternate between normal and reverse images. */ public void flash() { - if(invert) { + if (invert) { button.setImage(revs_bell); } else { button.setImage(norm_bell); diff --git a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/dialogs/AlarmAlertSaveLoadDlg.java b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/dialogs/AlarmAlertSaveLoadDlg.java index ee467d4ba4..d36cf44d40 100644 --- a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/dialogs/AlarmAlertSaveLoadDlg.java +++ b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/dialogs/AlarmAlertSaveLoadDlg.java @@ -20,6 +20,7 @@ package com.raytheon.viz.texteditor.alarmalert.dialogs; import java.io.File; +import java.util.ArrayList; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; @@ -37,6 +38,10 @@ import org.eclipse.swt.widgets.Text; import com.raytheon.uf.common.localization.LocalizationContext; import com.raytheon.uf.common.localization.LocalizationFile; import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException; +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.viz.texteditor.alarmalert.util.AlarmAlertFunctions; import com.raytheon.viz.ui.dialogs.CaveSWTDialog; @@ -49,6 +54,10 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Sep 17, 2009 mnash Initial creation + * ====================================== + * AWIPS2 DR Work + * 07/25/2012 953 jkorman Modified file "search" to return LocalizationFile + * instead of File so references are deleted in all locations. * * * @@ -58,6 +67,9 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog; public class AlarmAlertSaveLoadDlg extends CaveSWTDialog { + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(AlarmAlertSaveLoadDlg.class); + private Font font; private Composite shellComp; @@ -136,13 +148,21 @@ public class AlarmAlertSaveLoadDlg extends CaveSWTDialog { gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); lists.setLayoutData(gd); LocalizationContext lc = AlarmAlertFunctions.initUserLocalization(); - LocalizationFile fileDir = PathManagerFactory.getPathManager() - .getLocalizationFile(lc, "alarms"); - File file = fileDir.getFile(); - final File[] fileList = file.listFiles(); - for (File locFile : fileList) { - if (locFile.getName().endsWith(".xml")) { - lists.add(locFile.getName()); + + // Get a list of localization files! + LocalizationFile[] fList = PathManagerFactory.getPathManager() + .listFiles(lc, "alarms", new String[] { "xml" }, false, true); + + final java.util.List fileList = new ArrayList(); + for (LocalizationFile locFile : fList) { + // We only want the filename in the display list. + String[] s = locFile.getName().split("/"); + // Make sure we have some data! + if (s.length > 0) { + // The last element is the filename. + lists.add(s[s.length - 1]); + // Complete file reference here. + fileList.add(locFile); } } @@ -170,17 +190,30 @@ public class AlarmAlertSaveLoadDlg extends CaveSWTDialog { // loads the loadButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { + // Set the filename to be returned through getFileName() fileName = lists.getSelection()[0]; - // TODO load the file shell.close(); } }); - // delete the file from the list and from the file system + // delete the file from the display list and from the file system deleteButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { int num = lists.getSelectionIndex(); - fileList[num].delete(); + LocalizationFile f = fileList.get(num); + try { + if (!f.delete()) { + String msg = String.format( + "ALARM/ALERT:Failed deleting file %s", f + .getFile().getPath()); + statusHandler.handle(Priority.PROBLEM, msg); + } + } catch (LocalizationOpFailedException e) { + String msg = String.format( + "ALARM/ALERT:Failed deleting file %s", f.getFile() + .getPath()); + statusHandler.handle(Priority.PROBLEM, msg, e); + } lists.remove(num); } }); @@ -250,8 +283,8 @@ public class AlarmAlertSaveLoadDlg extends CaveSWTDialog { // get the file name saveButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { + // Set the filename to be returned through getFileName() fileName = textBox.getText(); - // TODO load the file shell.close(); } }); diff --git a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/dialogs/AlarmDisplayWindow.java b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/dialogs/AlarmDisplayWindow.java index 01d6dc1b7e..f6c7545f1d 100644 --- a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/dialogs/AlarmDisplayWindow.java +++ b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/dialogs/AlarmDisplayWindow.java @@ -188,15 +188,17 @@ public class AlarmDisplayWindow extends CaveSWTDialog { lines.append(text.getLine(lineIndex)).append("\n"); } - PrintDisplay.print(true, lines.toString(), - UFStatus.getHandler(AlarmDisplayWindow.class)); + PrintDisplay.print(lines.toString(), text.getFont() + .getFontData()[0], UFStatus + .getHandler(AlarmDisplayWindow.class)); } }); printBuffer.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { - PrintDisplay.print(true, text.getText(), + PrintDisplay.print(text.getText(), + text.getFont().getFontData()[0], UFStatus.getHandler(AlarmDisplayWindow.class)); } }); diff --git a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/util/AlarmAlertFunctions.java b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/util/AlarmAlertFunctions.java index 8b1290ff2a..5092709723 100644 --- a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/util/AlarmAlertFunctions.java +++ b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/util/AlarmAlertFunctions.java @@ -27,8 +27,6 @@ import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import javax.xml.bind.JAXB; @@ -76,7 +74,7 @@ public class AlarmAlertFunctions { private static final AlarmAlertProduct.ProductType AA = AlarmAlertProduct.ProductType.Alarm_Alert; private static final AlarmAlertProduct.ProductType PA = AlarmAlertProduct.ProductType.Proximity_Alarm; - + private static final Object configFileLock = new Object(); private static final String ALARM_ALERT_PATH = "alarms" + File.separator; @@ -130,50 +128,52 @@ public class AlarmAlertFunctions { */ public static void isInAlarmList(AlarmAlertProduct prod) { AlarmAlertLists instance = AlarmAlertLists.getInstance(); - + List currentAlarms = instance.getFilteredProducts(); boolean alarm = false; - List prods = findMatches(prod.getProductId(), currentAlarms); + List prods = findMatches(prod.getProductId(), + currentAlarms); // did we match anything? boolean alertAlarm = (prods.size() > 0); - if(alertAlarm) { + if (alertAlarm) { String pId = prods.get(0).getProductId(); - // first go get the product. All of the matching product identifiers are + // first go get the product. All of the matching product identifiers + // are // the same so just get the first. List prodList = getProduct(pId); AlarmAlertProduct productFound = null; - if(prodList.size() > 0) { + if (prodList.size() > 0) { String s = prodList.get(0).getProduct(); - for(AlarmAlertProduct p : prods) { + for (AlarmAlertProduct p : prods) { String search = p.getSearchString(); - + boolean match = false; - if((search != null) && (search.length() > 0)) { - if(s.indexOf(search) >= 0) { - match = true; + if ((search != null) && (search.length() > 0)) { + if (s.indexOf(search) >= 0) { + match = true; } } else { - match = true; + match = true; } if (match) { - if (productFound == null) - productFound = p; - if ("Alarm".equals(p.getAlarmType()) && p.isAlarm()) { - alarm = true; - productFound = p; - } - if (alarm) - break; + if (productFound == null) + productFound = p; + if ("Alarm".equals(p.getAlarmType()) && p.isAlarm()) { + alarm = true; + productFound = p; + } + if (alarm) + break; } } } - if(productFound != null) { + if (productFound != null) { prod.setAlarm(productFound.isAlarm()); prod.setAlarmType(productFound.getAlarmType()); - + instance.getCurrentAlarms().add(prod); instance.fireNewCurrentAlarmEvent(prod); - + ringBell(alarm); } } @@ -184,46 +184,51 @@ public class AlarmAlertFunctions { } /** - * Retrieve a text product from the text database based on its productId. - * @param productId AFOS ProductId to retrieve from the text database. + * Retrieve a text product from the text database based on its productId. + * + * @param productId + * AFOS ProductId to retrieve from the text database. * @return A list of text products. Will always return a not null reference. */ private static List getProduct(String productId) { List productList = null; - + ICommand command = CommandFactory.getAfosCommand(productId); try { - productList = command.executeCommand(TextEditorUtil.getTextDbsrvTransport()); + productList = command.executeCommand(TextEditorUtil + .getTextDbsrvTransport()); } catch (CommandFailedException e) { statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); } - if(productList == null) { + if (productList == null) { productList = new ArrayList(); } return productList; } - - + /** * Return a list of all alarms that match the incoming product identifier. + * * @param productId * @param currentAlarms * @return */ - private static List findMatches(String productId, List currentAlarms) { + private static List findMatches(String productId, + List currentAlarms) { List prods = new ArrayList(); - if(productId != null) { - productId = productId.toUpperCase(); + if (productId != null) { + productId = productId.trim().toUpperCase(); for (AlarmAlertProduct a : currentAlarms) { - //************** + // ************** // TODO : For now disable Proximity Alerts - //************** - if(AA.equals(a.getProductType())) { + // ************** + if (AA.equals(a.getProductType())) { String s = a.getProductId(); - if(s != null) { - s = s.toUpperCase(); - if(s.equals(productId)) { - // Reset the productId so we know we're dealing with uppercase + if (s != null) { + s = s.trim().toUpperCase(); + if (s.equals(productId)) { + // Reset the productId so we know we're dealing with + // uppercase a.setProductId(s); prods.add(a); } @@ -233,8 +238,7 @@ public class AlarmAlertFunctions { } return prods; } - - + /** * initialize the localization for user with the save/load functions * diff --git a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/util/AlarmBeepJob.java b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/util/AlarmBeepJob.java index 8c558b288a..b4d7a89ec3 100644 --- a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/util/AlarmBeepJob.java +++ b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/alarmalert/util/AlarmBeepJob.java @@ -24,7 +24,7 @@ import java.awt.Toolkit; 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.ui.progress.UIJob; /** * TODO Add Description @@ -35,6 +35,7 @@ import org.eclipse.core.runtime.jobs.Job; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Oct 19, 2009 mnash Initial creation + * Jul 25, 2012 15122 rferrel Add sound repeat interval. * * * @@ -42,17 +43,29 @@ import org.eclipse.core.runtime.jobs.Job; * @version 1.0 */ -public class AlarmBeepJob extends Job { +public class AlarmBeepJob extends UIJob { + + private static final int BEEP_COUNT = 5; + + private static final long BEEP_INTERVAL = 1000L; private boolean disposed; + private long delay; + private int count = 0; /** * @param name */ - public AlarmBeepJob(String name) { + public AlarmBeepJob(String name, long delay) { super(name); + + if (delay > (BEEP_COUNT * BEEP_INTERVAL)) { + this.delay = delay; + } else { + this.delay = (BEEP_COUNT + 1) * BEEP_INTERVAL; + } } /* @@ -62,27 +75,21 @@ public class AlarmBeepJob extends Job { * IProgressMonitor) */ @Override - protected IStatus run(IProgressMonitor monitor) { + public IStatus runInUIThread(IProgressMonitor monitor) { IStatus status = Status.OK_STATUS; - if (count < 5) { + if (count < BEEP_COUNT) { Toolkit.getDefaultToolkit().beep(); - reSchedule(); + if (!disposed) { + this.schedule(BEEP_INTERVAL); + } count++; - } else { - dispose(); + } else if (!disposed) { + schedule(delay - (BEEP_COUNT * BEEP_INTERVAL)); + count = 0; } return status; } - /** - * Schedule this job to run after the desired interval - */ - public void reSchedule() { - if (!disposed) { - this.schedule(1 * 1000); - } - } - /** * Cancel this job and release its reference to the DataManager */ diff --git a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/dialogs/AWIPSHeaderBlockDlg.java b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/dialogs/AWIPSHeaderBlockDlg.java index c709f65720..c577058570 100644 --- a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/dialogs/AWIPSHeaderBlockDlg.java +++ b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/dialogs/AWIPSHeaderBlockDlg.java @@ -90,6 +90,8 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog; * 01/26/2012 14468 D.Friedman Fix initial BBB field selection. * 05/30/2012 15046 D.Friedman Always set addressee field to ALL. * 06/19/2012 14975 D.Friedman Run callback when dialog is dismissed. + * 07/26/2012 15171 rferrel Disable editor's send and clear AFOS PIL fields when + * invalid product Id and user want to edit it anyway, * * * @author lvenable @@ -202,11 +204,11 @@ public class AWIPSHeaderBlockDlg extends CaveSWTDialog implements @Override public void widgetDisposed(DisposeEvent e) { if (parentEditor != null) - parentEditor.headerBlockDlgDismissed( - Boolean.TRUE.equals(getReturnValue())); + parentEditor.headerBlockDlgDismissed(Boolean.TRUE + .equals(getReturnValue())); } }); - + setReturnValue(false); createWmoIdFields(); @@ -274,7 +276,7 @@ public class AWIPSHeaderBlockDlg extends CaveSWTDialog implements // Create the message/indicator group combo box. gd = new GridData(70, SWT.DEFAULT); - bbbCboBx = new Combo(wmoIdComp, SWT.DROP_DOWN|SWT.READ_ONLY); + bbbCboBx = new Combo(wmoIdComp, SWT.DROP_DOWN | SWT.READ_ONLY); bbbCboBx.setItems(BBB_LIST); bbbCboBx.select(3); bbbCboBx.setLayoutData(gd); @@ -298,7 +300,7 @@ public class AWIPSHeaderBlockDlg extends CaveSWTDialog implements // Create the message/indicator version group combo box. gd = new GridData(70, SWT.DEFAULT); - bbbVerCboBx = new Combo(wmoIdComp, SWT.DROP_DOWN|SWT.READ_ONLY); + bbbVerCboBx = new Combo(wmoIdComp, SWT.DROP_DOWN | SWT.READ_ONLY); bbbVerCboBx.setItems(CHAR_LIST); bbbVerCboBx.select(0); bbbVerCboBx.setLayoutData(gd); @@ -473,7 +475,7 @@ public class AWIPSHeaderBlockDlg extends CaveSWTDialog implements .getTextLimit()) { wmoTtaaiiTF.setFocus(); } - + handleAddresseeModified(); } }); @@ -595,6 +597,7 @@ public class AWIPSHeaderBlockDlg extends CaveSWTDialog implements enterBtn.setEnabled(true); enterBtn.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { + boolean sendEnabled = true; if (!isProductValid()) { // Notify the user that the product may not be valid. // @@ -614,15 +617,25 @@ public class AWIPSHeaderBlockDlg extends CaveSWTDialog implements if (mb.open() == SWT.NO) { return; } + parentEditor.enableSend(false); + sendEnabled = false; + } else { + parentEditor.enableSend(true); } // call the set methods parentEditor.setCurrentWmoId(wmoTtaaiiTF.getText()); parentEditor.setCurrentSiteId(ccccTF.getText()); - parentEditor.setCurrentWsfoId(wsfoIdTF.getText()); - parentEditor.setCurrentProdCategory(prodCatTF.getText()); - parentEditor.setCurrentProdDesignator(prodDesignatorTF - .getText()); + if (sendEnabled) { + parentEditor.setCurrentWsfoId(wsfoIdTF.getText()); + parentEditor.setCurrentProdCategory(prodCatTF.getText()); + parentEditor.setCurrentProdDesignator(prodDesignatorTF + .getText()); + } else { + parentEditor.setCurrentWsfoId(""); + parentEditor.setCurrentProdCategory(""); + parentEditor.setCurrentProdDesignator(""); + } parentEditor.setAddressee(addresseeTF.getText()); setBbbId(); setReturnValue(true); diff --git a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/dialogs/AfosBrowserDlg.java b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/dialogs/AfosBrowserDlg.java index 6a03971590..325ab00017 100755 --- a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/dialogs/AfosBrowserDlg.java +++ b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/dialogs/AfosBrowserDlg.java @@ -535,22 +535,9 @@ public class AfosBrowserDlg extends CaveSWTDialog implements loadContinueBtn.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { - /* - * if ((nodeList.getSelectionIndex() > -1) && - * (categoryList.getSelectionIndex() > -1) && - * designatorList.getSelectionIndex() > -1) { - */ - /* - * TextDisplayModel.getInstance().setProductNode(token, - * selectedNode); - * TextDisplayModel.getInstance().setProductCategory(token, - * selectedCategory); - * TextDisplayModel.getInstance().setProductDesignator(token, - * selectedDesignator); - */ callbackClient.executeCommand(CommandFactory .getAfosCommand(currentAfosCommand)); - // } + loadContinueBtn.setFocus(); } }); @@ -563,20 +550,8 @@ public class AfosBrowserDlg extends CaveSWTDialog implements loadCloseBtn.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { - /* - * if ((nodeList.getSelectionIndex() > -1) && - * (categoryList.getSelectionIndex() > -1) && - * designatorList.getSelectionIndex() > -1) { - * TextDisplayModel.getInstance().setProductNode(token, - * selectedNode); - * TextDisplayModel.getInstance().setProductCategory(token, - * selectedCategory); - * TextDisplayModel.getInstance().setProductDesignator(token, - * selectedDesignator); - */ callbackClient.executeCommand(CommandFactory .getAfosCommand(currentAfosCommand)); - // } setReturnValue(false); shell.setVisible(false); @@ -778,7 +753,7 @@ public class AfosBrowserDlg extends CaveSWTDialog implements // Get the designator list - ensure that the entries are three // characters in length. for (String s : xxx) { - if(s.length() == 1) { + if (s.length() == 1) { s = s + " "; } else if (s.length() == 2) { s = s + " "; 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 f1c03cdf54..2579dc0a69 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 @@ -44,6 +44,7 @@ import java.util.Scanner; import java.util.TimeZone; import java.util.Timer; import java.util.TimerTask; +import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -67,8 +68,6 @@ import org.eclipse.swt.custom.VerifyKeyListener; import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.dnd.TextTransfer; import org.eclipse.swt.dnd.Transfer; -import org.eclipse.swt.events.ControlAdapter; -import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.FocusAdapter; @@ -87,6 +86,7 @@ import org.eclipse.swt.events.ShellEvent; import org.eclipse.swt.events.VerifyEvent; import org.eclipse.swt.events.VerifyListener; import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.FontMetrics; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; @@ -279,6 +279,8 @@ import com.raytheon.viz.ui.dialogs.SWTMessageBox; * 24Apr2012 14548 rferrel Merging lines for wrap places a space beween words when needed. * 27Apr2012 14902 rferrel No longer have blank line between AWIPS ID and UGC line. * 06/19/2012 14975 D.Friedman Prevent zeroed-out WMO header times. + * 18JUL2012 14457 rferrel Add mouse listener to clear site's update obs when clicked on. + * 25JUL2012 14459 rferrel Strip WMH headers when getting all METARs. * * * @author lvenable @@ -308,6 +310,10 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, private static final int END_ELEMENT_TAG_LEN = END_ELEMENT_TAG.length(); + private static final String METAR_LINE = "^(METAR |SPECI |\\s+\\S)"; + + private static final Pattern METAR_PATTERN = Pattern.compile(METAR_LINE); + private final List displayedPils = new ArrayList(); private Pattern obsRegex = null; @@ -943,13 +949,13 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, /** * flag to indicate it a product request is from the GUI or an updated ob. */ - private boolean updating = false; + private AtomicInteger updateCount = new AtomicInteger(0); private NotifyExpiration notify; private NotifyExpiration queuedNotify = null; - private String queuedAfos = null; + private String queuedProduct = null; /** * The Warngen work product id for draft PILs. @@ -1090,9 +1096,13 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, private RemoteRetrievalRequest lastRemoteRetrievalRequest; private Clipboard clipboard; - - private enum HeaderEditSession { CLOSE_ON_EXIT, IN_EDITOR } - + + private MouseListener updateObsListener = null; + + private enum HeaderEditSession { + CLOSE_ON_EXIT, IN_EDITOR + } + private HeaderEditSession headerEditSession; static { @@ -1192,7 +1202,6 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, @Override protected void initializeComponents(final Shell shell) { - shell.setSize(MIN_WIDTH, MIN_HEIGHT); Display display = getDisplay(); clipboard = new Clipboard(getDisplay()); @@ -1201,32 +1210,6 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, medFont = new Font(display, "Courier", 11, SWT.NORMAL); lrgFont = new Font(display, "Courier", 13, SWT.NORMAL); - // this.shell = shell; - shell.addControlListener(new ControlAdapter() { - public void controlResized(ControlEvent e) { - if (canRedraw == false) { - return; - } - - final Shell resizedShell = (Shell) e.getSource(); - final Point point = resizedShell.getSize(); - - if (point.x != MIN_WIDTH || point.y < (MIN_HEIGHT / 2)) { - canRedraw = false; - Display.getDefault().asyncExec(new Runnable() { - public void run() { - if (point.y < (MIN_HEIGHT / 2)) { - point.y = (MIN_HEIGHT / 2); - } - - resizedShell.setSize(MIN_WIDTH, point.y); - canRedraw = true; - } - }); - } - } - }); - if (textWorkstationFlag || isWarnGenDlg) { shell.addShellListener(new ShellAdapter() { @Override @@ -2632,8 +2615,6 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, if (rv == true) { recompileRegex(); wordWrapEnabled = true; - // textEditor.setWordWrap(true); - // sizeTextEditor(); } } @@ -2650,10 +2631,10 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, smallFontItem.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { - textEditor.setFont(smlFont); - // textEditorComp.layout(); - sizeTextEditor(); - headerTF.setFont(smlFont); + if (smallFontItem.getSelection()) { + textEditor.setFont(smlFont); + headerTF.setFont(smlFont); + } } }); @@ -2663,10 +2644,10 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, mediumFontItem.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { - textEditor.setFont(medFont); - // textEditorComp.layout(); - sizeTextEditor(); - headerTF.setFont(medFont); + if (mediumFontItem.getSelection()) { + textEditor.setFont(medFont); + headerTF.setFont(medFont); + } } }); @@ -2675,10 +2656,10 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, largeFontItem.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { - textEditor.setFont(lrgFont); - // textEditorComp.layout(); - sizeTextEditor(); - headerTF.setFont(lrgFont); + if (largeFontItem.getSelection()) { + textEditor.setFont(lrgFont); + headerTF.setFont(lrgFont); + } } }); } @@ -2816,6 +2797,10 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, @Override public void widgetSelected(SelectionEvent event) { clearTextEditor(); + if (updateObsListener != null) { + textEditor.removeMouseListener(updateObsListener); + updateObsListener = null; + } } }); } @@ -2871,7 +2856,6 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, } public void widgetDefaultSelected(SelectionEvent event) { - String tmp = afosCmdTF.getText(); tmp = tmp.trim(); afosCmdTF.setText(tmp); @@ -2959,7 +2943,6 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, } public void widgetDefaultSelected(SelectionEvent event) { - textEditor.setFocus(); wmoTtaaiiTF.setText(wmoTtaaiiTF.getText().toUpperCase()); ccccTF.setText(ccccTF.getText().toUpperCase()); wmoSearch(); @@ -3018,7 +3001,6 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, } public void widgetDefaultSelected(SelectionEvent event) { - textEditor.setFocus(); wmoTtaaiiTF.setText(wmoTtaaiiTF.getText().toUpperCase()); ccccTF.setText(ccccTF.getText().toUpperCase()); wmoSearch(); @@ -3080,22 +3062,15 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, } public void widgetDefaultSelected(SelectionEvent event) { - textEditor.setFocus(); awipsIdTF.setText(awipsIdTF.getText().trim().toUpperCase()); int charCount = awipsIdTF.getCharCount(); if (charCount < 4 || charCount > 6) { - // System.out - // .printf("Must enter a 6 or 9 character AFOS PIL%n"); - // System.out.printf("Character Count = %d%n", charCount); userInformation("Must enter a 4 to 6 character AWIPS ID"); awipsIdTF.setFocus(); return; } else { - // System.out.printf("NNN = %s%n", awipsIdTF.getText(0, 2)); TextDisplayModel.getInstance().setProductCategory(token, awipsIdTF.getText(0, 2)); - // System.out.printf("XXX = %s%n", - // awipsIdTF.getText(3, charCount - 1)); TextDisplayModel.getInstance().setProductDesignator(token, awipsIdTF.getText(3, charCount - 1)); } @@ -3151,10 +3126,33 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, * state of the check box */ private void handleUpdateObsChkBtn(boolean checked) { - // String pil = TextDisplayModel.getInstance().getAfosPil(token); - // System.out.println("Update Obs: state = " + checked + ", AFOS PIL = " - // + pil); if (checked) { + if (updateObsListener == null) { + updateObsListener = new MouseListener() { + + @Override + public void mouseUp(MouseEvent e) { + try { + int offset = textEditor + .getOffsetAtLocation(new Point(e.x, e.y)); + clearUpdateFlag(offset); + } catch (IllegalArgumentException ex) { + // bad mouse location ignore + } + } + + @Override + public void mouseDown(MouseEvent e) { + // Ignore + } + + @Override + public void mouseDoubleClick(MouseEvent e) { + // Ignore + } + }; + textEditor.addMouseListener(updateObsListener); + } NotificationManagerJob.addObserver(ALARM_ALERT_TOPIC, this); } else { NotificationManagerJob.removeObserver(ALARM_ALERT_TOPIC, this); @@ -3162,6 +3160,18 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, } + private void clearUpdateFlag(int offset) { + for (StyleRange range : textEditor.getStyleRanges()) { + if (range.start <= offset && offset < (range.start + range.length)) { + StyleRange lock = (StyleRange) range.clone(); + lock.background = null; + lock.foreground = null; + textEditor.setStyleRange(lock); + break; + } + } + } + private void clearAfosCmdTF() { if (!afosCmdTF.isDisposed()) { afosCmdTF.setText(""); @@ -3364,7 +3374,7 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, * Create the text editor (styled text) control. */ private void createTextAreaEditor() { - GridData gd = new GridData(GridData.FILL_BOTH); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); textEditorComp = new Composite(shell, SWT.NONE); GridLayout gridLayout = new GridLayout(1, false); textEditorComp.setLayout(gridLayout); @@ -3372,8 +3382,16 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, textEditor = new StyledText(textEditorComp, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL); - textEditor.setWordWrap(false); + gd = new GridData(SWT.FILL, SWT.FILL, true, true); textEditor.setFont(medFont); + GC gc = new GC(textEditor); + FontMetrics fm = gc.getFontMetrics(); + gc.dispose(); + int width = EDITOR_WIDTH * fm.getAverageCharWidth(); + gd.widthHint = width; + + textEditor.setLayoutData(gd); + textEditor.setWordWrap(false); textEditor.setEditable(false); textEditor.setKeyBinding(SWT.INSERT, SWT.NULL); // DR 7826 @@ -3436,22 +3454,8 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, // } // }); - sizeTextEditor(); - textEditor.addVerifyKeyListener(new VerifyKeyListener() { public void verifyKey(VerifyEvent event) { - - // System.out.println("event.keyCode = " + event.keyCode); - // System.out.println("event.character = <" + event.character - // + ">"); - // - // System.out.println("String.valueOf(event.character) = <" - // + String.valueOf(event.character) + ">"); - // - // System.out.println("String.valueOf(event.character).length = - // <" - // + String.valueOf(event.character).length() + ">"); - if (event.keyCode == SWT.DEL || event.character == SWT.BS || event.keyCode == SWT.SHIFT) { // Do nothing... @@ -3667,20 +3671,6 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, statusBarLabel.setLayoutData(gd); } - /** - * Size the text editor based on the text font size. - */ - private void sizeTextEditor() { - GC gc = new GC(textEditor); - FontMetrics fm = gc.getFontMetrics(); - gc.dispose(); - int width = EDITOR_WIDTH * fm.getAverageCharWidth(); - GridData data = new GridData(GridData.FILL_VERTICAL); - data.widthHint = width; - textEditor.setLayoutData(data); - textEditorComp.layout(); - } - /** * Enter the text editor mode. */ @@ -3764,12 +3754,12 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, stopAutoSave(); - if (warnGenFlag && queuedAfos != null) { + if (warnGenFlag && queuedProduct != null) { // Display the WarnGen in the queue, perform the popup and stop the // cancel. - showWarngenProduct(queuedAfos, queuedNotify); + showWarngenProduct(queuedProduct, queuedNotify); queuedNotify = null; - queuedAfos = null; + queuedProduct = null; return false; } // Set the edit mode flag @@ -3866,14 +3856,14 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, // Create and display the AWIPS header block dialog. AWIPSHeaderBlockDlg awipsHeaderBlockDlg = new AWIPSHeaderBlockDlg( shell, this); - - headerEditSession = closeEditorOnCancel ? - HeaderEditSession.CLOSE_ON_EXIT : HeaderEditSession.IN_EDITOR; + + headerEditSession = closeEditorOnCancel ? HeaderEditSession.CLOSE_ON_EXIT + : HeaderEditSession.IN_EDITOR; awipsHeaderBlockDlg.open(); // headerBlockDlgDismissed() is called when the dialog is dismissed. } - + /** * Called by AWIPSHeaderBlockDlg when it is dismissed. * @@ -3884,23 +3874,24 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, public void headerBlockDlgDismissed(boolean dialogResult) { HeaderEditSession lastSession = headerEditSession; headerEditSession = null; - + // If the user cancels the AWIPS header block dialog then // get out of edit mode. // Otherwise use the node, product category, and product designator. - + boolean editing = false; - + if (dialogResult == true) { TextDisplayModel tdm = TextDisplayModel.getInstance(); - + // Update the buttonology. updateButtonology(tdm.getAfosPil(token)); String bbbid = tdm.getBbbId(token); - + String nnnxxx = workProductId != null ? workProductId : tdm - .getProductCategory(token) + tdm.getProductDesignator(token); + .getProductCategory(token) + + tdm.getProductDesignator(token); // Set the header text field. if (bbbid.equals("NOR")) { String wmoId = tdm.getWmoId(token); @@ -3912,25 +3903,26 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, setHeaderTextField(tdm.getWmoId(token), tdm.getSiteId(token), currentDateId + " " + bbbid, "\n", nnnxxx); } - + // Update the "now editing" title of the text editor window. updateNowEditingTitle(); - + editing = true; } else { if (lastSession == HeaderEditSession.CLOSE_ON_EXIT) - editing = !cancelEditor(false); + editing = !cancelEditor(false); } - + if (lastSession == HeaderEditSession.CLOSE_ON_EXIT) if (editing) { StdTextProduct product = TextDisplayModel.getInstance() - .getStdTextProduct(token); + .getStdTextProduct(token); if (product == null) return; if (autoSave == null) { // user can cancel the edit immediately when the header is - // displayed, verify it was not cancelled before starting the + // displayed, verify it was not cancelled before starting + // the // autoSave task. autoSave = new AutoSaveTask(product.getWmoid(), product.getSite()); @@ -4080,7 +4072,8 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, * Print all text from the text editor to the default printer. */ private void printAllText() { - PrintDisplay.print(true, textEditor.getText(), statusHandler); + FontData fontData = textEditor.getFont().getFontData()[0]; + PrintDisplay.print(textEditor.getText(), fontData, statusHandler); } /** @@ -4102,7 +4095,8 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, if (mb.open() == SWT.YES) { String tmpText = textEditor.getText(); Point point = textEditor.getSelection(); - PrintDisplay.print(true, textEditor.getSelectionText(), + FontData fontData = textEditor.getFont().getFontData()[0]; + PrintDisplay.print(textEditor.getSelectionText(), fontData, statusHandler); textEditor.setText(tmpText); textEditor.setSelection(point); @@ -4642,15 +4636,18 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, } if (!isAutoSave) { - if (! resend) { + if (!resend) { // If not a resend, set the DDHHMM field to the current time productText = replaceDDHHMM(productText, currentDate); - + VtecObject vtecObj = VtecUtil.parseMessage(productText); if (warnGenFlag) { - // TODO: Pass in some flavor of currentDate to use to set the - // times. Currently roll over to the next minute between getting - // currentDate and getting the times in this method will cause + // TODO: Pass in some flavor of currentDate to use to set + // the + // times. Currently roll over to the next minute between + // getting + // currentDate and getting the times in this method will + // cause // them to be different. productText = updateVtecTimes(productText, vtecObj); // Update editor so the proper send times are displayed. @@ -4726,10 +4723,14 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, return successful; } - - /** Replaces the WMO heading DDHHMM field with the given text. - * @param productText Product text which includes the WMO heading - * @param ddhhmm Replacement text + + /** + * Replaces the WMO heading DDHHMM field with the given text. + * + * @param productText + * Product text which includes the WMO heading + * @param ddhhmm + * Replacement text * @return The modified product text */ private static String replaceDDHHMM(String productText, String ddhhmm) { @@ -4748,8 +4749,10 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, sb.append(' '); sb.append(s); } - if (parts.length > 1) - sb.append('\n').append(parts[1]); + if (parts.length > 1) { + sb.append('\n').append(parts[1]); + } + productText = sb.toString(); } @@ -4890,14 +4893,11 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, // Capture the input from the styled text widget. StringBuffer sb = new StringBuffer(st.getText()); String errMsg = null; - // System.out.println("Initial: " + sb); - // int counter = 0; int currentIndex = 0; int startIndex = 0; int endIndex = 0; try { while (sb.indexOf(BEGIN_ELEMENT_TAG, 0) >= 0) { - // System.out.println("Trial " + counter++ + ": " + sb); currentIndex = 0; startIndex = 0; endIndex = 0; @@ -4957,7 +4957,6 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, */ @Override public void verifyText(VerifyEvent event) { - // System.out.println("verify text event.start="+event.star0t); int length = event.end - event.start; try { if (length == 0) { @@ -5204,6 +5203,7 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, statusBarLabel.update(); boolean hasAttachment = false; String attachedFilename = new String(); + boolean validExecuteCommand = true; try { if (queryTransport == null) { @@ -5238,7 +5238,17 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, hasAttachment = true; } - if (updating) { + String commandText = command.getCommandTextFields()[0]; + StdTextProductId stdProdId = prod.getProdId(); + + if ("MTR".equals(stdProdId.getNnnid()) + && (commandText.startsWith("ALL:") + || commandText.startsWith("A:") || commandText + .endsWith("000"))) { + stripWMOHeaders(prod); + } + + if (updateCount.get() > 0) { updateDisplayedProduct(prod); } else { setDisplayedProduct(prod); @@ -5294,10 +5304,12 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, if (!accumChkBtn.getSelection()) { textEditor.setText(""); } + validExecuteCommand = false; } } catch (CommandFailedException e) { statusHandler.handle(Priority.PROBLEM, "Error retrieving metatdata", e); + validExecuteCommand = false; } if (!this.isDisposed()) { @@ -5313,104 +5325,104 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, } else { resendWarningProductnItem.setEnabled(true); } + + // Always give focus to textEditor after populating it. + if (validExecuteCommand) { + textEditor.setFocus(); + } } } - public void showWarngenProduct(String afosId, NotifyExpiration notify) { + private void stripWMOHeaders(StdTextProduct prod) { + String[] lines = prod.getProduct().split("\n"); + StringBuilder sb = new StringBuilder(); + for (String line : lines) { + Matcher m = METAR_PATTERN.matcher(line); + if (m.find()) { + sb.append(line).append("\n"); + } + } + prod.setProduct(sb.toString()); + } + + public void showWarngenProduct(String product, NotifyExpiration notify) { inEditMode = true; this.notify = notify; - StdTextProduct tmp = null; - final SimpleDateFormat sdf = new SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss.SSS"); - sdf.setTimeZone(TimeZone.getTimeZone("GMT")); - long t0 = System.currentTimeMillis(); - try { - if (queryTransport == null) { - queryTransport = TextEditorUtil.getTextDbsrvTransport(); - } - long t2 = System.currentTimeMillis(); - System.out - .println("Time getting TextDbSrv transport: " + (t2 - t0)); - ICommand cmd = CommandFactory.getAfosCommand(afosId); - long t3 = System.currentTimeMillis(); - System.out.println("Time getting afos command: " + (t3 - t2)); - tmp = cmd.executeCommand(queryTransport).get(0); - long t4 = System.currentTimeMillis(); - System.out.println("Time executing afos cmd: " + (t4 - t3)); - } catch (CommandFailedException e) { - e.printStackTrace(); - } - long t1 = System.currentTimeMillis(); - System.out - .println(sdf.format(new Date()) - + ": Text Workstation retrieving work product from database in " - + (t1 - t0) + "ms."); + String[] tokens = product.split(":", 2); - String warning = tmp.getProduct(); - String[] nnnxxx = TextDisplayModel.getNnnXxx(warning); - String siteNode = SiteAbbreviationUtil.getSiteNode(nnnxxx[1]); - String ttaaii = SiteAbbreviationUtil.getTtaaii(siteNode + nnnxxx[0] - + nnnxxx[1]); - final String w = warning.replace(TextWarningConstants.TTAAII, ttaaii); + if (tokens.length == 2) { + String afosId = tokens[0]; + String warning = tokens[1]; - TextDisplayModel.getInstance().createStdTextProduct(token, w, siteNode); + String[] nnnxxx = TextDisplayModel.getNnnXxx(warning); + String siteNode = SiteAbbreviationUtil.getSiteNode(nnnxxx[1]); + String ttaaii = SiteAbbreviationUtil.getTtaaii(siteNode + nnnxxx[0] + + nnnxxx[1]); + final String w = warning.replace(TextWarningConstants.TTAAII, + ttaaii); - workProductId = afosId.substring(3); - warnGenFlag = true; - VizApp.runAsync(new Runnable() { - @Override - public void run() { - long t0 = System.currentTimeMillis(); - // For VTEC related warning messages, turn off wordwrap by - // default. - if (textEditor == null) { - openDialog(); - } + TextDisplayModel.getInstance().createStdTextProduct(token, w, + siteNode); - if (textEditor.isDisposed()) { - return; - } + workProductId = afosId.substring(3); + warnGenFlag = true; + VizApp.runAsync(new Runnable() { + @Override + public void run() { + long t0 = System.currentTimeMillis(); + // For VTEC related warning messages, turn off wordwrap by + // default. + if (textEditor == null) { + openDialog(); + } - // textEditor.setWordWrap(false); + if (textEditor.isDisposed()) { + return; + } - // Set the text editor's contents to the warning message. - textEditor.removeVerifyListener(TextEditorDialog.this); - textEditor.setText(w); - // - // // Mark the uneditable warning text - // if (markUneditableText(textEditor)) { - // // Add listener to monitor attempt to edit locked text - // textEditor.addVerifyListener(TextEditorDialog.this); - // } - showDialog(); - long t1 = System.currentTimeMillis(); + // textEditor.setWordWrap(false); - System.out.println(sdf.format(new Date()) - + ": Text Workstation took " + (t1 - t0) - + "ms to show dialog"); - enterEditor(); + // Set the text editor's contents to the warning message. + textEditor.removeVerifyListener(TextEditorDialog.this); + textEditor.setText(w); + // + // // Mark the uneditable warning text + // if (markUneditableText(textEditor)) { + // // Add listener to monitor attempt to edit locked text + // textEditor.addVerifyListener(TextEditorDialog.this); + // } + showDialog(); + long t1 = System.currentTimeMillis(); + SimpleDateFormat sdf = new SimpleDateFormat( + "yyyy-MM-dd HH:mm:ss.SSS"); + sdf.setTimeZone(TimeZone.getTimeZone("GMT")); + System.out.println(sdf.format(new Date()) + + ": Text Workstation took " + (t1 - t0) + + "ms to show dialog"); + enterEditor(); - if (autoWrapMenuItem != null) { - Menu menu = autoWrapMenuItem.getMenu(); - for (MenuItem item : menu.getItems()) { - if (item.getSelection()) { - Object obj = item.getData(); - if (obj instanceof WrapButtonCfg) { - WrapButtonCfg buttonCfg = (WrapButtonCfg) obj; - if (buttonCfg.isWrapEnabled()) { - charWrapCol = buttonCfg.getWrapCol(); - wordWrapEnabled = true; - recompileRegex(); - } else { - wordWrapEnabled = false; + if (autoWrapMenuItem != null) { + Menu menu = autoWrapMenuItem.getMenu(); + for (MenuItem item : menu.getItems()) { + if (item.getSelection()) { + Object obj = item.getData(); + if (obj instanceof WrapButtonCfg) { + WrapButtonCfg buttonCfg = (WrapButtonCfg) obj; + if (buttonCfg.isWrapEnabled()) { + charWrapCol = buttonCfg.getWrapCol(); + wordWrapEnabled = true; + recompileRegex(); + } else { + wordWrapEnabled = false; + } } } } } + saved = false; } - saved = false; - } - }); + }); + } } private void replaceWorkProductId() { @@ -5575,7 +5587,6 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, } // open the script output window scriptOutput.open(); - System.out.println("output window closed..."); // update the menu following close if (scriptsShowOutputItem != null && !scriptsShowOutputItem.isDisposed()) { @@ -5780,7 +5791,6 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, @Override public void windowClosing() { - System.out.println("script editor window closing"); if (scriptRunner == null) { setScriptMenuControls(true); } @@ -5883,17 +5893,27 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, regex = "(METAR |SPECI )K" + product.getXxxid(); } + boolean haveWMOHeader = false; + if (regex != null) { // Find METAR to replace. // This assumes the product's METAR is the latest METAR and not a - // duplicate or older then the display. If not the case a check of + // duplicate or older in the display. If not the case a check of // the timestamp can be performed adjusting for possible roll over // to the next month. Pattern pattern = Pattern.compile(regex); for (int i = 0; i < noOfLines; ++i) { if (pattern.matcher(textEditor.getLine(i)).find()) { - // Adjust to the METAR's Wmo Header line. - lineIndex = i - 1; + lineIndex = i; + if (i > 0) { + Matcher m = METAR_PATTERN.matcher(textEditor + .getLine(i - 1)); + if (!m.find()) { + // Adjust to the METAR's Wmo Header line. + --lineIndex; + haveWMOHeader = true; + } + } break; } } @@ -5904,11 +5924,9 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, } } else { String prefix = product.getWmoid() + " " + product.getSite(); - // System.out.println("new header" + prefix); for (int i = 0; i < noOfLines; i++) { if (textEditor.getLine(i).startsWith(prefix)) { // found replacement point - // System.out.println("found " + prefix + " at line " + i); lineIndex = i; break; } @@ -5917,46 +5935,61 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, if (lineIndex == -1) { lineIndex = noOfLines; } - // note: this returns the number of lines in the text display area - // Since lines are zero indexed, this points to the second line - // of the product. Assuming a WMO header, this is the first line - // of the product - // System.out.println("inserting text at: " + lineIndex); + + String productText = product.getProduct(); + if (lineIndex == noOfLines) { textEditor.append("\n"); - textEditor.append(product.getProduct()); + textEditor.append(productText); } else { // need to find end of current product, then replace. int nextProductLoc = -1; - for (int i = lineIndex + 2; i < noOfLines; i++) { - String temp = textEditor.getLine(i); - if (!temp.startsWith(" ")) { + if (haveWMOHeader) { + // Assume next product also has WMO header + for (int i = lineIndex + 2; i < noOfLines; i++) { + String temp = textEditor.getLine(i); + if (!temp.startsWith(" ")) { + if (temp.startsWith("METAR") + || temp.startsWith("SPECI")) { + continue; + } else { + // found next product + nextProductLoc = i; + break; + } + } + } + } else { + // Remove WMO header + productText = productText + .substring(productText.indexOf('\n') + 1); + // Assume next product does not have a WMO header + for (int i = lineIndex + 1; i < noOfLines; ++i) { + String temp = textEditor.getLine(i); if (temp.startsWith("METAR") || temp.startsWith("SPECI")) { - continue; - } else { - // found next product nextProductLoc = i; break; } } } + int start = textEditor.getOffsetAtLine(lineIndex); int end = textEditor.getCharCount(); if (nextProductLoc != -1) { end = textEditor.getOffsetAtLine(nextProductLoc); - textEditor.replaceTextRange(start, end - start, - product.getProduct() + "\n"); + textEditor.replaceTextRange(start, end - start, productText + + "\n"); } else { - textEditor.replaceTextRange(start, end - start, - product.getProduct()); + textEditor.replaceTextRange(start, end - start, productText); } } // if updating, we need to highlight the site name. If the first word of // the line is "METAR" or "SPECI", we need to highlight the second word - lineIndex++; // need to skip the WMO header + if (haveWMOHeader) { + lineIndex++; // need to skip the WMO header + } String line = textEditor.getLine(lineIndex); - // System.out.println(line); int startIndex = textEditor.getOffsetAtLine(lineIndex); if (line.startsWith("METAR") || line.startsWith("SPECI")) { startIndex += 6; // skip first word plus a space @@ -5971,7 +6004,7 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, // retrieved for display in this text editor dialog // instance. TextDisplayModel.getInstance().setStdTextProduct(token, product); - updating = false; + updateCount.addAndGet(-1); } @Override @@ -6281,7 +6314,7 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, msgPIL = ""; } if (isObsDisplayed(msgPIL)) { - updating = true; + updateCount.addAndGet(1); ICommand command = CommandFactory.getAfosCommand(msgPIL); UpdateObsRun run = new UpdateObsRun(command); VizApp.runSync(run); @@ -7183,9 +7216,13 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener, } } + public void enableSend(boolean state) { + editorSendBtn.setEnabled(state); + } + public void enqueue(String afosId, NotifyExpiration notify2) { queuedNotify = notify2; - queuedAfos = afosId; + queuedProduct = afosId; } private boolean gfeForbidden(String ccc, String nnn) { diff --git a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/print/PrintDisplay.java b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/print/PrintDisplay.java index 6825f617cc..bb83845693 100644 --- a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/print/PrintDisplay.java +++ b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/print/PrintDisplay.java @@ -19,13 +19,15 @@ **/ package com.raytheon.viz.texteditor.print; -import java.awt.Color; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.print.PageFormat; -import java.awt.print.Printable; -import java.awt.print.PrinterException; -import java.awt.print.PrinterJob; +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; +import org.eclipse.swt.printing.Printer; +import org.eclipse.swt.printing.PrinterData; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus.Priority; @@ -39,6 +41,8 @@ import com.raytheon.uf.common.status.UFStatus.Priority; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Sep 15, 2011 10557 rferrel Initial creation + * Jul 17, 2012 14274 rferrel Now use eclipse Printer instead of awt. + * Text is printed using same font as the GUI * * * @@ -47,107 +51,182 @@ import com.raytheon.uf.common.status.UFStatus.Priority; */ public class PrintDisplay { - /** - * Print the text/document to the default print. - * - * @param autoPrint - * true send text directly to printer without prompting user for - * selecting a different printer. - * @param printedText - * the text to print. - */ - public static void print(boolean autoPrint, String printedText, + public static void print(final String printedText, final FontData fontData, IUFStatusHandler statusHandler) { - if (printedText == null || printedText.trim().length() == 0) { - // Do not waste paper on blank text. + PrinterData data = Printer.getDefaultPrinterData(); + if (data == null) { + statusHandler.handle(Priority.PROBLEM, + "No default printer specified."); return; } - PrintDisplay printer = new PrintDisplay(autoPrint, statusHandler); - printer.printIt(printedText); + if (printedText == null || printedText.trim().length() == 0) { + // Do not waste paper when nothing to print. + return; + } + + final Printer printer = new Printer(data); + PrintDisplay pd = new PrintDisplay(printer, printedText, fontData); + pd.printJob(); } - private boolean autoPrint; + private Printer printer; - private IUFStatusHandler statusHandler; + private String textToPrint; - private PrintDisplay(boolean autoPrint, IUFStatusHandler statusHandler) { - this.autoPrint = autoPrint; - this.statusHandler = statusHandler; + private FontData printerFontData; + + private int leftMargin; + + private int rightMargin; + + private int topMargin; + + private int bottomMargin; + + private String tabs; + + private GC gc; + + private int tabWidth; + + private int lineHeight; + + StringBuilder wordBuffer; + + int x; + + int y; + + int index; + + int end; + + private PrintDisplay(Printer printer, String text, FontData fontData) { + this.printer = printer; + this.textToPrint = text; + this.printerFontData = fontData; } - private void printIt(String printedText) { - PrinterJob printerJob = PrinterJob.getPrinterJob(); - - if (autoPrint || printerJob.printDialog()) { - printerJob.setPrintable(new Document(printedText)); - try { - printerJob.print(); - } catch (PrinterException e) { - statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), - e); + private void printJob() { + Thread thread = new Thread("Printing") { + public void run() { + printIt(); + printer.dispose(); } + }; + thread.start(); + } + + private void printIt() { + if (printer.startJob("Text")) { // the string is the job name - shows up + // in the printer's job list + Rectangle clientArea = printer.getClientArea(); + Rectangle trim = printer.computeTrim(0, 0, 0, 0); + Point dpi = printer.getDPI(); + + // one inch from left side of paper + leftMargin = dpi.x + trim.x; + // one inch from right side of paper + rightMargin = clientArea.width - dpi.x + trim.x + trim.width; + topMargin = dpi.y + trim.y; // one inch from top edge of paper + // one inch from bottom edge of paper + bottomMargin = clientArea.height - dpi.y + trim.y + trim.height; + + // Create a buffer for computing tab width. + int tabSize = 4; + StringBuilder tabBuffer = new StringBuilder(tabSize); + for (int i = 0; i < tabSize; i++) + tabBuffer.append(' '); + tabs = tabBuffer.toString(); + + /* + * Create printer GC, and create and set the printer font & + * foreground color. + */ + gc = new GC(printer); + Font printerFont = new Font(printer, printerFontData); + Color printerForegroundColor = new Color(printer, new RGB(0, 0, 0)); + Color printerBackgroundColor = new Color(printer, new RGB(255, 255, + 255)); + + gc.setFont(printerFont); + gc.setForeground(printerForegroundColor); + gc.setBackground(printerBackgroundColor); + tabWidth = gc.stringExtent(tabs).x; + lineHeight = gc.getFontMetrics().getHeight(); + + // Print text to current gc using word wrap + printText(); + printer.endJob(); + + // Cleanup graphics resources used in printing + printerFont.dispose(); + printerForegroundColor.dispose(); + printerBackgroundColor.dispose(); + gc.dispose(); } } - private class Document implements Printable { - - private final String[] printedText; - - private int numPages = 0; - - public Document(String printedText) { - super(); - this.printedText = printedText.split("\n"); + private void printText() { + printer.startPage(); + wordBuffer = new StringBuilder(); + x = leftMargin; + y = topMargin; + index = 0; + end = textToPrint.length(); + while (index < end) { + char c = textToPrint.charAt(index); + index++; + if (c != 0) { + if (c == 0x0a || c == 0x0d) { + if (c == 0x0d && index < end + && textToPrint.charAt(index) == 0x0a) { + index++; // if this is cr-lf, skip the lf + } + printWordBuffer(); + newline(); + } else { + if (c != '\t') { + wordBuffer.append(c); + } + if (Character.isWhitespace(c)) { + printWordBuffer(); + if (c == '\t') { + x += tabWidth; + } + } + } + } } + if (y + lineHeight <= bottomMargin) { + printer.endPage(); + } + } - @Override - public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) - throws PrinterException { - // --- Create the Graphics2D object - Graphics2D g2d = (Graphics2D) graphics; - - // --- Set the drawing color to black - g2d.setPaint(Color.black); - java.awt.Font font = g2d.getFont(); - String name = font.getName(); - int style = font.getStyle(); - int size = font.getSize(); - - g2d.setFont(new java.awt.Font(name, style, size - 2)); - - // --- Translate the origin to 0,0 for the top left corner - g2d.translate(pageFormat.getImageableX(), - pageFormat.getImageableY()); - - // Determine the lines per page and number of pages to print. - java.awt.FontMetrics metrics = g2d.getFontMetrics(); - int lineHeight = metrics.getHeight(); - int linesPerPage = (int) Math.floor(pageFormat.getImageableHeight() - / lineHeight); - numPages = ((printedText.length - 1) / linesPerPage) + 1; - - // Calculate the start line for this page. - int startLine = pageIndex * linesPerPage; - int endLine = startLine + linesPerPage - 1; - if (endLine >= printedText.length) { - endLine = printedText.length - 1; + private void printWordBuffer() { + if (wordBuffer.length() > 0) { + String word = wordBuffer.toString(); + int wordWidth = gc.stringExtent(word).x; + if (x + wordWidth > rightMargin) { + // word doesn't fit on current line, so wrap + newline(); } + gc.drawString(word, x, y, false); + x += wordWidth; + wordBuffer.setLength(0); + } + } - // Tell the PrinterJob if the page number is not a legal one. - if (pageIndex >= numPages) { - return NO_SUCH_PAGE; + private void newline() { + x = leftMargin; + y += lineHeight; + if (y + lineHeight > bottomMargin) { + printer.endPage(); + if (index + 1 < end) { + y = topMargin; + printer.startPage(); } - - int y = 0; - for (int i = startLine; i <= endLine; i++) { - y += lineHeight; - g2d.drawString(printedText[i], 0, y); - } - - g2d.dispose(); - // --- Validate the page - return (PAGE_EXISTS); } } } \ No newline at end of file diff --git a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/util/SiteAbbreviationUtil.java b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/util/SiteAbbreviationUtil.java index f131873652..f6d37b613b 100644 --- a/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/util/SiteAbbreviationUtil.java +++ b/cave/com.raytheon.viz.texteditor/src/com/raytheon/viz/texteditor/util/SiteAbbreviationUtil.java @@ -25,6 +25,7 @@ import com.raytheon.uf.common.site.SiteMap; import com.raytheon.uf.viz.core.catalog.DirectDbQuery; import com.raytheon.uf.viz.core.catalog.DirectDbQuery.QueryLanguage; import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.localization.LocalizationManager; import com.raytheon.viz.texteditor.TextWarningConstants; /** @@ -45,6 +46,22 @@ import com.raytheon.viz.texteditor.TextWarningConstants; public class SiteAbbreviationUtil { + private static String mySiteNode; + + /** + * Returns the 3 letter site node for the current localization. + * + * @return + */ + public static String getMySiteNode() { + if (mySiteNode == null) { + mySiteNode = getSiteNode(LocalizationManager.getInstance() + .getCurrentSite()); + } + + return mySiteNode; + } + /** * Grabs the site node from the FXA database afoslookup table. * diff --git a/cave/com.raytheon.viz.textworkstation/src/com/raytheon/viz/textworkstation/TextWorkstationDlg.java b/cave/com.raytheon.viz.textworkstation/src/com/raytheon/viz/textworkstation/TextWorkstationDlg.java index b72e6e73b4..d6a77e7f38 100755 --- a/cave/com.raytheon.viz.textworkstation/src/com/raytheon/viz/textworkstation/TextWorkstationDlg.java +++ b/cave/com.raytheon.viz.textworkstation/src/com/raytheon/viz/textworkstation/TextWorkstationDlg.java @@ -22,6 +22,7 @@ package com.raytheon.viz.textworkstation; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Calendar; import java.util.Date; import java.util.TimeZone; import java.util.Timer; @@ -110,9 +111,9 @@ public class TextWorkstationDlg extends CaveSWTDialog implements private Label utcTimeLabel; - private Label gmtTimeLabel; + private Label localTimeLabel; - SimpleDateFormat sdfGMT = new SimpleDateFormat("EEE dd MMM yyyy HH:mm z"); + SimpleDateFormat sdfLocal = new SimpleDateFormat("EEE dd MMM yyyy HH:mm z"); SimpleDateFormat sdfUTC = new SimpleDateFormat("EEE dd MMM yyyy HH:mm z"); @@ -197,8 +198,8 @@ public class TextWorkstationDlg extends CaveSWTDialog implements } private void initializeComponents() { - sdfGMT.setTimeZone(TimeZone.getTimeZone("GMT")); sdfUTC.setTimeZone(TimeZone.getTimeZone("UTC")); + sdfLocal.setTimeZone(Calendar.getInstance().getTimeZone()); createMenus(); new Label(shell, SWT.NONE).setText("host: " @@ -365,16 +366,18 @@ public class TextWorkstationDlg extends CaveSWTDialog implements } private void createTimeLabels() { - GridData gd = new GridData(300, SWT.DEFAULT); - gmtTimeLabel = new Label(shell, SWT.CENTER); - gmtTimeLabel.setLayoutData(gd); + GridData gd = null; gd = new GridData(300, SWT.DEFAULT); utcTimeLabel = new Label(shell, SWT.CENTER); utcTimeLabel.setLayoutData(gd); + gd = new GridData(300, SWT.DEFAULT); + localTimeLabel = new Label(shell, SWT.CENTER); + localTimeLabel.setLayoutData(gd); + date = SimulatedTime.getSystemTime().getTime(); - gmtTimeLabel.setText(sdfGMT.format(date)); + localTimeLabel.setText(sdfLocal.format(date)); utcTimeLabel.setText(sdfUTC.format(date)); } @@ -510,7 +513,7 @@ public class TextWorkstationDlg extends CaveSWTDialog implements private void updateTimeLabels() { date = SimulatedTime.getSystemTime().getTime(); - gmtTimeLabel.setText(sdfGMT.format(date)); + localTimeLabel.setText(sdfLocal.format(date)); utcTimeLabel.setText(sdfUTC.format(date)); } @@ -596,14 +599,14 @@ public class TextWorkstationDlg extends CaveSWTDialog implements // messages. delta += TextWorkstationDlg.incDelta; } else if (message.isNotExpired()) { - String afosId = message.getMessagePayload().toString(); + String product = message.getMessagePayload().toString(); if (wgDlg == null) { - productToDisplay = afosId; + productToDisplay = product; } else { if (!wgDlg.isEditMode()) { - wgDlg.showWarngenProduct(afosId, notify); + wgDlg.showWarngenProduct(product, notify); } else { - wgDlg.enqueue(afosId, notify); + wgDlg.enqueue(product, notify); } } } diff --git a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/VizWorkbenchManager.java b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/VizWorkbenchManager.java index eeaf803329..726fa51bbe 100644 --- a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/VizWorkbenchManager.java +++ b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/VizWorkbenchManager.java @@ -392,6 +392,9 @@ public class VizWorkbenchManager implements IPartListener, IPartListener2, } activeEditorMap .put(part.getSite().getWorkbenchWindow(), active); + if (active instanceof IDisplayPaneContainer) { + notifyListeners(); + } } } } diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/comm/WarningSender.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/comm/WarningSender.java index b985c4cdc7..0eeb06932a 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/comm/WarningSender.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/comm/WarningSender.java @@ -33,12 +33,12 @@ import javax.jms.MessageProducer; import javax.jms.Session; import com.raytheon.uf.common.dataplugin.text.request.InsertStdTextProductRequest; -import com.raytheon.uf.common.serialization.DynamicSerializationManager; -import com.raytheon.uf.common.serialization.DynamicSerializationManager.SerializationType; +import com.raytheon.uf.common.serialization.SerializationUtil; 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.comm.JMSConnection; +import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.localization.LocalizationManager; import com.raytheon.uf.viz.core.requests.ThriftClient; import com.raytheon.viz.core.mode.CAVEMode; @@ -65,173 +65,209 @@ import com.raytheon.viz.texteditor.util.SiteAbbreviationUtil; */ public class WarningSender implements IWarngenObserver { - private static final transient IUFStatusHandler statusHandler = UFStatus - .getHandler(WarningSender.class); + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(WarningSender.class); - private String hostName = null; + private String hostName = null; - private boolean notifyError; + private boolean notifyError; - private static final long MILLISECONDS_PER_SECOND = 1000; + private static final long MILLISECONDS_PER_SECOND = 1000; - private static final long SECONDS_PER_MINUTE = 60; + private static final long SECONDS_PER_MINUTE = 60; - private static final long TTL_MINUTES = 5; + private static final long TTL_MINUTES = 5; - private static Pattern PATTERN = Pattern.compile("(\\d{1,1})"); + private static Pattern PATTERN = Pattern.compile("(\\d{1,1})"); - private static final SimpleDateFormat sdf; + private static final SimpleDateFormat sdf; - static { - sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); - sdf.setTimeZone(TimeZone.getTimeZone("GMT")); - } + static { + sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + sdf.setTimeZone(TimeZone.getTimeZone("GMT")); + } - /* - * (non-Javadoc) Incoming message was not a binary - * - * @see - * com.raytheon.viz.texteditor.msgs.IWarngenObserver#setTextWarngenDisplay - * (java.lang.String) - */ - @Override - public void setTextWarngenDisplay(String warning, boolean ne) { - this.notifyError = ne; + /* + * (non-Javadoc) Incoming message was not a binary + * + * @see + * com.raytheon.viz.texteditor.msgs.IWarngenObserver#setTextWarngenDisplay + * (java.lang.String) + */ + @Override + public void setTextWarngenDisplay(String warning, boolean ne) { + this.notifyError = ne; - String number = "0"; - String host = TextWorkstationConstants.getId(); - long t0 = System.currentTimeMillis(); - String siteNode = SiteAbbreviationUtil.getSiteNode(LocalizationManager - .getInstance().getCurrentSite()); - System.out.println("Get site node time: " - + (System.currentTimeMillis() - t0)); - if (host == null) { - statusHandler.handle(Priority.ERROR, - "Text Workstation host not set in preferences."); - } else { - Matcher m = PATTERN.matcher(host); - if (m.find()) { - number = m.group(); - } - } + String number = "0"; + String host = TextWorkstationConstants.getId(); + long t0 = System.currentTimeMillis(); + String siteNode = SiteAbbreviationUtil.getSiteNode(LocalizationManager + .getInstance().getCurrentSite()); + System.out.println("Get site node time: " + + (System.currentTimeMillis() - t0)); + if (host == null) { + statusHandler.handle(Priority.ERROR, + "Text Workstation host not set in preferences."); + } else { + Matcher m = PATTERN.matcher(host); + if (m.find()) { + number = m.group(); + } + } - String id = siteNode + "WRKWG" + number; + String id = siteNode + "WRKWG" + number; + boolean sentToTextDatabase = false; - try { - CAVEMode mode = CAVEMode.getMode(); - boolean operationalMode = (CAVEMode.OPERATIONAL.equals(mode) - || CAVEMode.TEST.equals(mode) ? true : false); + try { + boolean messageNotSent = true; + int connectCount = 0; + t0 = System.currentTimeMillis(); + byte[] data = SerializationUtil.transformToThrift(id + ":" + + warning); + while (messageNotSent && connectCount < 4) { + Session s = null; + MessageProducer mp = null; + Connection conn = null; + try { + conn = JMSConnection.getInstance().getFactory() + .createConnection(); + s = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE); + mp = s.createProducer(s + .createQueue(TextWorkstationConstants + .getDestinationTextWorkstationQueueName())); + mp.setTimeToLive(TTL_MINUTES * SECONDS_PER_MINUTE + * MILLISECONDS_PER_SECOND); + BytesMessage m = s.createBytesMessage(); + m.writeBytes(data); + mp.send(m); + long t1 = System.currentTimeMillis(); + System.out.println(WarningSender.getCurTimeString() + ": " + + id + " sent to text workstation in " + (t1 - t0) + + "ms in " + (connectCount + 1) + + (connectCount > 0 ? " tries" : " try")); + messageNotSent = false; + } catch (JMSException e) { + if (notifyError) { + statusHandler + .handle(Priority.PROBLEM, + "Error trying to send product [" + + id + + "] to Text Workstation. Attempting to reconnect. ", + e); + notifyError = false; + } + } finally { + if (mp != null) { + try { + mp.close(); + mp = null; + } catch (Exception e) { + mp = null; + } + } + if (s != null) { + try { + s.close(); + s = null; + } catch (Exception e) { + s = null; + } + } + if (conn != null) { + try { + conn.close(); + conn = null; + } catch (Exception e) { + conn = null; + } + } + } + if (messageNotSent) { + if (!sentToTextDatabase) { + try { + sendToTextDatabase(id, warning); + sentToTextDatabase = true; + } catch (Exception e) { + statusHandler.handle(Priority.PROBLEM, + "Error trying to save product [" + id + + "] to Text Database: ", e); + } + } - // Generate StdTextProduct and insert into db - t0 = System.currentTimeMillis(); - ThriftClient.sendRequest(new InsertStdTextProductRequest(id, - warning, operationalMode)); + connectCount++; + switch (connectCount) { + case 1: + Thread.sleep(1000); + break; + case 2: + Thread.sleep(5 * 1000); + break; + case 3: + Thread.sleep(30 * 1000); + break; + case 4: + statusHandler.handle(Priority.PROBLEM, + "Could not reconnect (" + id + + ") after 3 tries: ", null); + break; + } + } + } - System.out.println(WarningSender.getCurTimeString() + ": " + id - + " saved to textdb in " - + (System.currentTimeMillis() - t0) + "ms"); + if (!sentToTextDatabase) { + try { + sendToTextDatabase(id, warning); + sentToTextDatabase = true; + } catch (Exception e) { + statusHandler.handle(Priority.PROBLEM, + "Error trying to save product [" + id + + "] to Text Database: ", e); + } + } + } catch (UnknownHostException uhe) { + if (notifyError) { + statusHandler.handle(Priority.PROBLEM, + "unable to map hostname, " + hostName + + ", to an ip address", uhe); + notifyError = false; + } - boolean messageNotSent = true; - int connectCount = 0; - t0 = System.currentTimeMillis(); - while (messageNotSent && connectCount < 4) { - Session s = null; - MessageProducer mp = null; - Connection conn = null; - try { - conn = JMSConnection.getInstance().getFactory() - .createConnection(); - s = conn.createSession(false, Session.CLIENT_ACKNOWLEDGE); - mp = s.createProducer(s - .createQueue(TextWorkstationConstants - .getDestinationTextWorkstationQueueName())); - mp.setTimeToLive(TTL_MINUTES * SECONDS_PER_MINUTE - * MILLISECONDS_PER_SECOND); - BytesMessage m = s.createBytesMessage(); - m.writeBytes(DynamicSerializationManager.getManager( - SerializationType.Thrift).serialize(id)); - mp.send(m); - System.out.println(WarningSender.getCurTimeString() + ": " - + id + " sent to text workstation in " - + (System.currentTimeMillis() - t0) + "ms"); - messageNotSent = false; - } catch (JMSException e) { - if (notifyError) { - statusHandler - .handle(Priority.PROBLEM, - "Error trying to send message (" - + id - + ") to Text Workstation. Attempting to reconnect. ", - e); - notifyError = false; - } - } finally { - if (mp != null) { - try { - mp.close(); - mp = null; - } catch (Exception e) { - mp = null; - } - } - if (s != null) { - try { - s.close(); - s = null; - } catch (Exception e) { - s = null; - } - } - if (conn != null) { - try { - conn.close(); - conn = null; - } catch (Exception e) { - conn = null; - } - } - } - if (messageNotSent) { - connectCount++; - switch (connectCount) { - case 1: - Thread.sleep(1000); - break; - case 2: - Thread.sleep(5 * 1000); - break; - case 3: - Thread.sleep(30 * 1000); - break; - case 4: - statusHandler.handle(Priority.PROBLEM, - "Could not reconnect (" + id - + ") after 3 tries: ", null); - break; - } - } - } - } catch (UnknownHostException uhe) { - if (notifyError) { - statusHandler.handle(Priority.PROBLEM, - "unable to map hostname, " + hostName - + ", to an ip address", uhe); - notifyError = false; - } + } catch (Exception e) { + statusHandler.handle(Priority.PROBLEM, + "Error trying to send product [" + id + + "] to Text Workstation: ", e); + } - } catch (Exception e) { - statusHandler.handle(Priority.PROBLEM, - "Error trying to send message (" + id - + ") to Text Workstation: ", e); - } + } - } + /** + * Saves a product to the text database. + * + * @param id + * @param warning + * @throws VizException + */ + public static void sendToTextDatabase(String id, String warning) + throws VizException { + CAVEMode mode = CAVEMode.getMode(); + boolean operationalMode = (CAVEMode.OPERATIONAL.equals(mode) + || CAVEMode.TEST.equals(mode) ? true : false); - public static String getCurTimeString() { - String rval = null; - synchronized (sdf) { - rval = sdf.format(new Date()); - } - return rval; - } + // Generate StdTextProduct and insert into db + long t0 = System.currentTimeMillis(); + ThriftClient.sendRequest(new InsertStdTextProductRequest(id, warning, + operationalMode)); + + System.out.println(WarningSender.getCurTimeString() + ": " + id + + " saved to textdb in " + (System.currentTimeMillis() - t0) + + "ms"); + } + + public static String getCurTimeString() { + String rval = null; + synchronized (sdf) { + rval = sdf.format(new Date()); + } + return rval; + } } diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/DbPointSourceDataAdaptor.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/DbPointSourceDataAdaptor.java index 5016f1dad5..8b2bb5fbd1 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/DbPointSourceDataAdaptor.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/DbPointSourceDataAdaptor.java @@ -19,14 +19,18 @@ **/ package com.raytheon.viz.warngen.config; +import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import org.apache.commons.lang.StringUtils; + import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration; import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration; import com.raytheon.uf.common.dataquery.requests.RequestConstraint; @@ -35,6 +39,7 @@ import com.raytheon.uf.common.geospatial.SpatialException; import com.raytheon.uf.common.geospatial.SpatialQueryFactory; import com.raytheon.uf.common.geospatial.SpatialQueryResult; import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.maps.rsc.DbMapQueryFactory; import com.raytheon.viz.warngen.PreferenceUtil; import com.raytheon.viz.warngen.gis.ClosestPoint; import com.vividsolutions.jts.geom.Geometry; @@ -96,21 +101,62 @@ public class DbPointSourceDataAdaptor implements IPointSourceDataAdaptor { } } - List points = new ArrayList(); + List points = null; try { - SpatialQueryResult[] ptFeatures = SpatialQueryFactory.create() - .query(pointSource, - ptFields.toArray(new String[ptFields.size()]), - searchArea, filter, SearchMode.INTERSECTS); + SpatialQueryResult[] ptFeatures = null; + Double decimationTolerance = pointConfig + .getGeometryDecimationTolerance(); + String field = "the_geom"; + + if (decimationTolerance != null && decimationTolerance > 0) { + // find available tolerances + List results = DbMapQueryFactory.getMapQuery( + "mapdata." + pointSource.toLowerCase(), field) + .getLevels(); + Collections.sort(results, Collections.reverseOrder()); + + boolean found = false; + for (Double val : results) { + if (val <= decimationTolerance) { + decimationTolerance = val; + found = true; + break; + } + } + + if (!found) { + decimationTolerance = null; + } + } + + if (decimationTolerance != null) { + DecimalFormat df = new DecimalFormat("0.######"); + String suffix = "_" + + StringUtils.replaceChars( + df.format(decimationTolerance), '.', '_'); + ptFeatures = SpatialQueryFactory.create().query(pointSource, + field + suffix, + ptFields.toArray(new String[ptFields.size()]), + searchArea, filter, SearchMode.INTERSECTS); + } else { + ptFeatures = SpatialQueryFactory.create().query(pointSource, + ptFields.toArray(new String[ptFields.size()]), + searchArea, filter, SearchMode.INTERSECTS); + } + + if (ptFeatures != null) { + points = new ArrayList(ptFeatures.length); + } else { + points = new ArrayList(0); + } + for (SpatialQueryResult ptRslt : ptFeatures) { if (ptRslt != null && ptRslt.geometry != null) { Object nameObj = ptRslt.attributes.get(pointField); if (nameObj != null) { int population = 0; int warngenlev = 0; - ClosestPoint cp = new ClosestPoint(); - if (ptFields.contains("population")) { try { population = Integer.valueOf(String diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Area.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Area.java index 951197ee00..940eb6b4d1 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Area.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Area.java @@ -27,6 +27,7 @@ import java.util.List; import java.util.Map; import org.apache.commons.lang.Validate; +import org.geotools.referencing.GeodeticCalculator; import com.raytheon.uf.common.dataplugin.warning.config.AreaConfiguration; import com.raytheon.uf.common.dataplugin.warning.config.AreaSourceConfiguration; @@ -70,7 +71,7 @@ import com.vividsolutions.jts.geom.Geometry; * MarineZones shapefiles have no FE_AREA. * Apr 13, 2012 #14691 Qinglu lin Added code for two more fe_area: er and nr. * May 4, 2012 #14887 Qinglu lin Changed 0.25 to 0.60 for DEFAULT_PORTION_TOLERANCE; - * added code to pass a Envelope calculatePortion(). + * added code to pass a Envelope calculatePortion(). * * * @@ -172,8 +173,9 @@ public class Area { List uniqueFips = new ArrayList(); List areas = new ArrayList(); + GeodeticCalculator gc = new GeodeticCalculator(); for (GeospatialData regionFeature : countyMap.values()) { - Geometry regionGeom = regionFeature.geometry; + Geometry regionGeom = regionFeature.geometry; AffectedAreas area = new AffectedAreas(); area.name = regionFeature.attributes.get(areaField).toString(); area.fips = regionFeature.attributes.get(fipsField).toString(); @@ -217,7 +219,8 @@ public class Area { * DEFAULT_PORTION_TOLERANCE; if (areaIntersection < tolerCheck) { area.partOfArea = GisUtil.asStringList(GisUtil - .calculatePortion(regionGeom, intersection, area.suppress)); + .calculatePortion(regionGeom, intersection, gc, + area.suppress)); } // Search the parent region @@ -225,66 +228,67 @@ public class Area { if (parentRegion != null) { area.parentRegion = String.valueOf(parentRegion.attributes .get(parentAreaField)); - String feArea = (String)regionFeature.attributes.get("FE_AREA"); - final List partList = new ArrayList(); + String feArea = (String) regionFeature.attributes + .get("FE_AREA"); + final List partList = new ArrayList(); if (feArea == null) { - // Marine warnings - partList.add(""); + // Marine warnings + partList.add(""); } else { - if (feArea.equals("pa")) - partList.add("PA"); - else if(feArea.equals("mi")) - partList.add("MI"); - else if(feArea.equals("pd")) - partList.add("PD"); - else if(feArea.equals("up")) - partList.add("UP"); - else if(feArea.equals("bb")) - partList.add("BB"); - else if(feArea.equals("er")) - partList.add("ER"); - else if(feArea.equals("eu")) - partList.add("EU"); - else if(feArea.equals("sr")) - partList.add("SR"); - else if(feArea.equals("nr")) - partList.add("NR"); - else if(feArea.equals("wu")) - partList.add("WU"); - else if(feArea.equals("ds")) - partList.add("DS"); - else if(feArea.equals("ne")) - partList.add("NE"); - else if(feArea.equals("nw")) - partList.add("NW"); - else if(feArea.equals("se")) - partList.add("SE"); - else if(feArea.equals("sw")) - partList.add("SW"); - else { - for (int i=0; i calculatePortion(Geometry geom, - Geometry geom2) { - return calculatePortion(geom, geom2, SuppressMap.NONE); + Geometry geom2, GeodeticCalculator gc) { + return calculatePortion(geom, geom2, gc, SuppressMap.NONE); } public static EnumSet calculatePortion(Geometry geom, - Geometry intersection, String suppressType) { + Geometry intersection, GeodeticCalculator gc, String suppressType) { Direction xDirection = null; Direction yDirection = null; @@ -161,23 +167,25 @@ public class GisUtil { double extremaThresholdY = approximateHeight * EXTREME_DELTA; if (distanceX < centerThresholdX) { - xDirection = Direction.CENTRAL; - if (distanceY < centerThresholdY) - yDirection = Direction.CENTRAL; + xDirection = Direction.CENTRAL; + if (distanceY < centerThresholdY) + yDirection = Direction.CENTRAL; } if (xDirection != null && yDirection != null) { - // Both xDirection equals Direction.CENTRAL and yDirection equals Direction.CENTRAL - // calculated above is not always correct for returning EnumSet.of(xDirection,yDirection). - // The following 'if statement' filters out some cases. - if (distanceX < MIN1 || distanceY < MIN1 || (distanceX < MIN2 && distanceY < MIN2)) - return EnumSet.of(xDirection,yDirection); + // Both xDirection equals Direction.CENTRAL and yDirection equals + // Direction.CENTRAL + // calculated above is not always correct for returning + // EnumSet.of(xDirection,yDirection). + // The following 'if statement' filters out some cases. + if (distanceX < MIN1 || distanceY < MIN1 + || (distanceX < MIN2 && distanceY < MIN2)) + return EnumSet.of(xDirection, yDirection); } - + xDirection = null; yDirection = null; - - GeodeticCalculator gc = new GeodeticCalculator(); + gc.setStartingGeographicPoint(centroid.x, centroid.y); gc.setDestinationGeographicPoint(point.x, point.y); double azimuth = gc.getAzimuth(); @@ -229,26 +237,32 @@ public class GisUtil { && !suppressType.equals(SuppressMap.ALL)) retVal.add(yDirection); - if (xDirection != null && - (xDirection.equals(Direction.WEST) || xDirection.equals(Direction.EAST))) { - if ( env.getHeight() < RATIO*approximateHeight) { + if (xDirection != null + && (xDirection.equals(Direction.WEST) || xDirection + .equals(Direction.EAST))) { + if (env.getHeight() < RATIO * approximateHeight) { retVal.add(Direction.CENTRAL); } } - if (yDirection != null && - (yDirection.equals(Direction.NORTH) || yDirection.equals(Direction.SOUTH))) { - if ( env.getWidth() < RATIO*approximateWidth) { + if (yDirection != null + && (yDirection.equals(Direction.NORTH) || yDirection + .equals(Direction.SOUTH))) { + if (env.getWidth() < RATIO * approximateWidth) { retVal.add(Direction.CENTRAL); } } - - if ((retVal.contains(Direction.NORTH) && retVal.contains(Direction.WEST)) || - (retVal.contains(Direction.NORTH) && retVal.contains(Direction.EAST)) || - (retVal.contains(Direction.SOUTH) && retVal.contains(Direction.WEST)) || - (retVal.contains(Direction.SOUTH) && retVal.contains(Direction.EAST)) ) { - if (retVal.contains(Direction.CENTRAL)) - retVal.remove(Direction.CENTRAL); + + if ((retVal.contains(Direction.NORTH) && retVal + .contains(Direction.WEST)) + || (retVal.contains(Direction.NORTH) && retVal + .contains(Direction.EAST)) + || (retVal.contains(Direction.SOUTH) && retVal + .contains(Direction.WEST)) + || (retVal.contains(Direction.SOUTH) && retVal + .contains(Direction.EAST))) { + if (retVal.contains(Direction.CENTRAL)) + retVal.remove(Direction.CENTRAL); } if (isExtreme && !suppressType.equals(SuppressMap.ALL)) @@ -286,11 +300,11 @@ public class GisUtil { coord.x = oldCoord.x; } coord.y = oldCoord.y; - + return coord; - + } - + public static Coordinate[] d2dCoordinates(Coordinate[] oldCoords) { int length = oldCoords.length; Coordinate[] coords = new Coordinate[length]; @@ -327,15 +341,15 @@ public class GisUtil { /** * restoreAlaskaLon() * - * Feb 28, 2012 DR13596 Qinglu Lin Created. + * Feb 28, 2012 DR13596 Qinglu Lin Created. * - * If the longitude of a Coordinate is less than -180 and corresponding - * latitude is larger than 45 degree North, convert it to a value - * equivalent to (360 + the longitude). + * If the longitude of a Coordinate is less than -180 and corresponding + * latitude is larger than 45 degree North, convert it to a value equivalent + * to (360 + the longitude). */ public static Coordinate restoreAlaskaLon(Coordinate oldCoords) { Coordinate coord = new Coordinate(); - if (oldCoords.x < -180. && oldCoords.y > 45.) { + if (oldCoords.x < -180. && oldCoords.y > 45.) { coord.x = 360. + oldCoords.x; } else { coord.x = oldCoords.x; diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Wx.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Wx.java index f182519702..f7fc246d90 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Wx.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Wx.java @@ -53,6 +53,8 @@ import com.raytheon.uf.common.dataplugin.warning.config.PathcastConfiguration; import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration; import com.raytheon.uf.common.dataplugin.warning.config.PointSourceConfiguration.SearchMethod; import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration; +import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialData; +import com.raytheon.uf.common.dataplugin.warning.gis.GeospatialFactory; import com.raytheon.uf.common.dataplugin.warning.util.FileUtil; import com.raytheon.uf.common.dataquery.requests.RequestConstraint; import com.raytheon.uf.common.geospatial.DestinationGeodeticCalculator; @@ -264,6 +266,7 @@ public class Wx { Date start = DateUtil.roundDate(new Date(wwaStartTime + delta), pathcastConfiguration.getInterval()); Date stormTime = new Date(wwaStartTime); + DestinationGeodeticCalculator gc = new DestinationGeodeticCalculator(); while (start.getTime() <= wwaStopTime) { PathCast cast = new PathCast(); cast.time = new Date(start.getTime()); @@ -277,7 +280,6 @@ public class Wx { Coordinate[] pathCoords = new Coordinate[stormLocations.length]; for (int i = 0; i < pathCoords.length; ++i) { Coordinate loc = stormLocations[i]; - DestinationGeodeticCalculator gc = new DestinationGeodeticCalculator(); gc.setStartingGeographicPoint(loc.x, loc.y); long time = (cast.time.getTime() - stormTime.getTime()) / 1000; double distance = stormTrackState.speed * time; @@ -363,11 +365,9 @@ public class Wx { null, false, SearchMode.INTERSECTS); } - SpatialQueryResult[] timeZoneFeatures = SpatialQueryFactory - .create().query(timezoneTable, - new String[] { timezoneField }, - bufferedPathCastArea, null, false, - SearchMode.INTERSECTS); + // timeZones are limited, use data for whole CWA and further + // intersection later + GeospatialData[] timeZones = GeospatialFactory.getTimezones(); Map> pcPoints = new HashMap>(); for (PathCast pc : pathcasts) { @@ -383,7 +383,8 @@ public class Wx { Point centroid = pcGeom != null ? pcGeom.getCentroid() : warningPolygon.getCentroid(); - SpatialQueryResult myArea = null, myTz = null; + SpatialQueryResult myArea = null; + GeospatialData myTz = null; if (areaFeatures != null) { // Find area and parent area @@ -395,13 +396,13 @@ public class Wx { } } - if (timeZoneFeatures != null) { + if (timeZones != null) { // Find time zone - if (timeZoneFeatures.length == 1) { - myTz = timeZoneFeatures[0]; + if (timeZones.length == 1) { + myTz = timeZones[0]; } else { - for (SpatialQueryResult tzResult : timeZoneFeatures) { - if (tzResult.geometry.contains(centroid)) { + for (GeospatialData tzResult : timeZones) { + if (tzResult.prepGeom.contains(centroid)) { myTz = tzResult; break; } @@ -435,7 +436,9 @@ public class Wx { } // Find closest points - List points = new ArrayList(); + GeodeticCalculator gc = new GeodeticCalculator(); + List points = new ArrayList( + ptFeatures.length); for (SpatialQueryResult pointRslt : ptFeatures) { Geometry localPt = (Geometry) pointRslt.attributes .get(transformedKey); @@ -467,7 +470,6 @@ public class Wx { cp.distance = minDist; cp.roundedDistance = (int) metersToDistance .convert(minDist); - GeodeticCalculator gc = new GeodeticCalculator(); gc.setStartingGeographicPoint(cp.point.x, cp.point.y); gc.setDestinationGeographicPoint(closestCoord.x, closestCoord.y); @@ -529,8 +531,7 @@ public class Wx { // check for same point in other pathcast objects. If same point // exists, remove from which ever pathcast is furthest away Set closestPtNames = new HashSet(30); - List tmpPoints = new ArrayList( - maxCount); + List tmpPoints = new ArrayList(maxCount); Queue tmp = new ArrayDeque(pathcasts); while (tmp.isEmpty() == false) { PathCast pc = tmp.remove(); @@ -560,14 +561,14 @@ public class Wx { tmpPoints.clear(); for (int i = 0; i < points.size() && i < maxCount; ++i) { - ClosestPoint point = points.get(i); - String name = point.getName(); - if (!closestPtNames.contains(name)) { - // To prevent duplicate cities in pathcast, - // only unused point is added to tmpPoints - tmpPoints.add(point); - closestPtNames.add(name); - } + ClosestPoint point = points.get(i); + String name = point.getName(); + if (!closestPtNames.contains(name)) { + // To prevent duplicate cities in pathcast, + // only unused point is added to tmpPoints + tmpPoints.add(point); + closestPtNames.add(name); + } } if (tmpPoints.size() > 0) { pc.points = tmpPoints.toArray(new ClosestPoint[tmpPoints @@ -711,7 +712,7 @@ public class Wx { // Sort by fields should have been validated to be same as well List fields = pointConfigs[0].getSortBy() != null ? Arrays - .asList(pointConfigs[0].getSortBy()) : new ArrayList(); + .asList(pointConfigs[0].getSortBy()) : new ArrayList(0); Geometry searchArea = null; double bufferVal = thresholdInMeters; @@ -734,9 +735,9 @@ public class Wx { stormCoords.length + endStormCoords.length); allCoords.addAll(Arrays.asList(stormCoords)); long time = (wwaStopTime - wwaStartTime) / 1000; + DestinationGeodeticCalculator gc = new DestinationGeodeticCalculator(); for (int i = stormCoords.length - 1; i >= 0; --i) { Coordinate loc = stormCoords[i]; - DestinationGeodeticCalculator gc = new DestinationGeodeticCalculator(); gc.setStartingGeographicPoint(loc.x, loc.y); double distance = stormTrackState.speed * time; gc.setDirection(StormTrackDisplay @@ -769,25 +770,32 @@ public class Wx { List availablePoints = new ArrayList(); for (PointSourceConfiguration pointConfig : pointConfigs) { + long t0 = System.currentTimeMillis(); availablePoints.addAll(DataAdaptorFactory.createPointSource( pointConfig).getData(config, pointConfig, bufferedSearchArea, localizedSite)); + long t1 = System.currentTimeMillis(); + System.out.println("getClosestPoint.dbQuery took " + (t1 - t0) + + " for point source " + pointConfig.getPointSource()); } // Convert searchArea to a local projection Geometry localSearchArea = JTS.transform(searchArea, latLonToLocal); - List> points = new ArrayList>(); Coordinate[] localCoords = localSearchArea.getCoordinates(); Coordinate[] coords = searchArea.getCoordinates(); + List> points = new ArrayList>( + coords.length); + GeodeticCalculator gc = new GeodeticCalculator(); + Map nameMap = new HashMap( + (int) (availablePoints.size() * 1.3)); for (int i = 0; i < coords.length; ++i) { Coordinate coord = localCoords[i]; Geometry localDistanceGeom = dimensions == 1 ? localSearchArea : gf .createPoint(coord); Geometry distanceGeom = dimensions == 1 ? searchArea : gf .createPoint(coords[i]); - List pts = new ArrayList(); - Map nameMap = new HashMap(); + nameMap.clear(); for (ClosestPoint cp : availablePoints) { Geometry localPt = JTS.transform(gf.createPoint(cp.point), @@ -800,16 +808,10 @@ public class Wx { ClosestPoint existingPt = nameMap.get(cp.name); if (existingPt == null || distance < existingPt.distance) { // Set the distances - ClosestPoint cp2 = new ClosestPoint(cp); - cp2.distance = distance; + ClosestPoint cp2 = new ClosestPoint(cp); + cp2.distance = distance; cp2.roundedDistance = (int) metersToDistance .convert(distance); - // No point by name or we are better at this location - if (existingPt != null) { - // There was an existing point, remove it - pts.remove(existingPt); - } - GeodeticCalculator gc = new GeodeticCalculator(); gc.setStartingGeographicPoint(cp2.point.x, cp2.point.y); Coordinate cen = distanceGeom.getCentroid() .getCoordinate(); @@ -822,11 +824,12 @@ public class Wx { cp2.oppositeRoundedAzimuth = ClosestPoint .adjustAngle(cp2.roundedAzimuth + 180); nameMap.put(cp2.name, cp2); - pts.add(cp2); } } } + List pts = new ArrayList( + nameMap.values()); if (fields.isEmpty() == false) { // Sort the points based on sortBy fields Collections.sort(pts, new ClosestPointComparator(fields)); @@ -839,38 +842,52 @@ public class Wx { } // Filter to maxCount (Somewhat duplicate logic as pathcast) - Queue> tmp = new ArrayDeque>( - points); - while (tmp.isEmpty() == false) { - List pts = tmp.remove(); - for (int i = 0; i < pts.size() && i < maxCount; ++i) { - // For each point, look for duplicate points in another - ClosestPoint cp = pts.get(i); - for (List pts2 : tmp) { - if (pts2 != pts) { - ClosestPoint found = find(cp, pts2, maxCount); - if (found != null) { - // We found a point within maxCount in this - // list. - if (found.distance < cp.distance) { - // This point is closer to the other - pts.remove(i--); - break; - } else { - // Remove from other pathcast, we are closer - pts2.remove(found); + if (points.size() == 1) { + // optimized for single instance + List pts = points.get(0); + if (pts.size() > maxCount) { + // need to reduce points + pts.subList(maxCount, pts.size()).clear(); + } + } else if (points.size() > 1) { + Queue> tmp = new ArrayDeque>( + points); + while (!tmp.isEmpty()) { + List pts = tmp.remove(); + int maxIndex = Math.min(pts.size(), maxCount); + for (int i = 0; i < maxIndex; ++i) { + // For each point, look for duplicate points in another + ClosestPoint cp = pts.get(i); + for (List pts2 : tmp) { + if (pts2 != pts) { + ClosestPoint found = find(cp, pts2, maxCount); + if (found != null) { + // We found a point within maxCount in this + // list. + if (found.distance < cp.distance) { + // This point is closer to the other + pts.remove(i--); + // changed size of pts, may need to change + // maxIndex + if (pts.size() < maxIndex) { + maxIndex--; + } + break; + } else { + // Remove from other pathcast, we are + // closer + pts2.remove(found); + } } } } } - } - List tmpPoints = new ArrayList(maxCount); - for (int i = 0; i < pts.size() && i < maxCount; ++i) { - tmpPoints.add(pts.get(i)); + if (pts.size() > maxIndex) { + // need to reduce points + pts.subList(maxIndex, pts.size()).clear(); + } } - pts.clear(); - pts.addAll(tmpPoints); } if (points.size() == 1) { List rval = points.get(0); diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenDialog.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenDialog.java index d357d3ae62..9c0ecffe9c 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenDialog.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenDialog.java @@ -2045,14 +2045,12 @@ public class WarngenDialog extends CaveSWTDialog implements /** * Set the shell to visible and then move it on top of the CAVE dialog. */ - public void showDialog(boolean show) { - if (shell != null && shell.isDisposed() == false) { - if (shell.isVisible() != show) { - // Only call setVisible if we aren't what we need - shell.setVisible(show); - } - + public void showDialog(boolean show) { + if (shell != null && shell.isDisposed() == false) { if (show) { + if (shell.isVisible() == false) { + shell.setVisible(true); + } // Move above parent shell if we are showing it shell.moveAbove(getParent()); } diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenUIManager.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenUIManager.java index bec48e778f..8b9b324bff 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenUIManager.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenUIManager.java @@ -202,9 +202,6 @@ public class WarngenUIManager extends InputAdapter { return super.handleMouseUp(x, y, mouseButton); } - if (mouseButton == 2 && !pointCreated) { - new DeleteVertexAction().run(); - } if (mouseButton == 3) { Coordinate c = container.translateClick(x, y); @@ -425,11 +422,14 @@ public class WarngenUIManager extends InputAdapter { Coordinate toRemove = (Coordinate) coords[idx].clone(); GeometryFactory gf = new GeometryFactory(); List coordList = new ArrayList(); - + List alreadyRemoved = new ArrayList(); + for (int i = 0; i < coords.length; ++i) { Coordinate toAdd = (Coordinate) coords[i].clone(); - if (!toAdd.equals(toRemove)) { + if (!toAdd.equals(toRemove) || alreadyRemoved.contains(toAdd)) { coordList.add(toAdd); + } else { + alreadyRemoved.add(toAdd); } } diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/template/TemplateRunner.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/template/TemplateRunner.java index 6808209fb6..66434de188 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/template/TemplateRunner.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/template/TemplateRunner.java @@ -22,14 +22,17 @@ package com.raytheon.viz.warngen.template; import java.awt.geom.Point2D; import java.io.StringWriter; import java.text.DateFormat; +import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; +import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.HashMap; import java.util.Properties; @@ -41,12 +44,14 @@ import javax.measure.converter.UnitConverter; import javax.measure.unit.NonSI; import javax.measure.unit.SI; +import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.tools.generic.ListTool; +import org.geotools.referencing.GeodeticCalculator; import com.raytheon.uf.common.activetable.ActiveTableMode; import com.raytheon.uf.common.activetable.ActiveTableRecord; @@ -67,6 +72,7 @@ import com.raytheon.uf.common.time.DataTime; import com.raytheon.uf.common.time.SimulatedTime; import com.raytheon.uf.edex.core.EdexException; import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.maps.rsc.DbMapQueryFactory; import com.raytheon.uf.viz.core.requests.ThriftClient; import com.raytheon.viz.awipstools.ToolsDataManager; import com.raytheon.viz.awipstools.common.StormTrackData; @@ -96,6 +102,7 @@ import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryCollection; import com.vividsolutions.jts.geom.Polygon; +import com.vividsolutions.jts.geom.prep.PreparedGeometry; import com.vividsolutions.jts.io.WKTReader; /** @@ -218,7 +225,8 @@ public class TemplateRunner { context.put("dateUtil", new DateUtil()); context.put("pointComparator", new ClosestPointComparator()); - String action = followupData != null ? followupData.getAct() : WarningAction.NEW.toString(); + String action = followupData != null ? followupData.getAct() + : WarningAction.NEW.toString(); String phen = followupData != null ? followupData.getPhen() : null; String sig = followupData != null ? followupData.getSig() : null; String etn = followupData != null ? followupData.getEtn() : null; @@ -249,20 +257,21 @@ public class TemplateRunner { String[] oneLetterTZ; double minSize = 1.0E-3d; if (areas != null && areas.length > 0) { - Set timeZones = new HashSet(); + Set timeZones = new HashSet(); for (AffectedAreas area : areas) { if (area.getTimezone() != null) { // Handles counties that span two time zones String oneLetterTimeZones = area.getTimezone().trim(); oneLetterTZ = new String[oneLetterTimeZones.length()]; if (oneLetterTimeZones.length() == 1) { - timeZones.add(String.valueOf(oneLetterTimeZones.charAt(0))); + timeZones.add(String.valueOf(oneLetterTimeZones + .charAt(0))); } else { // Determine if one letter timezone is going to be put into timeZones. Polygon[] poly1, poly2; int n1, n2; double size, totalSize; - for (int i = 0; i < oneLetterTimeZones.length(); i++) { + for (int i = 0; i < oneLetterTimeZones.length(); i++) { oneLetterTZ[i] = String.valueOf(oneLetterTimeZones.charAt(i)); Geometry timezoneGeom = warngenLayer.getTimezoneGeom(oneLetterTZ[i]); t0 = System.currentTimeMillis(); @@ -298,8 +307,8 @@ public class TemplateRunner { + (System.currentTimeMillis() - t0)); if (totalSize > minSize) { timeZones.add(oneLetterTZ[i]); - } - } + } + } // If timeZones has nothing in it when the hatched area is very small, // use the timezone of larger intersection size. if (timeZones.size() == 0 ) { @@ -321,11 +330,11 @@ public class TemplateRunner { Iterator iterator = timeZones.iterator(); while (iterator.hasNext()) { - if (context.get("localtimezone") == null) { - context.put("localtimezone", iterator.next()); - } else if (context.get("secondtimezone") == null) { - context.put("secondtimezone", iterator.next()); - } + if (context.get("localtimezone") == null) { + context.put("localtimezone", iterator.next()); + } else if (context.get("secondtimezone") == null) { + context.put("secondtimezone", iterator.next()); + } } } @@ -343,11 +352,12 @@ public class TemplateRunner { "expire", DateUtil.roundDateTo15(selectedAction == WarningAction.EXT ? endTime : wx.getEndTime())); - + // duration: convert millisecond to minute - long duration = (wx.getEndTime().getTime()-wx.getStartTime().getTime())/(1000*60); + long duration = (wx.getEndTime().getTime() - wx.getStartTime() + .getTime()) / (1000 * 60); context.put("duration", duration); - + context.put("event", eventTime); context.put("ugcline", FipsUtil.getUgcLine(areas, wx.getEndTime(), 15)); @@ -392,8 +402,7 @@ public class TemplateRunner { context.put("movementDirection", motionDirection); // Convert to Point2D representation as Velocity requires // getX() and getY() methods which Coordinate does not have - Coordinate[] newStormLocs = GisUtil - .d2dCoordinates(stormLocs); + Coordinate[] newStormLocs = GisUtil.d2dCoordinates(stormLocs); Point2D.Double[] coords = new Point2D.Double[newStormLocs.length]; for (int i = 0; i < newStormLocs.length; i++) { coords[i] = new Point2D.Double(newStormLocs[i].x, @@ -524,8 +533,9 @@ public class TemplateRunner { if (totalSegments > 1) { al = FollowUpUtil.canceledAreasFromText(originalText); } - context.put("cancel"+ config.getAreaConfig().getVariable(), al); - context.put("ugclinecan", FollowUpUtil.getUgcLineCanFromText(originalText)); + context.put("cancel" + config.getAreaConfig().getVariable(), al); + context.put("ugclinecan", + FollowUpUtil.getUgcLineCanFromText(originalText)); } else if (selectedAction == WarningAction.EXT) { context.put("action", WarningAction.EXT.toString()); context.put("etn", etn); @@ -641,7 +651,7 @@ public class TemplateRunner { + (System.currentTimeMillis() - tz0)); return WarningTextHandler.handle(script.toString().toUpperCase(), - areas, cancelareas, selectedAction, + areas, cancelareas, selectedAction, WarningAction.valueOf((String) context.get("action")), config.getAutoLockText()); } @@ -720,15 +730,13 @@ public class TemplateRunner { Validate.isTrue( config.getAreaConfig().getIncludedWatchAreaBuffer() >= 0, "IncludedWatchAreaBuffer can not be negative"); - Polygon watchArea = (Polygon) polygon.buffer(milesToKilometer - .convert(config.getAreaConfig().getIncludedWatchAreaBuffer()) - / KmToDegrees); + WatchUtil rval = null; GetActiveTableRequest req = new GetActiveTableRequest(); + String[] includedWatches = config.getIncludedWatches(); - if (config.getIncludedWatches() != null - && config.getIncludedWatches().length > 0) { + if (includedWatches != null && includedWatches.length > 0) { String phensigList = null; - for (String includedWatch : config.getIncludedWatches()) { + for (String includedWatch : includedWatches) { if (includedWatch.equalsIgnoreCase("torWatches")) { phensigList = phensigList == null ? "TO.A" : phensigList + ",TO.A"; @@ -737,66 +745,137 @@ public class TemplateRunner { + ",SV.A"; } } + req.setPhensigList(phensigList); - } else { - return null; - } - if (CAVEMode.getMode().equals(CAVEMode.PRACTICE)) { - req.setMode(ActiveTableMode.PRACTICE); - } else { - req.setMode(ActiveTableMode.OPERATIONAL); - } + if (CAVEMode.getMode().equals(CAVEMode.PRACTICE)) { + req.setMode(ActiveTableMode.PRACTICE); + } else { + req.setMode(ActiveTableMode.OPERATIONAL); + } - req.setSiteID(fourLetterSiteId); - req.setRequestValidTimes(true); + req.setSiteID(fourLetterSiteId); + req.setRequestValidTimes(true); - GetActiveTableResponse resp = (GetActiveTableResponse) ThriftClient - .sendRequest(req); - java.util.List activeTable = resp.getActiveTable(); + long t0 = System.currentTimeMillis(); + GetActiveTableResponse resp = (GetActiveTableResponse) ThriftClient + .sendRequest(req); + long t1 = System.currentTimeMillis(); + java.util.List activeTable = resp + .getActiveTable(); - if (activeTable != null && activeTable.isEmpty() == false) { - warngenLayer.createGeometryForWatches(watchArea, activeTable); - } else { - return null; - } + System.out.println("getWatches.getActiveTable time: " + (t1 - t0) + + ", found " + + (activeTable != null ? activeTable.size() : "0") + + " watches"); + boolean val = activeTable != null && !activeTable.isEmpty(); + if (val) { + // Look for ones with valid geometry - SpatialQueryResult[] parentRegionFeatures = null; - try { - parentRegionFeatures = SpatialQueryFactory.create().query("States", - new String[] { "Name" }, watchArea, null, false, - SearchMode.INTERSECTS); - } catch (Exception e) { - return null; - } + t0 = System.currentTimeMillis(); + Polygon watchArea = (Polygon) polygon.buffer(milesToKilometer + .convert(config.getAreaConfig() + .getIncludedWatchAreaBuffer()) + / KmToDegrees); + t1 = System.currentTimeMillis(); + System.out.println("getWatches.polygonBuffer time: " + + (t1 - t0)); - WatchUtil rval = new WatchUtil(); - WeatherAdvisoryWatch watch = null; + t0 = System.currentTimeMillis(); + warngenLayer.createGeometryForWatches(watchArea, activeTable); + t1 = System.currentTimeMillis(); + System.out.println("getWatches.createWatchGeometry time: " + + (t1 - t0)); + SpatialQueryResult[] parentRegionFeatures = null; - for (ActiveTableRecord atr : activeTable) { - // For each State in our watchArea... - for (int j = 0; j < parentRegionFeatures.length; j++) { - watch = new WeatherAdvisoryWatch(); - watch.setEndTime(atr.getEndTime().getTime()); - watch.setPhensig(atr.getPhensig()); + try { + String field = "the_geom"; + t0 = System.currentTimeMillis(); + List results = DbMapQueryFactory.getMapQuery( + "mapdata.states", field).getLevels(); + Collections.sort(results, Collections.reverseOrder()); + Double decimationTolerance = null; + for (Double result : results) { + if (result <= 0.064) { + decimationTolerance = result; + } + } - // Get the intersection of watchArea with State. - Geometry parentGeom = parentRegionFeatures[j].geometry; + if (decimationTolerance != null) { + DecimalFormat df = new DecimalFormat("0.######"); + String suffix = "_" + + StringUtils.replaceChars(df.format(results + .get(results.size() - 1)), '.', '_'); + parentRegionFeatures = SpatialQueryFactory.create() + .query("states", field + suffix, + new String[] { "Name" }, watchArea, + null, false, SearchMode.INTERSECTS); + } else { + parentRegionFeatures = SpatialQueryFactory.create() + .query("states", new String[] { "Name" }, + watchArea, null, false, + SearchMode.INTERSECTS); + } - // If State intersections intersects with out ATR record, add - // watch - if (GeometryUtil.intersects(parentGeom, atr.getGeometry())) { - watch.setParentRegion(parentRegionFeatures[j].attributes - .get("Name").toString()); - - watch.setPartOfParentRegion(GisUtil.asStringList(GisUtil - .calculatePortion(parentGeom, atr.getGeometry()))); - rval.addWaw(watch); + t1 = System.currentTimeMillis(); + System.out.println("getWatches.stateSpatialQuery time: " + + (t1 - t0) + ", found " + + parentRegionFeatures.length + " states"); + } catch (Exception e) { + statusHandler.handle(Priority.PROBLEM, + "Error querying state geometries", e); + return null; } + + rval = new WatchUtil(); + WeatherAdvisoryWatch watch = null; + long cumulativeIntersect = 0; + long cumulativeCalcPortion = 0; + GeodeticCalculator gc = new GeodeticCalculator(); + + // For each State in our watchArea... + for (int j = 0; j < parentRegionFeatures.length; j++) { + Geometry parentGeom = parentRegionFeatures[j].geometry; + List prepGeoms = new ArrayList(); + GeometryUtil.recursivePreparedGeometry(parentGeom, + prepGeoms); + + for (ActiveTableRecord atr : activeTable) { + // Get the intersection of watchArea with State. + watch = new WeatherAdvisoryWatch(); + watch.setEndTime(atr.getEndTime().getTime()); + watch.setPhensig(atr.getPhensig()); + + // If State intersections intersects with out ATR + // record, add watch + t0 = System.currentTimeMillis(); + boolean intersects = GeometryUtil.intersects(prepGeoms, + atr.getGeometry()); + t1 = System.currentTimeMillis(); + cumulativeIntersect = (t1 - t0); + + if (intersects) { + watch.setParentRegion(parentRegionFeatures[j].attributes + .get("Name").toString()); + + t0 = System.currentTimeMillis(); + watch.setPartOfParentRegion(GisUtil + .asStringList(GisUtil.calculatePortion( + parentGeom, atr.getGeometry(), gc))); + t1 = System.currentTimeMillis(); + cumulativeCalcPortion = (t1 - t0); + rval.addWaw(watch); + } + } + } + + System.out.println("getWatches.cumulativeIntersect: " + + cumulativeIntersect); + System.out.println("getWatches.cumulativeCalcPortion: " + + cumulativeCalcPortion); } } return rval; } - } diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/util/WarnGenMathTool.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/util/WarnGenMathTool.java index 2a33ee53ee..b25eecb18c 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/util/WarnGenMathTool.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/util/WarnGenMathTool.java @@ -27,6 +27,12 @@ import org.apache.velocity.tools.generic.MathTool; /** * @author bwoodle * + * SOFTWARE HISTORY + * + * Date Ticket# Engineer Description + * ------------ ---------- ----------- -------------------------- + * Jul 31, 2012 15219 Qinglu Lin Added roundAndPad(). + * */ public class WarnGenMathTool extends MathTool { @@ -57,4 +63,19 @@ public class WarnGenMathTool extends MathTool { return roundToInt(num, 5); } + /** + * Round movement direction to integer, and pad it with leading zeros + * if it's less than 100 + */ + public static String roundAndPad(double direction) { + int num = (int)Math.rint(direction); + if (num < 10) + return String.format ("00%s",num); + else + if (num < 100) + return String.format ("0%s",num); + else + return String.format ("%s",num); + } + } diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/util/WarningTextHandler.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/util/WarningTextHandler.java index eebb62648d..a06eb6da7a 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/util/WarningTextHandler.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/util/WarningTextHandler.java @@ -441,6 +441,8 @@ public class WarningTextHandler { } if (line.trim().length() == 0) { + insideTML = false; + insideLatLon = false; headlineFound = false; if (smwCan) { if (lockSmwCan) @@ -694,7 +696,7 @@ public class WarningTextHandler { // Locking LAT...LON m = latLonPtrn.matcher(line); if (m.find()) { - sb.append(LOCK_START + line + "\n"); + sb.append(LOCK_START + line + "\n" + LOCK_END); insideLatLon = true; continue; } @@ -702,11 +704,10 @@ public class WarningTextHandler { if (insideLatLon) { m = subLatLonPtrn.matcher(line); if (m.find()) { - sb.append(line + "\n"); + sb.append(LOCK_START +line + "\n" + LOCK_END); continue; } else { insideLatLon = false; - sb.append(LOCK_END); } } @@ -719,7 +720,7 @@ public class WarningTextHandler { // Locking TIME...MOT..LOC m = tmlPtrn.matcher(line); if (m.find()) { - sb.append(LOCK_START + line + "\n"); + sb.append(LOCK_START + line + "\n"+ LOCK_END); insideTML = true; continue; } @@ -727,11 +728,10 @@ public class WarningTextHandler { if (insideTML) { m = subTMLPtrn.matcher(line); if (m.matches()) { - sb.append(line + "\n"); + sb.append(LOCK_START + line + "\n" + LOCK_END); continue; } else { insideTML = false; - sb.append(LOCK_END); } } diff --git a/deltaScripts/future/relocateTextUtilities.py b/deltaScripts/future/relocateTextUtilities.py new file mode 100644 index 0000000000..cc636fb002 --- /dev/null +++ b/deltaScripts/future/relocateTextUtilities.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python + +## +# 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. +## + +import glob +import os +import shutil + + +def forceTextProdRegen(): + oldTextProds = glob.glob('/awips2/edex/data/utility/cave_static/configured/*/gfe/userPython/textProducts/*.py*') + for script in oldTextProds: + try: + os.remove(script) + except: + pass + oldTextUtils = glob.glob('/awips2/edex/data/utility/cave_static/configured/*/gfe/userPython/textUtilities/regular/*.py*') + for script in oldTextUtils: + try: + os.remove(script) + except: + pass + # touch shapefile and template file to force regen of textProducts and all textUtilities + shapeFile = glob.glob('/awips2/edex/data/utility/edex_static/base/shapefiles/*/*.shp')[0] + prodTemplate = glob.glob('/awips2/edex/data/utility/edex_static/base/textproducts/templates/product/*.py')[0] + # passing None as the second arg is equivalent to running touch + os.utime(shapeFile, None) + os.utime(prodTemplate, None) + +def relocateSiteLevelUtils(): + sitePaths = getSubDirs('/awips2/edex/data/utility/cave_static/site') + for site in sitePaths: + scripts = glob.glob(os.path.join(site, 'gfe/userPython/textProducts/*.py')) + for script in scripts: + if not isTextProduct(script): + moveToUtilities(script) + +def relocateUserLevelUtils(): + userPaths = getSubDirs('/awips2/edex/data/utility/cave_static/user') + for user in userPaths: + scripts = glob.glob(os.path.join(user, 'gfe/userPython/textProducts/*.py')) + for script in scripts: + if not isTextProduct(script): + moveToUtilities(script) + +def getSubDirs(path): + return [os.path.join(path, name) for name in os.listdir(path) + if os.path.isdir(os.path.join(path, name))] + +def isTextProduct(path): + retVal = False + with open(path, 'r') as f: + txt = f.read() + if "class TextProduct" in txt: + retVal = True + return retVal + +def moveToUtilities(srcPath): + destPath = srcPath.replace('textProducts', 'textUtilities/regular', 1) + if not os.path.isdir(os.path.dirname(destPath)): + os.makedirs(os.path.dirname(destPath)) + shutil.move(srcPath, destPath) + # make sure any .pyo, .pyc, and .md5 files are not left behind + garbageFiles = glob.glob(srcPath + "*") + for file in garbageFiles: + try: + os.remove(file) + except: + pass + +def main(): + forceTextProdRegen() + relocateSiteLevelUtils() + relocateUserLevelUtils() + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/edexOsgi/build.edex/esb/conf/db/hibernateConfig/maps/hibernate.cfg.xml b/edexOsgi/build.edex/esb/conf/db/hibernateConfig/maps/hibernate.cfg.xml index 6587a70f0f..79efc40e97 100644 --- a/edexOsgi/build.edex/esb/conf/db/hibernateConfig/maps/hibernate.cfg.xml +++ b/edexOsgi/build.edex/esb/conf/db/hibernateConfig/maps/hibernate.cfg.xml @@ -62,9 +62,9 @@ 1 60 300 - 10 - 10 1 + 20 + 20 diff --git a/edexOsgi/build.edex/esb/conf/log4j.xml b/edexOsgi/build.edex/esb/conf/log4j.xml index 20eae58b79..2ee48f8aa3 100644 --- a/edexOsgi/build.edex/esb/conf/log4j.xml +++ b/edexOsgi/build.edex/esb/conf/log4j.xml @@ -17,12 +17,32 @@ + + + + + + + + + + + + + + - + + + + + + + diff --git a/edexOsgi/build.edex/esb/conf/res/base/attributeNames.xml b/edexOsgi/build.edex/esb/conf/res/base/attributeNames.xml index dd29625b00..7e014fab4c 100644 --- a/edexOsgi/build.edex/esb/conf/res/base/attributeNames.xml +++ b/edexOsgi/build.edex/esb/conf/res/base/attributeNames.xml @@ -241,7 +241,5 @@ archiveDir svcBackupDir mhsData - requestTimeLogFilter - responseSizeLogFilter diff --git a/edexOsgi/build.edex/esb/conf/res/base/environment.xml b/edexOsgi/build.edex/esb/conf/res/base/environment.xml index 64c3a3c3d5..38058b4d1e 100644 --- a/edexOsgi/build.edex/esb/conf/res/base/environment.xml +++ b/edexOsgi/build.edex/esb/conf/res/base/environment.xml @@ -47,8 +47,6 @@ false ${env:edex.home}/../GFESuite/ /data/fxa/mhs - 1000 - 8 diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/VM_global_library.vm b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/VM_global_library.vm index a6ab74429c..25017c4ad7 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/VM_global_library.vm +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/VM_global_library.vm @@ -1,8 +1,7 @@ ##### UPDATED 3/2/12 12.2.1-4 BY EVAN BOOKBINDER ##### Qinglu Lin 04-04-2012 DR 14691. ##### Qinglu Lin 06-18-2012 DR 15043. Use duration in secondBullet. - -#* +##### Qinglu Lin 07-31-2012 DR 15217. Use roundAndPad for movement direction in DEG. #################################################################################################### Mile Marker Test Code macro "mmarkers" use (called out of VM_global_library.vm): @@ -330,7 +329,7 @@ ${mathUtil.abs(${mathUtil.round($v100)})}## #macro( tml $time $motdir $motspd $timeFormat $eventlocation ) TIME...MOT...LOC ## ${dateUtil.format(${start}, ${timeFormat.time})}Z ## -${mathUtil.round(${motdir})}DEG ## +${mathUtil.roundAndPad(${motdir})}DEG ## ${mathUtil.round(${motspd})}KT ## #foreach(${eventCoord} in ${eventLocation}) #llFormat(${eventCoord.y}) #llFormat(${eventCoord.x}) ## diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodAdvisory.xml b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodAdvisory.xml index ab1c53e225..be7d050092 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodAdvisory.xml +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodAdvisory.xml @@ -296,6 +296,7 @@ and place into this template --> ffmp_basins + 0.064 streamname diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodAdvisoryFollowup.xml b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodAdvisoryFollowup.xml index 134c25f2d8..18622249b8 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodAdvisoryFollowup.xml +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodAdvisoryFollowup.xml @@ -256,6 +256,7 @@ and place into this template --> ffmp_basins + 0.064 streamname diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodAdvisoryFollowup_Zones.xml b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodAdvisoryFollowup_Zones.xml index 5fa4770733..01f9f0c8a7 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodAdvisoryFollowup_Zones.xml +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodAdvisoryFollowup_Zones.xml @@ -290,6 +290,7 @@ and place into this template --> ffmp_basins + 0.064 streamname diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodAdvisory_Zones.xml b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodAdvisory_Zones.xml index 32ff00e343..a05ab96e23 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodAdvisory_Zones.xml +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodAdvisory_Zones.xml @@ -336,6 +336,7 @@ and place into this template --> ffmp_basins + 0.064 streamname diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodWarning.xml b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodWarning.xml index 80a438edf9..7989ed5672 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodWarning.xml +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodWarning.xml @@ -321,6 +321,7 @@ and place into this template --> ffmp_basins + 0.064 streamname diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodWarningFollowup.xml b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodWarningFollowup.xml index 1433fd1a7b..6f51d34850 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodWarningFollowup.xml +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodWarningFollowup.xml @@ -267,6 +267,7 @@ and place into this template --> ffmp_basins + 0.064 streamname diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodWarningFollowup_Zones.xml b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodWarningFollowup_Zones.xml index ee0d6b7eec..ca49de4272 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodWarningFollowup_Zones.xml +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodWarningFollowup_Zones.xml @@ -306,6 +306,7 @@ and place into this template --> ffmp_basins + 0.064 streamname diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodWarning_Zones.xml b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodWarning_Zones.xml index 1301279c46..38dd206ab2 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodWarning_Zones.xml +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/arealFloodWarning_Zones.xml @@ -349,6 +349,7 @@ and place into this template --> ffmp_basins + 0.064 streamname diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/customTemplate.vm b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/customTemplate.vm index 05352d9182..1bfd43192f 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/customTemplate.vm +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/customTemplate.vm @@ -167,7 +167,7 @@ THIS IS A TEST MESSAGE. DO NOT TAKE ACTION BASED ON THIS MESSAGE. TIME...MOT...LOC ## ${dateUtil.format(${event}, ${timeFormat.time})}Z ## -${mathUtil.round(${movementDirection})}DEG ## +${mathUtil.roundAndPad(${movementDirection})}DEG ## ${mathUtil.round(${movementInKnots})}KT ## #foreach(${eventCoord} in ${eventLocation}) #llFormat(${eventCoord.y}) #llFormat(${eventCoord.x}) ## diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/extremeWindWarning.vm b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/extremeWindWarning.vm index 329120f96b..959034f936 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/extremeWindWarning.vm +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/extremeWindWarning.vm @@ -1,12 +1,13 @@ ################# -################################################################ -## EXTREME WIND WARNING TEMPLATE ## -## (SLIGHTLY) MODIFIED BY TOM BIRCHARD - WFO HFO ## +############################################################################ +## EXTREME WIND WARNING TEMPLATE ## +## (SLIGHTLY) MODIFIED BY TOM BIRCHARD - WFO HFO ## ## VERSION AWIPS II 1.0 -- 15-APRIL-2011 -## MODIFIED EVAN BOOKBINDER 09-16-2011 OB11.0.8-8 ## -## EVAN BOOKBINDER WFO EAX 11-04-2011 OB11.9-3 (DRs) ## -## ## -################################################################## +## MODIFIED EVAN BOOKBINDER 09-16-2011 OB11.0.8-8 ## +## EVAN BOOKBINDER WFO EAX 11-04-2011 OB11.9-3 (DRs) ## +## QINGLU LIN 7-31-2012 DR 15217 use roundAndPad ## +## ## +############################################################################ ## EWW PRODUCT ## ################# ## @@ -188,7 +189,7 @@ THIS IS A TEST MESSAGE. DO NOT TAKE ACTION BASED ON THIS MESSAGE. TIME...MOT...LOC ## ${dateUtil.format(${event}, ${timeFormat.time})}Z ## -${mathUtil.round(${movementDirection})}DEG ## +${mathUtil.roundAndPad(${movementDirection})}DEG ## ${mathUtil.round(${movementInKnots})}KT ## #foreach(${eventCoord} in ${eventLocation}) #llFormat(${eventCoord.y}) #llFormat(${eventCoord.x}) ## diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/extremeWindWarningFollowup.vm b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/extremeWindWarningFollowup.vm index bf0bacf43d..ca65bb9b66 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/extremeWindWarningFollowup.vm +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/extremeWindWarningFollowup.vm @@ -2,6 +2,7 @@ ## EWW SVS ## ## MODIFIED EVAN BOOKBINDER 09-16-2011 OB11.0.8-8 ## Evan Bookbinder 4-25-2012 for OB 12.3.1 (corText) +## QINGLU LIN 7-31-2012 DR 15217 use roundAndPad ################################################ ## ### CREATE PHRASING DEPENDING ON WHETHER WE ISSUE EXP PRIOR TO EXPIRATION TIME OR NOT @@ -336,7 +337,7 @@ THIS IS A TEST MESSAGE. DO NOT TAKE ACTION BASED ON THIS MESSAGE. TIME...MOT...LOC ## ${dateUtil.format(${event}, ${timeFormat.time})}Z ## -${mathUtil.round(${movementDirection})}DEG ## +${mathUtil.roundAndPad(${movementDirection})}DEG ## ${mathUtil.round(${movementInKnots})}KT ## #foreach(${eventCoord} in ${eventLocation}) #llFormat(${eventCoord.y}) #llFormat(${eventCoord.x}) ## @@ -487,7 +488,7 @@ LAT...LON ## TIME...MOT...LOC ## ${dateUtil.format(${event}, ${timeFormat.time})}Z ## -${mathUtil.round(${movementDirection})}DEG ## +${mathUtil.roundAndPad(${movementDirection})}DEG ## ${mathUtil.round(${movementInKnots})}KT ## #foreach(${eventCoord} in ${eventLocation}) #llFormat(${eventCoord.y}) #llFormat(${eventCoord.x}) ## diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/ffwfaw.xml b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/ffwfaw.xml index 7b9258cdb7..27e6a280ff 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/ffwfaw.xml +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/ffwfaw.xml @@ -338,6 +338,7 @@ ALTHOUGH IT SERVES NO PURPOSE HERE, IT WILL CRASH WARNGEN IF REMOVED --> ffmp_basins + 0.064 streamname diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/flashFloodWarning.xml b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/flashFloodWarning.xml index d27ccefda8..0571339759 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/flashFloodWarning.xml +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/flashFloodWarning.xml @@ -311,6 +311,7 @@ and place into this template --> ffmp_basins + 0.064 streamname diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/flashFloodWarningFollowup.xml b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/flashFloodWarningFollowup.xml index 29ee6edb61..f51059ec30 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/flashFloodWarningFollowup.xml +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/flashFloodWarningFollowup.xml @@ -269,6 +269,7 @@ and place into this template --> ffmp_basins + 0.064 streamname diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/flashFloodWarningFollowup_Zones.xml b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/flashFloodWarningFollowup_Zones.xml index 46917cccdd..3d6a93f1c0 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/flashFloodWarningFollowup_Zones.xml +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/flashFloodWarningFollowup_Zones.xml @@ -275,6 +275,7 @@ and place into this template --> ffmp_basins + 0.064 streamname diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/flashFloodWarning_Zones.xml b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/flashFloodWarning_Zones.xml index bf0b1034e5..a47c03c630 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/flashFloodWarning_Zones.xml +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/flashFloodWarning_Zones.xml @@ -304,6 +304,7 @@ and place into this template --> ffmp_basins + 0.064 streamname diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/impactSevereThunderstormWarning.vm b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/impactSevereThunderstormWarning.vm index 628fb62734..95a654b2ab 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/impactSevereThunderstormWarning.vm +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/impactSevereThunderstormWarning.vm @@ -5,6 +5,7 @@ ## VERSION AWIPS II 1.0 -- 2-21-2012 OB12.1.1-1 ## ## VERSION AWIPS II 1.1 -- 2-29-2012 OB12.2.1-4 ## ## VERSION AWIPS II 1.2 -- 4-20-2012 ## +## BY QINGLU LIN 7-31-2012 DR 15217 use roundAndPad ## ################################################################ ## ##SET SOME INITIAL VARIABLES @@ -656,7 +657,7 @@ THIS IS A TEST MESSAGE. DO NOT TAKE ACTION BASED ON THIS MESSAGE. TIME...MOT...LOC ## ${dateUtil.format(${event}, ${timeFormat.time})}Z ## -${mathUtil.round(${movementDirection})}DEG ## +${mathUtil.roundAndPad(${movementDirection})}DEG ## ${mathUtil.round(${movementInKnots})}KT ## #foreach(${eventCoord} in ${eventLocation}) #llFormat(${eventCoord.y}) #llFormat(${eventCoord.x}) ## diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/impactSevereWeatherStatement.vm b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/impactSevereWeatherStatement.vm index 2f9c2fa970..3aac4392af 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/impactSevereWeatherStatement.vm +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/impactSevereWeatherStatement.vm @@ -5,6 +5,7 @@ ## VERSION AWIPS II 1.0 -- 2-21-2012 OB12.1.1-1 ## ## VERSION AWIPS II 1.1 -- 2-29-2012 OB12.2.1-4 ## ## VERSION AWIPS II 1.2 -- 4-20-2012 ## +## BY QINGLU LIN 7-31-2012 DR 15217 use roundAndPad ## ################################################################ ## ################################################################### @@ -302,7 +303,7 @@ REMEMBER...A TORNADO WARNING STILL REMAINS IN EFFECT FOR !** PORTION AND COUNTY TIME...MOT...LOC ## ${dateUtil.format(${now}, ${timeFormat.time})}Z ## -${mathUtil.round(${movementDirection})}DEG ## +${mathUtil.roundAndPad(${movementDirection})}DEG ## ${mathUtil.round(${movementInKnots})}KT ## #foreach(${eventCoord} in ${eventLocation}) #llFormat(${eventCoord.y}) #llFormat(${eventCoord.x}) ## @@ -1161,7 +1162,7 @@ THIS IS A TEST MESSAGE. DO NOT TAKE ACTION BASED ON THIS MESSAGE. TIME...MOT...LOC ## ${dateUtil.format(${event}, ${timeFormat.time})}Z ## -${mathUtil.round(${movementDirection})}DEG ## +${mathUtil.roundAndPad(${movementDirection})}DEG ## ${mathUtil.round(${movementInKnots})}KT ## #foreach(${eventCoord} in ${eventLocation}) #llFormat(${eventCoord.y}) #llFormat(${eventCoord.x}) ## diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/impactTornadoWarning.vm b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/impactTornadoWarning.vm index 089e9782ba..4ca6ee4802 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/impactTornadoWarning.vm +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/impactTornadoWarning.vm @@ -5,6 +5,7 @@ ## VERSION AWIPS II 1.0 -- 2-21-2012 OB12.1.1-1 ## ## VERSION AWIPS II 1.1 -- 2-29-2012 OB12.2.1-4 ## ## VERSION AWIPS II 1.2 -- 4-20-2012 ## +## BY QINGLU LIN 7-31-2012 DR 15217 use roundAndPad ## ################################################################ ## ESTABLISH SOME INITIAL VARIABLES #set ($preAmble = "") @@ -627,7 +628,7 @@ THIS IS A TEST MESSAGE. DO NOT TAKE ACTION BASED ON THIS MESSAGE. TIME...MOT...LOC ## ${dateUtil.format(${event}, ${timeFormat.time})}Z ## -${mathUtil.round(${movementDirection})}DEG ## +${mathUtil.roundAndPad(${movementDirection})}DEG ## ${mathUtil.round(${movementInKnots})}KT ## #foreach(${eventCoord} in ${eventLocation}) #llFormat(${eventCoord.y}) #llFormat(${eventCoord.x}) ## diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/nonConvectiveFlashFloodWarning.xml b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/nonConvectiveFlashFloodWarning.xml index dbd0196b89..b3d382ae86 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/nonConvectiveFlashFloodWarning.xml +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/nonConvectiveFlashFloodWarning.xml @@ -369,6 +369,7 @@ and place into this template ffmp_basins + 0.064 streamname diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/nonConvectiveFlashFloodWarningFollowup.xml b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/nonConvectiveFlashFloodWarningFollowup.xml index ba06385b13..59a2dd4764 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/nonConvectiveFlashFloodWarningFollowup.xml +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/nonConvectiveFlashFloodWarningFollowup.xml @@ -396,6 +396,7 @@ and place into this template ffmp_basins + 0.064 streamname diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/nonConvectiveFlashFloodWarningFollowup_Zones.xml b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/nonConvectiveFlashFloodWarningFollowup_Zones.xml index 0ba5705ed8..8ea5cdf3a9 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/nonConvectiveFlashFloodWarningFollowup_Zones.xml +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/nonConvectiveFlashFloodWarningFollowup_Zones.xml @@ -398,6 +398,7 @@ and place into this template ffmp_basins + 0.064 streamname diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/nonConvectiveFlashFloodWarning_Zones.xml b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/nonConvectiveFlashFloodWarning_Zones.xml index a34c4e7552..51c1cac32b 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/nonConvectiveFlashFloodWarning_Zones.xml +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/nonConvectiveFlashFloodWarning_Zones.xml @@ -368,6 +368,7 @@ and place into this template ffmp_basins + 0.064 streamname diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/severeThunderstormWarning.vm b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/severeThunderstormWarning.vm index b94f780416..27384c25ae 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/severeThunderstormWarning.vm +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/severeThunderstormWarning.vm @@ -8,6 +8,7 @@ ## 11-04-2011 OB11.9-3 (DRs) ## ## 2-24-2012 OB12.2.1 CLEANUP ## ## BY QINGLU LIN 6-18-2012 DR 15043 use duration ## +## BY QINGLU LIN 7-31-2012 DR 15217 use roundAndPad ## ################################################################ ## ##SET SOME INITIAL VARIABLES @@ -475,7 +476,7 @@ THIS IS A TEST MESSAGE. DO NOT TAKE ACTION BASED ON THIS MESSAGE. TIME...MOT...LOC ## ${dateUtil.format(${event}, ${timeFormat.time})}Z ## -${mathUtil.round(${movementDirection})}DEG ## +${mathUtil.roundAndPad(${movementDirection})}DEG ## ${mathUtil.round(${movementInKnots})}KT ## #foreach(${eventCoord} in ${eventLocation}) #llFormat(${eventCoord.y}) #llFormat(${eventCoord.x}) ## diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/severeWeatherStatement.vm b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/severeWeatherStatement.vm index 7446de8c4f..da9149404a 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/severeWeatherStatement.vm +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/severeWeatherStatement.vm @@ -9,6 +9,7 @@ ## BY EVAN BOOKBINDER 2-24-2012 OB12.2.1 ## ## BY MIKE REGA 5-3-2012 DR 14885 MND blank line ## ## BY QINGLU LIN 6-18-2012 DR 15043 use duration ## +## BY QINGLU LIN 7-31-2012 DR 15217 use roundAndPad## ################################################################# ## ################################################################### @@ -277,7 +278,7 @@ REMEMBER...A TORNADO WARNING STILL REMAINS IN EFFECT FOR !** PORTION AND COUNTY TIME...MOT...LOC ## ${dateUtil.format(${now}, ${timeFormat.time})}Z ## -${mathUtil.round(${movementDirection})}DEG ## +${mathUtil.roundAndPad(${movementDirection})}DEG ## ${mathUtil.round(${movementInKnots})}KT ## #foreach(${eventCoord} in ${eventLocation}) #llFormat(${eventCoord.y}) #llFormat(${eventCoord.x}) ## @@ -859,7 +860,7 @@ THIS IS A TEST MESSAGE. DO NOT TAKE ACTION BASED ON THIS MESSAGE. TIME...MOT...LOC ## ${dateUtil.format(${event}, ${timeFormat.time})}Z ## -${mathUtil.round(${movementDirection})}DEG ## +${mathUtil.roundAndPad(${movementDirection})}DEG ## ${mathUtil.round(${movementInKnots})}KT ## #foreach(${eventCoord} in ${eventLocation}) #llFormat(${eventCoord.y}) #llFormat(${eventCoord.x}) ## diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/significantWeatherAdvisory.vm b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/significantWeatherAdvisory.vm index 16e1e0575b..d0ceee0fff 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/significantWeatherAdvisory.vm +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/significantWeatherAdvisory.vm @@ -6,6 +6,7 @@ ## Edited by Mike Dangelo 02-27-2012 ## ## Edited by Phil Kurimski 3-01-2012 OB12.2.1-4 ## ## Evan Bookbinder 4-25-2012 for OB 12.3.1 (MND) +## QINGLU LIN 7-31-2012 DR 15217 use roundAndPad ## ###################################################### ## ##SET SOME INITIAL VARIABLES @@ -322,7 +323,7 @@ THIS IS A TEST MESSAGE. DO NOT TAKE ACTION BASED ON THIS MESSAGE. TIME...MOT...LOC ## ${dateUtil.format(${event}, ${timeFormat.time})}Z ## -${mathUtil.round(${movementDirection})}DEG ## +${mathUtil.roundAndPad(${movementDirection})}DEG ## ${mathUtil.round(${movementInKnots})}KT ## #foreach(${eventCoord} in ${eventLocation}) #llFormat(${eventCoord.y}) #llFormat(${eventCoord.x}) ## diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/specialMarineWarning.vm b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/specialMarineWarning.vm index c5e9d4286e..2f97773b33 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/specialMarineWarning.vm +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/specialMarineWarning.vm @@ -9,6 +9,7 @@ ## VERSION AWIPS II 1.4 -- JAN 26 2012 OB12.1.1-1 ## ## Cleaned up wind coding for version 1.4 ## ## VERSION AWIPS II 1.5 -- MAR 2 2012 OB12.2.1-4 ## +## BY QINGLU LIN 7-31-2012 DR 15217 use roundAndPad ## ##################################################### ## Added Volcano Information in version 1.3 for sites where ## Volcanoes affect their marine zones. If sites wish to hide @@ -394,7 +395,7 @@ THIS IS A TEST MESSAGE. DO NOT TAKE ACTION BASED ON THIS MESSAGE. TIME...MOT...LOC ## ${dateUtil.format(${event}, ${timeFormat.time})}Z ## -${mathUtil.round(${movementDirection})}DEG ## +${mathUtil.roundAndPad(${movementDirection})}DEG ## ${mathUtil.round(${movementInKnots})}KT ## #foreach(${eventCoord} in ${eventLocation}) #llFormat(${eventCoord.y}) #llFormat(${eventCoord.x}) ## diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/specialMarineWarningFollowup.vm b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/specialMarineWarningFollowup.vm index 4f1e3eee88..0779831aa9 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/specialMarineWarningFollowup.vm +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/specialMarineWarningFollowup.vm @@ -10,6 +10,7 @@ ## Cleaned up wind coding for version 1.4 ## ## VERSION AWIPS II 1.5 -- MAR 2 2012 OB12.2.1-4 ## ## BY MGAMAZAYCHIKOV -- JUL 20 2012 DR15006 ## +## BY QINGLU LIN 7-31-2012 DR 15217 use roundAndPad ## ##################################################### ## Added Volcano Information in version 1.3 for sites where ## Volcanoes affect their marine zones. If sites wish to hide @@ -563,7 +564,7 @@ THIS IS A TEST MESSAGE. DO NOT TAKE ACTION BASED ON THIS MESSAGE. TIME...MOT...LOC ## ${dateUtil.format(${event}, ${timeFormat.time})}Z ## -${mathUtil.round(${movementDirection})}DEG ## +${mathUtil.roundAndPad(${movementDirection})}DEG ## ${mathUtil.round(${movementInKnots})}KT ## #foreach(${eventCoord} in ${eventLocation}) #llFormat(${eventCoord.y}) #llFormat(${eventCoord.x}) ## @@ -976,7 +977,7 @@ THIS IS A TEST MESSAGE. DO NOT TAKE ACTION BASED ON THIS MESSAGE. TIME...MOT...LOC ## ${dateUtil.format(${event}, ${timeFormat.time})}Z ## -${mathUtil.round(${movementDirection})}DEG ## +${mathUtil.roundAndPad(${movementDirection})}DEG ## ${mathUtil.round(${movementInKnots})}KT ## #foreach(${eventCoord} in ${eventLocation}) #llFormat(${eventCoord.y}) #llFormat(${eventCoord.x}) ## @@ -1402,7 +1403,7 @@ THIS IS A TEST MESSAGE. DO NOT TAKE ACTION BASED ON THIS MESSAGE. TIME...MOT...LOC ## ${dateUtil.format(${now}, ${timeFormat.time})}Z ## -${mathUtil.round(${movementDirection})}DEG ## +${mathUtil.roundAndPad(${movementDirection})}DEG ## ${mathUtil.round(${movementInKnots})}KT ## #foreach(${eventCoord} in ${eventLocation}) #llFormat(${eventCoord.y}) #llFormat(${eventCoord.x}) ## diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/tornadoWarning.vm b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/tornadoWarning.vm index 0ae6165a8b..86e1177ea2 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/tornadoWarning.vm +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/warngen/tornadoWarning.vm @@ -11,6 +11,7 @@ ## EVAN BOOKBINDER WFO EAX 11-04-11 - OB11.9-3 (DRs) ## ## EVAN BOOKBINDER WFO EAX 2-24-12 - OB12.2.1 ## ## MIKE REGA 5-03-12 - DR 14885 MND blank line ## +## QINGLU LIN 7-31-2012 DR 15217 use roundAndPad ## ############################################################################### ## ESTABLISH SOME INITIAL VARIABLES #set($preAmble = "") @@ -421,7 +422,7 @@ THIS IS A TEST MESSAGE. DO NOT TAKE ACTION BASED ON THIS MESSAGE. TIME...MOT...LOC ## ${dateUtil.format(${event}, ${timeFormat.time})}Z ## -${mathUtil.round(${movementDirection})}DEG ## +${mathUtil.roundAndPad(${movementDirection})}DEG ## ${mathUtil.round(${movementInKnots})}KT ## #foreach(${eventCoord} in ${eventLocation}) #llFormat(${eventCoord.y}) #llFormat(${eventCoord.x}) ## diff --git a/edexOsgi/build.edex/esb/data/utility/edex_static/base/smartinit/Init.py b/edexOsgi/build.edex/esb/data/utility/edex_static/base/smartinit/Init.py index 31ab9521ff..4db1571056 100644 --- a/edexOsgi/build.edex/esb/data/utility/edex_static/base/smartinit/Init.py +++ b/edexOsgi/build.edex/esb/data/utility/edex_static/base/smartinit/Init.py @@ -23,6 +23,7 @@ # ------------ ---------- ----------- -------------------------- # 02/16/12 14439 jdynina modified haines thresholds # 02/16/12 13917 jdynina merged in changes from TRAC ticket 11391 +# 07/25/12 #957 dgilling implement edit areas as args to calc methods. # # ## @@ -36,7 +37,7 @@ pytime = time #-------------------------------------------------------------------------- #-------------------------------------------------------------------------- -# Definitiona for model database class. +# Definition for model database class. #-------------------------------------------------------------------------- class MDB: def __init__(self, dblist): @@ -336,11 +337,7 @@ class Forecaster(GridUtilities): # LogStream.logProblem("staticTopo not available, using topo") # self.__stopo = self.__topo - areas = self._client.getEditAreaNames() - areasize = areas.size() - self._editAreas = [] - for i in range(areasize): - self._editAreas.append(str(areas.get(i))) + self._editAreas = self._client.getEditAreaNames() self._empty = self.__topo * 0 self._minus = self._empty - 1 @@ -958,8 +955,8 @@ class Forecaster(GridUtilities): for arg in args: if arg in self._editAreas: if cache[arg][0] is None: - p = self.newdb()[we] - ea = p.getEditArea(arg) + p = self.newdb().getItem(we) + ea = p.getEditArea(arg).__numpy__[0] cache[arg] = (ea, (0, sys.maxint)) gargs.append(cache[arg][0]) continue diff --git a/edexOsgi/build.edex/esb/data/utility/edex_static/base/textproducts/Generator.py b/edexOsgi/build.edex/esb/data/utility/edex_static/base/textproducts/Generator.py index 8b43696fe2..7be3c78550 100755 --- a/edexOsgi/build.edex/esb/data/utility/edex_static/base/textproducts/Generator.py +++ b/edexOsgi/build.edex/esb/data/utility/edex_static/base/textproducts/Generator.py @@ -30,6 +30,8 @@ Date Ticket# Engineer Description Jun 23, 2008 1180 jelkins Initial creation Jul 08, 2008 1222 jelkins Modified for use within Java Jul 09, 2008 1222 jelkins Split command line loader from class +Jul 24, 2012 #944 dgilling Refactored to support separate + generation of products and utilities. @author: jelkins """ @@ -78,6 +80,20 @@ LOG = logging.getLogger("Generator") # List of protected files fileList = [] +#Installation information for product formatters. +#Directories to Process, src/dest +ProcessDirectories = [ + { + 'src': "textproducts/templates/product", + 'dest': "textProducts" + }, + { + 'src': "textproducts/templates/utility", + 'dest': "textUtilities/regular" + }, + ] + + class Generator(): """Generates site specific text products from base template files. @@ -86,11 +102,8 @@ class Generator(): def __init__(self): """Class constructor""" - - # self.setSiteId(siteId) - # self.setDestination(destinationDir) - - self.setTemplate(TEMPLATE_DIR) + self.__destination = None + self.__siteId = None def setSiteId(self,siteId): """Set the site ID @@ -107,25 +120,6 @@ class Generator(): else: raise LookupError, ' unknown WFO: ' + siteId - def setTemplate(self, value): - """Set this generator's source directory - - Verifies the directory exists and is readable - - @param value: this value should be a fully qualified path - @type value: string - - @raise IOError: when the directory is not found - """ - from os import access - from os import R_OK - - if access(value,R_OK): - self.__template = value - else: - LOG.debug("Attempted to use templates from: %s" % value) - raise IOError, 'directory not readable' - def setDestination(self, value): """Set this generator's output directory @@ -155,14 +149,6 @@ class Generator(): """ return self.__siteId - def getTemplate(self): - """The template directory location - - @return: the template directory location - @rtype: string - """ - return self.__template - def getDestination(self): """The directory into which the generated files are placed @@ -185,7 +171,10 @@ class Generator(): self.__delete() self.__createPilDictionary(self.__siteId) - created = self.__create() + + created = 0 + for dirInfo in ProcessDirectories: + created += self.__create(dirInfo['src'], dirInfo['dest']) LOG.info("%d text products created" % created) LOG.debug("Configuration of Text Products Finish") @@ -199,12 +188,12 @@ class Generator(): # ---- Delete Empty Directory ----------------------------------------- - try: - from os import rmdir - rmdir(self.getDestination()) - except OSError, description: - LOG.warn("unable to remove directory (%s)" % description) - pass + for dirInfo in ProcessDirectories: + try: + os.rmdir(os.path.join(self.getDestination(), dirInfo['dest'])) + except OSError, description: + LOG.warn("unable to remove directory (%s)" % description) + pass def info(self): """Text product information for this site""" @@ -311,23 +300,23 @@ class Generator(): from preferences.configureTextProducts import ProductToStandardMapping subDict = {} - subDict[''] = siteid - subDict[''] = SITE_INFO[siteid]['region'] - subDict[''] = SITE_INFO[siteid]['wfoCityState'] - subDict[''] = SITE_INFO[siteid]['wfoCity'] - subDict[''] = SITE_INFO[siteid]['fullStationID'] - subDict[''] = SITE_INFO[siteid]['state'] + subDict[''] = siteid.strip() + subDict[''] = SITE_INFO[siteid]['region'].strip() + subDict[''] = SITE_INFO[siteid]['wfoCityState'].strip() + subDict[''] = SITE_INFO[siteid]['wfoCity'].strip() + subDict[''] = SITE_INFO[siteid]['fullStationID'].strip() + subDict[''] = SITE_INFO[siteid]['state'].strip() if product is not None: - subDict[''] = product + subDict[''] = product.strip() if ProductToStandardMapping.has_key(product): - subDict[''] = ProductToStandardMapping[product] + subDict[''] = ProductToStandardMapping[product].strip() else: - subDict[''] = product + subDict[''] = product.strip() if pilInfo is not None: for k in pilInfo.keys(): - subDict['<' + k + '>'] = pilInfo[k] + subDict['<' + k + '>'] = pilInfo[k].strip() if pilInfo is not None and pilInfo.has_key("pil") and multiPilFlag: - subDict[''] = pilInfo["pil"][3:6]#pil=nnnxxx, want xxx + subDict[''] = pilInfo["pil"][3:6].strip() #pil=nnnxxx, want xxx else: subDict['_'] = "" #no multiple pils @@ -350,33 +339,27 @@ class Generator(): pilInfo = self.__pilInfo subDict = {} - subDict['Site'] = siteid - subDict['Region'] = SITE_INFO[siteid]['region'] + subDict['Site'] = siteid.strip() + subDict['Region'] = SITE_INFO[siteid]['region'].strip() if product is not None: - subDict['Product'] = product + subDict['Product'] = product.strip() if pilInfo is not None and pilInfo.has_key("pil") and multiPilFlag: - subDict['MultiPil'] = pilInfo["pil"][3:6] #xxx of nnnxxx + subDict['MultiPil'] = pilInfo["pil"][3:6].strip() #xxx of nnnxxx else: subDict['_MultiPil'] = "" #no pil information, remove entry return self.substituteKeywords(subDict,fileName) - def __getTemplateFiles(self): + def __getTemplateFiles(self, srcDir): """Get a list of all template files @return: a list of all template files @rtype: list """ + pathMgr = PathManagerFactory.getPathManager() edexStaticBase = pathMgr.getContext(LocalizationType.EDEX_STATIC, LocalizationLevel.BASE) - templateFiles = pathMgr.listFiles(edexStaticBase, "textproducts/templates", None, True, True) - -# templateFiles = [] -# -# from os import walk -# for root,dirs,files in walk(TEMPLATE_DIR): -# map(lambda fileName:templateFiles.append(join(root,fileName)),files) - + templateFiles = pathMgr.listFiles(edexStaticBase, srcDir, None, False, True) return templateFiles def __printPilDictionary(self, pillist): @@ -503,7 +486,7 @@ class Generator(): LOG.error("Unknown Product: %s" % regularNameBase) return None - def __create(self): + def __create(self, srcDir, destDir): """Build the formatters for this site Substitute the appropriate values into the templates. Name and place @@ -519,11 +502,11 @@ class Generator(): # ---- Gather a list of all template Files -------------------------- - templateFiles = self.__getTemplateFiles() + templateFiles = self.__getTemplateFiles(srcDir) # ---- Process the files --------------------------------------------- - import os, stat, string + import stat, string for lf in templateFiles: fileName = str(lf.getFile().getAbsolutePath()) @@ -604,7 +587,7 @@ class Generator(): # ---- Output to File ----------------------------------- - destFilename = join(self.getDestination(),destName)+regNameExt + destFilename = join(self.getDestination(), destDir, destName) + regNameExt LOG.debug(" ---> %s" % destFilename) try: @@ -679,60 +662,59 @@ class Generator(): allProducts.append(p) for p in templateProds: allProducts.append(p) + + for dirInfo in ProcessDirectories: + templateFiles = self.__getTemplateFiles(dirInfo['src']) - templateFiles = self.__getTemplateFiles() + #determine potential files, based on the template files + for lf in templateFiles: + tf = str(lf.getFile().getAbsolutePath()) - #determine potential files, based on the template files - for lf in templateFiles: - tf = str(lf.getFile().getAbsolutePath()) - - LOG.debug("Template= %s" % basename(tf)) - mname = basename(tf) - globExpressions = [] - - #wildcard the Site - mname = string.replace(mname, "Site", "???") #always 3 chars - - #wildcard the Region - mname = string.replace(mname, "Region", "??") #always 2 chars - - #wildcard the _MultiPil - wcards = [] - if string.find(mname, "_MultiPil") != -1: - wcards.append(string.replace(mname, "_MultiPil", "")) - wcards.append(string.replace(mname, "_MultiPil", "_?")) - wcards.append(string.replace(mname, "_MultiPil", "_??")) - wcards.append(string.replace(mname, "_MultiPil", "_???")) - else: - wcards.append(mname) - - #wildcard the Product - if string.find(mname, "Product") == 0: - for wc in wcards: - for prd in allProducts: - ge = prd + wc[7:] #Product is first 7 characters - globExpressions.append(ge) - - #simple case - Product does not need to be expanded - else: - for wc in wcards: - globExpressions.append(wc) - - for g in globExpressions: - - searchString = join(self.getDestination(),g) - - delfiles = glob.glob(searchString) - - for fn in delfiles: - #delete any existing file - try: - os.chmod(fn, 0644) - os.remove(fn) - LOG.debug(" DEL---> %s" % fn) - productsRemoved += 1 - except: - pass + LOG.debug("Template= %s" % basename(tf)) + mname = basename(tf) + globExpressions = [] + + #wildcard the Site + mname = string.replace(mname, "Site", "???") #always 3 chars + + #wildcard the Region + mname = string.replace(mname, "Region", "??") #always 2 chars + + #wildcard the _MultiPil + wcards = [] + if string.find(mname, "_MultiPil") != -1: + wcards.append(string.replace(mname, "_MultiPil", "")) + wcards.append(string.replace(mname, "_MultiPil", "_?")) + wcards.append(string.replace(mname, "_MultiPil", "_??")) + wcards.append(string.replace(mname, "_MultiPil", "_???")) + else: + wcards.append(mname) + + #wildcard the Product + if string.find(mname, "Product") == 0: + for wc in wcards: + for prd in allProducts: + ge = prd + wc[7:] #Product is first 7 characters + globExpressions.append(ge) + + #simple case - Product does not need to be expanded + else: + for wc in wcards: + globExpressions.append(wc) + + for g in globExpressions: + searchString = join(self.getDestination(), dirInfo['dest'], g) + delfiles = glob.glob(searchString) + + for fn in delfiles: + #delete any existing file + try: + os.chmod(fn, 0644) + os.remove(fn) + LOG.debug(" DEL---> %s" % fn) + productsRemoved += 1 + except: + pass LOG.debug(" Deleting Existing Baseline Templates Finished........") diff --git a/edexOsgi/build.edex/esb/data/utility/edex_static/base/textproducts/templates/product/Hazard_HLS.py b/edexOsgi/build.edex/esb/data/utility/edex_static/base/textproducts/templates/product/Hazard_HLS.py index f703d6b209..2e4586340e 100644 --- a/edexOsgi/build.edex/esb/data/utility/edex_static/base/textproducts/templates/product/Hazard_HLS.py +++ b/edexOsgi/build.edex/esb/data/utility/edex_static/base/textproducts/templates/product/Hazard_HLS.py @@ -5167,16 +5167,16 @@ READINESS ACTIONS AS RECOMMENDED."""), def _surge_Watch_Impact_stmt(self, info, segment): t="" water_dict = self._totalWaterLevel_dict(info, segment) - if info.surgeHtPlusTide > water_dict.get("Extreme", 7): + if info.surgeHtPlusTide >= water_dict.get("Extreme", 7): damage="WIDESPREAD MAJOR" - elif info.surgeHtPlusTide > water_dict.get("High", 5): + elif info.surgeHtPlusTide >= water_dict.get("High", 5): damage="AREAS OF MAJOR" - elif info.surgeHtPlusTide > water_dict.get("Moderate", 3): + elif info.surgeHtPlusTide >= water_dict.get("Moderate", 3): damage="AREAS OF MODERATE" - elif info.surgeHtPlusTide > water_dict.get("Low", 1): + elif info.surgeHtPlusTide >= water_dict.get("Low", 1): damage="AREAS OF MINOR" else: damage = None @@ -5189,16 +5189,16 @@ READINESS ACTIONS AS RECOMMENDED."""), def _surge_Impact_stmt(self, info, segment): t="" water_dict = self._totalWaterLevel_dict(info, segment) - if info.surgeHtPlusTide > water_dict.get("Extreme", 7): + if info.surgeHtPlusTide >= water_dict.get("Extreme", 7): damage= self._totalWaterLevel_Extreme_stmt(info, segment) - elif info.surgeHtPlusTide > water_dict.get("High", 5): + elif info.surgeHtPlusTide >= water_dict.get("High", 5): damage= self._totalWaterLevel_High_stmt(info, segment) - elif info.surgeHtPlusTide > water_dict.get("Moderate", 3): + elif info.surgeHtPlusTide >= water_dict.get("Moderate", 3): damage= self._totalWaterLevel_Moderate_stmt(info, segment) - elif info.surgeHtPlusTide > water_dict.get("Low", 1): + elif info.surgeHtPlusTide >= water_dict.get("Low", 1): damage= self._totalWaterLevel_Low_stmt(info, segment) else: damage ="MINOR COASTAL FLOOD DAMAGE" diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/reference/ReferenceMgr.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/reference/ReferenceMgr.java new file mode 100644 index 0000000000..43b563038d --- /dev/null +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/reference/ReferenceMgr.java @@ -0,0 +1,162 @@ +/** + * 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.plugin.gfe.reference; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.raytheon.edex.plugin.gfe.config.IFPServerConfig; +import com.raytheon.uf.common.dataplugin.gfe.db.objects.GridLocation; +import com.raytheon.uf.common.dataplugin.gfe.reference.ReferenceData; +import com.raytheon.uf.common.dataplugin.gfe.reference.ReferenceID; +import com.raytheon.uf.common.dataplugin.gfe.server.message.ServerResponse; +import com.raytheon.uf.common.localization.IPathManager; +import com.raytheon.uf.common.localization.LocalizationFile; +import com.raytheon.uf.common.localization.LocalizationUtil; +import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.common.serialization.SerializationUtil; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.util.FileUtil; + +/** + * Manages reference sets for the ifpServer. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 24, 2012            dgilling     Initial creation
+ * 
+ * 
+ * + * @author dgilling + * @version 1.0 + */ + +public class ReferenceMgr { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(ReferenceMgr.class); + + private static final String EDIT_AREAS_DIR = FileUtil.join("gfe", + "editAreas"); + + IPathManager pathMgr; + + GridLocation dbGridLocation; + + public ReferenceMgr(final IFPServerConfig config) { + this.pathMgr = PathManagerFactory.getPathManager(); + this.dbGridLocation = config.dbDomain(); + } + + /** + * Returns the inventory of data on disk. + * + * @return ReferenceIDs for every defined edit area on disk. + */ + public ServerResponse> getInventory() { + List refIDs = new ArrayList(); + LocalizationFile[] contents = PathManagerFactory.getPathManager() + .listStaticFiles(EDIT_AREAS_DIR, new String[] { ".xml" }, + false, true); + if (contents != null) { + for (LocalizationFile lf : contents) { + String s = LocalizationUtil.extractName(lf.getName()); + String area = s.replace(".xml", ""); + refIDs.add(new ReferenceID(area, lf.isProtected(), lf + .getContext().getLocalizationLevel())); + } + } + + statusHandler.debug("ReferenceID inventory: " + refIDs); + + ServerResponse> sr = new ServerResponse>(); + sr.setPayload(refIDs); + return sr; + } + + /** + * Retrieves the specified ReferenceData, which is identified + * by ReferenceIDs, and returns it to the caller. + * + * @param ids + * ReferenceIDs of the data to retrieve. + * @return The requested ReferenceData. + */ + public ServerResponse> getData( + final List ids) { + ServerResponse> sr = new ServerResponse>(); + List data = new ArrayList(); + + // process each ReferenceID requested + for (ReferenceID id : ids) { + String path = FileUtil.join(EDIT_AREAS_DIR, id.getName() + ".xml"); + LocalizationFile lf = pathMgr.getStaticLocalizationFile(path); + + // does it exist? + if (lf == null) { + sr.addMessage("Unable to find reference data [" + id + "]"); + data = Collections.emptyList(); + sr.setPayload(data); + return sr; + } + + // open and read the file + ReferenceData refData = null; + try { + refData = (ReferenceData) SerializationUtil + .jaxbUnmarshalFromXmlFile(lf.getFile().getPath()); + } catch (Exception e) { + sr.addMessage("Unable to read reference data [" + id + "]"); + data = Collections.emptyList(); + sr.setPayload(data); + return sr; + } + + // assemble the actual ReferenceID, with the protect and access + // flags + ReferenceID referenceID = new ReferenceID(id.getName(), + lf.isProtected(), lf.getContext().getLocalizationLevel()); + + // assemble the ReferenceData + refData.setGloc(dbGridLocation); + refData.setId(referenceID); + data.add(refData); + } + + sr.setPayload(data); + return sr; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "ReferenceMgr [" + dbGridLocation.getSiteId() + "]"; + } +} diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/smartinit/IFPWE.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/smartinit/IFPWE.java index bb5f791f50..f2354b8278 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/smartinit/IFPWE.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/smartinit/IFPWE.java @@ -20,12 +20,16 @@ package com.raytheon.edex.plugin.gfe.smartinit; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.TimeZone; +import com.raytheon.edex.plugin.gfe.config.IFPServerConfig; +import com.raytheon.edex.plugin.gfe.config.IFPServerConfigManager; +import com.raytheon.edex.plugin.gfe.reference.ReferenceMgr; import com.raytheon.edex.plugin.gfe.server.GridParmManager; import com.raytheon.edex.plugin.gfe.server.lock.LockManager; import com.raytheon.edex.plugin.gfe.util.SendNotifications; @@ -36,8 +40,12 @@ import com.raytheon.uf.common.dataplugin.gfe.db.objects.GridParmInfo; import com.raytheon.uf.common.dataplugin.gfe.db.objects.ParmID; import com.raytheon.uf.common.dataplugin.gfe.discrete.DiscreteKey; import com.raytheon.uf.common.dataplugin.gfe.exception.GfeException; +import com.raytheon.uf.common.dataplugin.gfe.grid.Grid2DBit; import com.raytheon.uf.common.dataplugin.gfe.grid.Grid2DByte; import com.raytheon.uf.common.dataplugin.gfe.grid.Grid2DFloat; +import com.raytheon.uf.common.dataplugin.gfe.reference.ReferenceData; +import com.raytheon.uf.common.dataplugin.gfe.reference.ReferenceData.RefType; +import com.raytheon.uf.common.dataplugin.gfe.reference.ReferenceID; import com.raytheon.uf.common.dataplugin.gfe.server.lock.LockTable; import com.raytheon.uf.common.dataplugin.gfe.server.lock.LockTable.LockMode; import com.raytheon.uf.common.dataplugin.gfe.server.message.ServerMsg; @@ -62,10 +70,11 @@ import com.raytheon.uf.common.time.TimeRange; * *
  * SOFTWARE HISTORY
- * Date			Ticket#		Engineer	Description
- * ------------	----------	-----------	--------------------------
- * May 7, 2008				njensen	    Initial creation
- * Jan 22, 2010      4248   njensen      Better error msgs
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * May 7, 2008              njensen     Initial creation
+ * Jan 22, 2010  4248       njensen     Better error msgs
+ * Jul 25, 2012  #957       dgilling    Implement getEditArea().
  * 
  * 
* @@ -455,4 +464,30 @@ public class IFPWE { public ParmID getParmid() { return parmId; } + + public Grid2DBit getEditArea(String name) { + try { + IFPServerConfig config = IFPServerConfigManager + .getServerConfig(siteId); + ReferenceMgr refMgr = new ReferenceMgr(config); + + ServerResponse> sr = refMgr.getData(Arrays + .asList(new ReferenceID(name))); + if (sr.isOkay()) { + ReferenceData data = sr.getPayload().get(0); + if (data.refType() != RefType.POLYGON) { + throw new Exception("Edit area is not a polygon"); + } + return data.getGrid(); + } else { + statusHandler.error("Unable to retrieve edit area [" + name + + "]: " + sr.message()); + } + } catch (Exception e) { + statusHandler.error("Unable to retrieve edit area [" + name + "].", + e); + } + + return null; + } } diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/smartinit/InitClient.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/smartinit/InitClient.java index e9c91d3000..ce65ca3e28 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/smartinit/InitClient.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/smartinit/InitClient.java @@ -22,10 +22,9 @@ package com.raytheon.edex.plugin.gfe.smartinit; import java.util.ArrayList; import java.util.List; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - +import com.raytheon.edex.plugin.gfe.config.IFPServerConfig; import com.raytheon.edex.plugin.gfe.config.IFPServerConfigManager; +import com.raytheon.edex.plugin.gfe.reference.ReferenceMgr; import com.raytheon.edex.plugin.gfe.server.GridParmManager; import com.raytheon.edex.plugin.gfe.server.database.TopoDatabaseManager; import com.raytheon.edex.plugin.gfe.util.SendNotifications; @@ -33,14 +32,15 @@ import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID; import com.raytheon.uf.common.dataplugin.gfe.db.objects.GFERecord; import com.raytheon.uf.common.dataplugin.gfe.db.objects.ParmID; import com.raytheon.uf.common.dataplugin.gfe.exception.GfeException; +import com.raytheon.uf.common.dataplugin.gfe.reference.ReferenceID; +import com.raytheon.uf.common.dataplugin.gfe.server.message.ServerResponse; import com.raytheon.uf.common.dataplugin.gfe.server.notify.UserMessageNotification; import com.raytheon.uf.common.dataplugin.gfe.server.request.GetGridRequest; import com.raytheon.uf.common.dataplugin.gfe.slice.IGridSlice; -import com.raytheon.uf.common.dataplugin.gfe.util.GfeUtil; +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.TimeRange; -import com.raytheon.uf.edex.core.EDEXUtil; -import com.raytheon.uf.edex.core.EdexException; /** * Init Client used by smart init for retrieving specific info @@ -50,6 +50,7 @@ import com.raytheon.uf.edex.core.EdexException; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Apr 29, 2008 njensen Initial creation + * Jul 25, 2012 #957 dgilling Implement getEditAreaNames(). * * * @@ -59,7 +60,8 @@ import com.raytheon.uf.edex.core.EdexException; public class InitClient { - private static final Log logger = LogFactory.getLog(InitClient.class); + private static final transient IUFStatusHandler logger = UFStatus + .getHandler(InitClient.class); private DatabaseID destinationDB; @@ -109,10 +111,33 @@ public class InitClient { return list; } - public List getEditAreaNames() { - ArrayList list = new ArrayList(); - // TODO implement something here - return list; + // returning an array here instead of a List because arrays get converted to + // Python lists automatically by Jep + public String[] getEditAreaNames() { + try { + String siteId = destinationDB.getSiteId(); + IFPServerConfig config = IFPServerConfigManager + .getServerConfig(siteId); + ReferenceMgr refMgr = new ReferenceMgr(config); + + ServerResponse> sr = refMgr.getInventory(); + if (sr.isOkay()) { + List ids = sr.getPayload(); + String[] l = new String[ids.size()]; + for (int i = 0; i < ids.size(); i++) { + l[i] = ids.get(i).getName(); + } + + return l; + } else { + logger.error("Unable to retrieve edit area inventory: " + + sr.message()); + } + } catch (Exception e) { + logger.error("Unable to retrieve edit area inventory.", e); + } + + return new String[0]; } public IGridSlice getTopo() throws GfeException { diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/textproducts/Configurator.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/textproducts/Configurator.java index 98cbcbeb02..7fa29754f0 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/textproducts/Configurator.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/textproducts/Configurator.java @@ -57,9 +57,11 @@ import com.raytheon.uf.edex.database.cluster.ClusterTask; * *
  * SOFTWARE HISTORY
- * Date			Ticket#		Engineer	Description
- * ------------	----------	-----------	--------------------------
- * Jul 7, 2008	1222		jelkins	Initial creation
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * Jul 7, 2008  1222        jelkins     Initial creation
+ * Jul 24,2012  #944        dgilling    Fix text product template generation
+ *                                      to create textProducts and textUtilities.
  * 
  * 
* @@ -108,8 +110,7 @@ public class Configurator { try { destinationDirectory = pathMgr.getFile(caveStaticConfig, - FileUtil.join("gfe", "userPython", "textProducts")) - .getCanonicalPath(); + FileUtil.join("gfe", "userPython")).getCanonicalPath(); } catch (IOException e) { log.error("Unable to determine the destination directory", e); log.warn("Textproducts will not be configured."); diff --git a/edexOsgi/com.raytheon.edex.plugin.grib/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject b/edexOsgi/com.raytheon.edex.plugin.grib/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject index 4105c55c03..d04ff31480 100644 --- a/edexOsgi/com.raytheon.edex.plugin.grib/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject +++ b/edexOsgi/com.raytheon.edex.plugin.grib/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject @@ -11,3 +11,5 @@ com.raytheon.edex.plugin.grib.util.GribParamInfo com.raytheon.edex.plugin.grib.util.ParameterInfo com.raytheon.edex.plugin.grib.spatial.FileData com.raytheon.edex.plugin.grib.spatial.FileDataList +com.raytheon.edex.plugin.grib.decoderpostprocessors.PostProcessedModelSet +com.raytheon.edex.plugin.grib.decoderpostprocessors.PostProcessedModel diff --git a/edexOsgi/com.raytheon.edex.plugin.grib/src/com/raytheon/edex/plugin/grib/decoderpostprocessors/GribPostProcessor.java b/edexOsgi/com.raytheon.edex.plugin.grib/src/com/raytheon/edex/plugin/grib/decoderpostprocessors/GribPostProcessor.java index d94c5af917..627a0c36cb 100644 --- a/edexOsgi/com.raytheon.edex.plugin.grib/src/com/raytheon/edex/plugin/grib/decoderpostprocessors/GribPostProcessor.java +++ b/edexOsgi/com.raytheon.edex.plugin.grib/src/com/raytheon/edex/plugin/grib/decoderpostprocessors/GribPostProcessor.java @@ -20,23 +20,20 @@ package com.raytheon.edex.plugin.grib.decoderpostprocessors; -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import com.raytheon.uf.common.dataplugin.grib.GribRecord; import com.raytheon.uf.common.dataplugin.grib.exception.GribException; -import com.raytheon.uf.common.localization.IPathManager; -import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; -import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; +import com.raytheon.uf.common.dataplugin.grib.util.GribModelLookup; import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.common.serialization.SerializationException; +import com.raytheon.uf.common.serialization.SerializationUtil; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; -import com.raytheon.uf.common.status.UFStatus.Priority; /** * An implementation to modify a grib record after the initial grid decoding if @@ -56,147 +53,162 @@ import com.raytheon.uf.common.status.UFStatus.Priority; * @version 1 */ public class GribPostProcessor { - private static final transient IUFStatusHandler statusHandler = UFStatus - .getHandler(GribPostProcessor.class); + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(GribPostProcessor.class); - /** The singleton instance */ - private static GribPostProcessor instance; + /** The singleton instance */ + private static GribPostProcessor instance; - /** The map containing the currently registered grib post processors */ - private static Map> processorMap = new HashMap>(); + /** The map containing the currently registered grib post processors */ + private static Map> processorMap = new HashMap>(); - /** - * Gets the singleton instance of GribPostProcessor - * - * @return The singleton instance of GribPostProcessor - */ - public static synchronized GribPostProcessor getInstance() { - if (instance == null) { - instance = new GribPostProcessor(); - } - return instance; - } + private static final String CLASS_PREFIX = "com.raytheon.edex.plugin.grib.decoderpostprocessors."; - /** - * Creates a new GribPostProcessor instance - */ - private GribPostProcessor() { - IPathManager pm = PathManagerFactory.getPathManager(); - String processorFile = pm.getFile( - pm.getContext(LocalizationType.EDEX_STATIC, - LocalizationLevel.BASE), - "/grib/postProcessModels/postProcessedModels.txt").getPath(); - BufferedReader in = null; - try { - in = new BufferedReader(new FileReader(processorFile)); - String line = null; - String[] tokens = null; - while ((line = in.readLine()) != null) { - if (line.startsWith("#") || line.trim().isEmpty()) { - continue; - } - tokens = line.split(":"); - String model = tokens[0].trim(); - IDecoderPostProcessor postProcessor = getPostProcessor( - tokens[0].trim(), tokens[1].trim()); - if (processorMap.containsKey(model)) { - processorMap.get(model).add(postProcessor); - } else { - ArrayList processors = new ArrayList(); - processors.add(postProcessor); - processorMap.put(model, processors); - } - } - in.close(); - } catch (IOException e) { - statusHandler.handle(Priority.PROBLEM, - "Error reading post processed model file", e); - } catch (GribException e) { - statusHandler.handle(Priority.PROBLEM, - "Error instantiating decoder post processor", e); - } finally { - if (in != null) { - try { - in.close(); - } catch (IOException e) { - statusHandler.handle(Priority.PROBLEM, - "Error closing post processed model file", e); - } - } - } - } + /** + * Gets the singleton instance of GribPostProcessor + * + * @return The singleton instance of GribPostProcessor + */ + public static synchronized GribPostProcessor getInstance() { + if (instance == null) { + instance = new GribPostProcessor(); + } + return instance; + } - /** - * Processes the GribRecords to determine if they need post processing - * - * @param records - * The records to examine - * @return The GribRecords including any new records created during the post - * processing - * @throws GribException - */ - public GribRecord[] process(GribRecord[] records) throws GribException { - List processors; - GribRecord[] results = null; - List additionalGrids = null; - for (int i = 0; i < records.length; i++) { - // Check the map to see if this grib record is part of a model for - // which post processing is necessary - processors = processorMap.get(records[i].getModelInfo() - .getModelName()); - if (processors != null) { - for (IDecoderPostProcessor processor : processors) { - // Post processing is not necessary, so we continue - if (processor == null) { - continue; - } - // Post processing is necessary - else { - results = processor.process(records[i]); - if (results.length == 0) { - return results; - } - records[i] = results[0]; - if (results.length > 1) { - if (additionalGrids == null) { - additionalGrids = new ArrayList(); - } - for (int j = 1; j < results.length; j++) { - additionalGrids.add(results[j]); - } - } - } - } - } - } - if (additionalGrids == null) { - return records; - } else { - for (int i = 0; i < records.length; i++) { - additionalGrids.add(records[i]); - } - return additionalGrids.toArray(new GribRecord[] {}); - } - } + /** + * Creates a new GribPostProcessor instance + */ + private GribPostProcessor() { + String processorFile = PathManagerFactory + .getPathManager() + .getStaticFile( + "/grib/postProcessModels/postProcessedModels.xml") + .getPath(); - private IDecoderPostProcessor getPostProcessor(String modelName, - String processorClassName) throws GribException { + try { + // Get the list of available model names + Set modelNames = GribModelLookup.getInstance() + .getModelNames(); - for (List processors : processorMap.values()) { - for (IDecoderPostProcessor processor : processors) { - if (processor.getClass().getCanonicalName() - .equals(processorClassName)) { - return processor; - } - } - } - try { - return (IDecoderPostProcessor) Class.forName(processorClassName) - .newInstance(); - } catch (Exception e) { - throw new GribException( - "Error instantiating decoder post processor for " - + modelName + " model.", e); - } - } + // Unmarshal the post processed model file + PostProcessedModelSet ppModelSet = (PostProcessedModelSet) SerializationUtil + .jaxbUnmarshalFromXmlFile(processorFile); + + /* + * Iterate over post processed models. Determine which models apply + * to each post processor if a regex is present + */ + for (PostProcessedModel ppModel : ppModelSet.getModels()) { + for (String modelName : modelNames) { + if (modelName.matches(ppModel.getModelName())) { + List processorInstances = processorMap + .get(modelName); + if (processorInstances == null) { + processorMap.put(modelName, + new ArrayList()); + processorInstances = processorMap.get(modelName); + } + + for (String processor : ppModel.getProcessors()) { + try { + processorInstances + .add((IDecoderPostProcessor) Class + .forName( + CLASS_PREFIX + + processor) + .newInstance()); + } catch (InstantiationException e) { + statusHandler + .fatal("Error instantiating grib post processor!", + e); + } catch (IllegalAccessException e) { + statusHandler + .fatal("Error instantiating grib post processor!", + e); + } catch (ClassNotFoundException e) { + statusHandler + .info("Class [" + + CLASS_PREFIX + + processor + + "] not found. Trying to load class: [" + + processor + "]"); + try { + processorInstances + .add((IDecoderPostProcessor) Class + .forName(processor) + .newInstance()); + } catch (Exception e1) { + statusHandler + .fatal("Error instantiating grib post processor!", + e1); + } + } + + } + + } + } + } + } catch (SerializationException e) { + statusHandler.fatal( + "Error unmarshalling post processed model list: "+processorFile, e); + } + + } + + /** + * Processes the GribRecords to determine if they need post processing + * + * @param records + * The records to examine + * @return The GribRecords including any new records created during the post + * processing + * @throws GribException + */ + public GribRecord[] process(GribRecord[] records) throws GribException { + List processors; + GribRecord[] results = null; + List additionalGrids = null; + for (int i = 0; i < records.length; i++) { + // Check the map to see if this grib record is part of a model for + // which post processing is necessary + processors = processorMap.get(records[i].getModelInfo() + .getModelName()); + if (processors != null) { + for (IDecoderPostProcessor processor : processors) { + // Post processing is not necessary, so we continue + if (processor == null) { + continue; + } + // Post processing is necessary + else { + results = processor.process(records[i]); + if (results.length == 0) { + continue; + } + records[i] = results[0]; + if (results.length > 1) { + if (additionalGrids == null) { + additionalGrids = new ArrayList(); + } + for (int j = 1; j < results.length; j++) { + additionalGrids.add(results[j]); + } + } + } + } + } + } + if (additionalGrids == null) { + return records; + } else { + GribRecord[] returnArray = new GribRecord[records.length+additionalGrids.size()]; + System.arraycopy(records, 0, returnArray, 0, records.length); + for (int i = records.length; i < returnArray.length; i++) { + returnArray[i] = additionalGrids.get(i-records.length); + } + return returnArray; + } + } } diff --git a/edexOsgi/com.raytheon.edex.plugin.grib/src/com/raytheon/edex/plugin/grib/decoderpostprocessors/PostProcessedModel.java b/edexOsgi/com.raytheon.edex.plugin.grib/src/com/raytheon/edex/plugin/grib/decoderpostprocessors/PostProcessedModel.java new file mode 100644 index 0000000000..5e5fb9ff77 --- /dev/null +++ b/edexOsgi/com.raytheon.edex.plugin.grib/src/com/raytheon/edex/plugin/grib/decoderpostprocessors/PostProcessedModel.java @@ -0,0 +1,100 @@ +/** + * 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.plugin.grib.decoderpostprocessors; + +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 com.raytheon.uf.common.serialization.ISerializableObject; + +/** + * A container class to hold which post processors apply to a grib model + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 7/24/12      949         bphillip    Initial Creation
+ * 
+ * 
+ * + * @author bphillip + * @version 1 + */ +@XmlRootElement(name = "postProcessedModel") +@XmlAccessorType(XmlAccessType.NONE) +public class PostProcessedModel implements ISerializableObject { + + /** + * The model name to which the processors apply. May be a regular expression + */ + @XmlElement + private String modelName; + + /** + * The list of grib decoder post processors. The short class name may be + * used if the class is in the + * com.raytheon.edex.plugin.grib.decoderpostprocessors package. A fully + * qualified name may be used if the grib post processor is defined + * elsewhere + */ + @XmlElement(name = "processorName") + private List processors; + + public PostProcessedModel() { + + } + + public String getModelName() { + return modelName; + } + + public void setModelName(String modelName) { + this.modelName = modelName; + } + + public List getProcessors() { + if (processors == null) { + processors = new ArrayList(); + } + return processors; + } + + public void setProcessors(List processors) { + this.processors = processors; + } + + public String toString() { + StringBuffer buf = new StringBuffer(); + buf.append(modelName).append("\n"); + for (String proc : processors) { + buf.append(proc).append("\n"); + } + return buf.toString(); + } + +} diff --git a/edexOsgi/com.raytheon.edex.plugin.grib/src/com/raytheon/edex/plugin/grib/decoderpostprocessors/PostProcessedModelSet.java b/edexOsgi/com.raytheon.edex.plugin.grib/src/com/raytheon/edex/plugin/grib/decoderpostprocessors/PostProcessedModelSet.java new file mode 100644 index 0000000000..62c3135951 --- /dev/null +++ b/edexOsgi/com.raytheon.edex.plugin.grib/src/com/raytheon/edex/plugin/grib/decoderpostprocessors/PostProcessedModelSet.java @@ -0,0 +1,70 @@ +/** + * 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.plugin.grib.decoderpostprocessors; + +import java.util.ArrayList; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElements; +import javax.xml.bind.annotation.XmlRootElement; + +import com.raytheon.uf.common.serialization.ISerializableObject; + +/** + * A container class to hold the list of models needing to be post processed + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 7/24/12      949         bphillip    Initial Creation
+ * 
+ * 
+ * + * @author bphillip + * @version 1 + */ +@XmlRootElement(name = "postProcessedModels") +@XmlAccessorType(XmlAccessType.NONE) +public class PostProcessedModelSet implements ISerializableObject{ + + /** + * List of post processed modesl + */ + @XmlElements({ @XmlElement(name = "postProcessedModel", type = PostProcessedModel.class) }) + private ArrayList models; + + public ArrayList getModels() { + if(models == null){ + models = new ArrayList(); + } + return models; + } + + public void setModels(ArrayList models) { + this.models = models; + } + +} diff --git a/edexOsgi/com.raytheon.edex.plugin.grib/utility/edex_static/base/grib/postProcessModels/postProcessedModels.txt b/edexOsgi/com.raytheon.edex.plugin.grib/utility/edex_static/base/grib/postProcessModels/postProcessedModels.txt deleted file mode 100644 index ae96f585d8..0000000000 --- a/edexOsgi/com.raytheon.edex.plugin.grib/utility/edex_static/base/grib/postProcessModels/postProcessedModels.txt +++ /dev/null @@ -1,80 +0,0 @@ -# RUC130 PostProcessor -RUC130:com.raytheon.edex.plugin.grib.decoderpostprocessors.RUC130GribPostProcessor - -# Generate 6Hr Records Post Processor -ECMWF-HiRes:com.raytheon.edex.plugin.grib.decoderpostprocessors.ECMWFHiResProcessor -GFS213:com.raytheon.edex.plugin.grib.decoderpostprocessors.GFSProcessor - -# Post Processor For Lifted Index, if the ability to limit post processing to specific -# parameters is ever added this would be better done there -ETA:com.raytheon.edex.plugin.grib.decoderpostprocessors.Nam80PostProcessor -ETA218:com.raytheon.edex.plugin.grib.decoderpostprocessors.LiftedIndexPostProcessor -ETA242:com.raytheon.edex.plugin.grib.decoderpostprocessors.LiftedIndexPostProcessor -GFS212:com.raytheon.edex.plugin.grib.decoderpostprocessors.LiftedIndexPostProcessor -GFS213:com.raytheon.edex.plugin.grib.decoderpostprocessors.LiftedIndexPostProcessor - -# Ensemble Grids that need to be stitched together -AVN37:com.raytheon.edex.plugin.grib.decoderpostprocessors.EnsembleGridAssembler -AVN38:com.raytheon.edex.plugin.grib.decoderpostprocessors.EnsembleGridAssembler -AVN39:com.raytheon.edex.plugin.grib.decoderpostprocessors.EnsembleGridAssembler -AVN40:com.raytheon.edex.plugin.grib.decoderpostprocessors.EnsembleGridAssembler -ECMF1:com.raytheon.edex.plugin.grib.decoderpostprocessors.EnsembleGridAssembler -ECMF2:com.raytheon.edex.plugin.grib.decoderpostprocessors.EnsembleGridAssembler -ECMF3:com.raytheon.edex.plugin.grib.decoderpostprocessors.EnsembleGridAssembler -ECMF4:com.raytheon.edex.plugin.grib.decoderpostprocessors.EnsembleGridAssembler -ECMF5:com.raytheon.edex.plugin.grib.decoderpostprocessors.EnsembleGridAssembler -ECMF6:com.raytheon.edex.plugin.grib.decoderpostprocessors.EnsembleGridAssembler -ECMF7:com.raytheon.edex.plugin.grib.decoderpostprocessors.EnsembleGridAssembler -ECMF8:com.raytheon.edex.plugin.grib.decoderpostprocessors.EnsembleGridAssembler -ENSEMBLE37:com.raytheon.edex.plugin.grib.decoderpostprocessors.EnsembleGridAssembler -ENSEMBLE38:com.raytheon.edex.plugin.grib.decoderpostprocessors.EnsembleGridAssembler -ENSEMBLE39:com.raytheon.edex.plugin.grib.decoderpostprocessors.EnsembleGridAssembler -ENSEMBLE40:com.raytheon.edex.plugin.grib.decoderpostprocessors.EnsembleGridAssembler -UKMET37:com.raytheon.edex.plugin.grib.decoderpostprocessors.EnsembleGridAssembler -UKMET38:com.raytheon.edex.plugin.grib.decoderpostprocessors.EnsembleGridAssembler -UKMET39:com.raytheon.edex.plugin.grib.decoderpostprocessors.EnsembleGridAssembler -UKMET40:com.raytheon.edex.plugin.grib.decoderpostprocessors.EnsembleGridAssembler - -# FFG grids -FFG-TIR:com.raytheon.edex.plugin.grib.decoderpostprocessors.FFGGribPostProcessor -FFG-RSA:com.raytheon.edex.plugin.grib.decoderpostprocessors.FFGGribPostProcessor -FFG-ORN:com.raytheon.edex.plugin.grib.decoderpostprocessors.FFGGribPostProcessor -FFG-FWR:com.raytheon.edex.plugin.grib.decoderpostprocessors.FFGGribPostProcessor -FFG-MSR:com.raytheon.edex.plugin.grib.decoderpostprocessors.FFGGribPostProcessor -FFG-TUA:com.raytheon.edex.plugin.grib.decoderpostprocessors.FFGGribPostProcessor -FFG-ALR:com.raytheon.edex.plugin.grib.decoderpostprocessors.FFGGribPostProcessor -FFG-RHA:com.raytheon.edex.plugin.grib.decoderpostprocessors.FFGGribPostProcessor -FFG-STR:com.raytheon.edex.plugin.grib.decoderpostprocessors.FFGGribPostProcessor -FFG-KRF:com.raytheon.edex.plugin.grib.decoderpostprocessors.FFGGribPostProcessor -FFG-ACR:com.raytheon.edex.plugin.grib.decoderpostprocessors.FFGGribPostProcessor -FFG-PTR:com.raytheon.edex.plugin.grib.decoderpostprocessors.FFGGribPostProcessor -FFG-TAR:com.raytheon.edex.plugin.grib.decoderpostprocessors.FFGGribPostProcessor - -#RFCqpf grids -RFCqpf:com.raytheon.edex.plugin.grib.decoderpostprocessors.OverwriteGribPostProcessor -#MPE-Local grids -MPE-Local:com.raytheon.edex.plugin.grib.decoderpostprocessors.OverwriteGribPostProcessor -MPE-Mosaic:com.raytheon.edex.plugin.grib.decoderpostprocessors.OverwriteGribPostProcessor - -#RTMA grids -RTMA:com.raytheon.edex.plugin.grib.decoderpostprocessors.RTMAGribPostProcessor - -#LAPS grids -LAPS:com.raytheon.edex.plugin.grib.decoderpostprocessors.LapsPostProcessor - -#TPC grids -CPCoutlook211:com.raytheon.edex.plugin.grib.decoderpostprocessors.CPCoutlookGribPostProcessor - -#MSAS grids -MSAS:com.raytheon.edex.plugin.grib.decoderpostprocessors.MSASPostProcessor - -#HPCqpf grids -HPCqpf:com.raytheon.edex.plugin.grib.decoderpostprocessors.OverwriteGribPostProcessor -HPCqpfNDFD:com.raytheon.edex.plugin.grib.decoderpostprocessors.OverwriteGribPostProcessor - -#Canadian GEM grids -Canadian-Reg:com.raytheon.edex.plugin.grib.decoderpostprocessors.CanadianRegPostProcessor -Canadian-NH:com.raytheon.edex.plugin.grib.decoderpostprocessors.CanadianNHPostProcessor - -# RUC236 PostProcessor -RUC236:com.raytheon.edex.plugin.grib.decoderpostprocessors.RUC236GribPostProcessor \ No newline at end of file diff --git a/edexOsgi/com.raytheon.edex.plugin.grib/utility/edex_static/base/grib/postProcessModels/postProcessedModels.xml b/edexOsgi/com.raytheon.edex.plugin.grib/utility/edex_static/base/grib/postProcessModels/postProcessedModels.xml new file mode 100644 index 0000000000..9f76ee1f23 --- /dev/null +++ b/edexOsgi/com.raytheon.edex.plugin.grib/utility/edex_static/base/grib/postProcessModels/postProcessedModels.xml @@ -0,0 +1,125 @@ + + + + + + UKMET[0-9]{2}|ECMF[0-9]{2}|ENSEMBLE[0-9]{2}|AVN[0-9]{2} + + EnsembleGridAssembler + + + + + HPCqpfNDFD + OverwriteGribPostProcessor + + + + RFCqpf + OverwriteGribPostProcessor + + + + HPCqpf + OverwriteGribPostProcessor + + + + MPE-.*|QPE-.* + OverwriteGribPostProcessor + + + + + FFG-[A-Z]{3} + FFGGribPostProcessor + + + + + ETA218 + LiftedIndexPostProcessor + + + + GFS212 + LiftedIndexPostProcessor + + + + GFS213 + GFSProcessor + LiftedIndexPostProcessor + + + + ETA242 + LiftedIndexPostProcessor + + + + + RTMA + RTMAGribPostProcessor + + + + + ECMWF-HiRes + ECMWFHiResProcessor + + + + + MSAS + MSASPostProcessor + + + + + ETA + Nam80PostProcessor + + + + + RUC236 + RUC236GribPostProcessor + + + + + CPCoutlook211 + CPCoutlookGribPostProcessor + + + + + Canadian-NH + CanadianNHPostProcessor + + + + Canadian-Reg + CanadianRegPostProcessor + + + + + LAPS + LapsPostProcessor + + + + + RUC130 + RUC130GribPostProcessor + + + + diff --git a/edexOsgi/com.raytheon.edex.plugin.text/src/com/raytheon/edex/plugin/text/impl/TextSeparatorFactory.java b/edexOsgi/com.raytheon.edex.plugin.text/src/com/raytheon/edex/plugin/text/impl/TextSeparatorFactory.java index 446d8d820f..59e5854cf2 100644 --- a/edexOsgi/com.raytheon.edex.plugin.text/src/com/raytheon/edex/plugin/text/impl/TextSeparatorFactory.java +++ b/edexOsgi/com.raytheon.edex.plugin.text/src/com/raytheon/edex/plugin/text/impl/TextSeparatorFactory.java @@ -19,7 +19,6 @@ **/ package com.raytheon.edex.plugin.text.impl; -import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.logging.Log; @@ -46,6 +45,10 @@ import com.raytheon.uf.edex.wmo.message.WMOHeader; * Aug 12, 2008 jkorman Initial creation * Jul 10, 2009 2191 rjpeter Finished implementation. * 06/29/2012 15154 D. Friedman Fix detection of TAF collectives. + * ====================================== + * AWIPS2 DR Work + * 07/25/2012 959 jkorman Modified order of entry for determining + * the data type (standard or collective) for input data. * * * @author jkorman @@ -193,12 +196,15 @@ public class TextSeparatorFactory { String firstLine = WMOMessageSeparator.getLine(rawData, startIndex); int firstLineLen = firstLine.length(); - if (staticData.matchStdCollective(dataDes) != null) { + + // Maintain this order of entry so that Standard Text products + // are checked before collectives. + if ((stdAfosId = staticData.getProductId(ispanId)) != null) { + msgType = WMOMessageType.STD_TEXT; + } else if (staticData.matchStdCollective(dataDes) != null) { msgType = WMOMessageType.STD_COLLECTIVE; } else if (staticData.matchUACollective(dataDes) != null) { msgType = WMOMessageType.UA_COLLECTIVE; - } else if ((stdAfosId = staticData.getProductId(ispanId)) != null) { - msgType = WMOMessageType.STD_TEXT; } // dataDes/ispanId were not mapped, check hard coded diff --git a/edexOsgi/com.raytheon.uf.common.comm/src/com/raytheon/uf/common/comm/HttpClient.java b/edexOsgi/com.raytheon.uf.common.comm/src/com/raytheon/uf/common/comm/HttpClient.java index 02e07e7cc7..625e0f5f03 100644 --- a/edexOsgi/com.raytheon.uf.common.comm/src/com/raytheon/uf/common/comm/HttpClient.java +++ b/edexOsgi/com.raytheon.uf.common.comm/src/com/raytheon/uf/common/comm/HttpClient.java @@ -283,9 +283,10 @@ public class HttpClient { } int currentCount = ongoing.incrementAndGet(); if (currentCount > getMaxConnectionsPerHost()) { - statusHandler.debug(currentCount + " ongoing http requests to " - + host - + ". Likely waiting for free connection from pool."); + String msg = currentCount + " ongoing http requests to " + host + + ". Likely waiting for free connection from pool."; + statusHandler.debug(msg); + System.out.println(msg); } while (retry) { retry = false; diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.grib/src/com/raytheon/uf/common/dataplugin/grib/util/GribModelLookup.java b/edexOsgi/com.raytheon.uf.common.dataplugin.grib/src/com/raytheon/uf/common/dataplugin/grib/util/GribModelLookup.java index 44aac08506..c664b6a207 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.grib/src/com/raytheon/uf/common/dataplugin/grib/util/GribModelLookup.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.grib/src/com/raytheon/uf/common/dataplugin/grib/util/GribModelLookup.java @@ -21,6 +21,7 @@ package com.raytheon.uf.common.dataplugin.grib.util; import java.util.HashMap; import java.util.Map; +import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -126,6 +127,10 @@ public class GribModelLookup { } } } + + public Set getModelNames(){ + return modelsByName.keySet(); + } private String toKey(Integer center, Integer subcenter, String grid, Integer process) { diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/config/PointSourceConfiguration.java b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/config/PointSourceConfiguration.java index 66bd7c5e4b..fd638e5ce9 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/config/PointSourceConfiguration.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/config/PointSourceConfiguration.java @@ -46,6 +46,9 @@ public class PointSourceConfiguration { @XmlElement private String pointSource; + @XmlElement + private Double geometryDecimationTolerance; + @XmlElement private String pointField; @@ -145,4 +148,13 @@ public class PointSourceConfiguration { this.withinPolygon = withinPolygon; } + public Double getGeometryDecimationTolerance() { + return geometryDecimationTolerance; + } + + public void setGeometryDecimationTolerance( + Double geometryDecimationTolerance) { + this.geometryDecimationTolerance = geometryDecimationTolerance; + } + } diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/gis/GeospatialFactory.java b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/gis/GeospatialFactory.java index 45c65a4930..0b614003f1 100644 --- a/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/gis/GeospatialFactory.java +++ b/edexOsgi/com.raytheon.uf.common.dataplugin.warning/src/com/raytheon/uf/common/dataplugin/warning/gis/GeospatialFactory.java @@ -60,7 +60,7 @@ import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory; * AreaSourceConfiguration to areaFields List. * Apr 11, 2012 #14691 Qinglu Lin For marine warnings, getFeAreaField() returns null. * So, do not add the returned value of getFeAreaField() - * to areaFields. + * to areaFields. * * * @@ -116,7 +116,16 @@ public class GeospatialFactory { GeospatialData[] areas = dataSet.getAreas(); GeospatialData[] parentAreas = dataSet.getParentAreas(); - timezones = dataSet.getTimezones(); + GeospatialData[] myTimeZones = dataSet.getTimezones(); + if (myTimeZones != null && myTimeZones.length > 0) { + if (timezones == null) { + timezones = myTimeZones; + } + + for (GeospatialData tz : myTimeZones) { + tz.prepGeom = PreparedGeometryFactory.prepare(tz.geometry); + } + } Map> uniqueAreasMap = new HashMap>(); for (GeospatialData data : areas) { @@ -254,20 +263,20 @@ public class GeospatialFactory { AreaSourceConfiguration[] ascs = template.getAreaSources(); for (AreaSourceConfiguration asc : ascs) { - List areaFields = new ArrayList(); - String feAreaField = asc.getFeAreaField(); - String timeZoneField = asc.getTimeZoneField(); - areaFields.add(WarningConstants.GID); + List areaFields = new ArrayList(); + String feAreaField = asc.getFeAreaField(); + String timeZoneField = asc.getTimeZoneField(); + areaFields.add(WarningConstants.GID); areaFields.add(asc.getAreaField()); if (feAreaField != null) { - areaFields.add(feAreaField); - } - + areaFields.add(feAreaField); + } + if (timeZoneField != null) { areaFields.add(timeZoneField); } areaFields.add(asc.getFipsField()); - areaFields.add(asc.getAreaNotationField()); + areaFields.add(asc.getAreaNotationField()); GeospatialMetadata gmd = new GeospatialMetadata(); gmd.setAreaSource(asc.getAreaSource()); diff --git a/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/DestinationGeodeticCalculator.java b/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/DestinationGeodeticCalculator.java index 29fc9300d0..72582024e0 100644 --- a/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/DestinationGeodeticCalculator.java +++ b/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/DestinationGeodeticCalculator.java @@ -23,143 +23,144 @@ import org.geotools.referencing.GeodeticCalculator; * @version 1.0 */ public class DestinationGeodeticCalculator { - private static final double MAX_DIST = 20000000; + private static final double MAX_DIST = 20000000; - private double azimuth; + private double azimuth; - private double distance; + private double distance; - private double startLongitude; + private double startLongitude; - private double startLatitude; + private double startLatitude; - private double destLongitude; + private double destLongitude; - private double destLatitude; + private double destLatitude; - private boolean validDistance; + private boolean validDistance; - private boolean validDestination; + private boolean validDestination; - /** - * Set the azimuth and the distance. - * - * @param azimuth - * The azimuth in decimal degrees from -180° to 180°. - * @param distance - * The orthodromic distance in the same units as the ellipsoid - * axis. - * - */ - public void setDirection(double azimuth, double distance) - throws IllegalArgumentException { - this.azimuth = checkAzimuth(azimuth); - this.distance = distance; - validDistance = true; - validDestination = false; - } + private GeodeticCalculator gc = new GeodeticCalculator(); - /** - * Returns the orthodromic distance - */ - public double getOrthodromicDistance() { - if (!validDistance) { - GeodeticCalculator gc = new GeodeticCalculator(); - gc.setStartingGeographicPoint(startLongitude, startLatitude); - gc.setDestinationGeographicPoint(destLongitude, destLatitude); - distance = gc.getOrthodromicDistance(); - } - return distance; - } + /** + * Set the azimuth and the distance. + * + * @param azimuth + * The azimuth in decimal degrees from -180° to 180°. + * @param distance + * The orthodromic distance in the same units as the ellipsoid + * axis. + * + */ + public void setDirection(double azimuth, double distance) + throws IllegalArgumentException { + this.azimuth = checkAzimuth(azimuth); + this.distance = distance; + validDistance = true; + validDestination = false; + } - /** - * Sets starting point - */ - public void setStartingGeographicPoint(double lon, double lat) - throws IllegalArgumentException { - this.startLongitude = checkLongitude(lon); - this.startLatitude = checkLatitude(lat); - } + /** + * Returns the orthodromic distance + */ + public double getOrthodromicDistance() { + if (!validDistance) { + GeodeticCalculator gc = new GeodeticCalculator(); + gc.setStartingGeographicPoint(startLongitude, startLatitude); + gc.setDestinationGeographicPoint(destLongitude, destLatitude); + distance = gc.getOrthodromicDistance(); + } + return distance; + } - /** - * Sets starting point - */ - public void setStartingGeographicPoint(Point2D point) - throws IllegalArgumentException { - setStartingGeographicPoint(point.getX(), point.getY()); - } + /** + * Sets starting point + */ + public void setStartingGeographicPoint(double lon, double lat) + throws IllegalArgumentException { + this.startLongitude = checkLongitude(lon); + this.startLatitude = checkLatitude(lat); + } - /** - * Sets destination point - */ - public void setDestinationGeographicPoint(double lon, double lat) - throws IllegalArgumentException { - this.destLongitude = checkLongitude(lon); - this.destLatitude = checkLatitude(lat); - validDestination = true; - validDistance = false; - } + /** + * Sets starting point + */ + public void setStartingGeographicPoint(Point2D point) + throws IllegalArgumentException { + setStartingGeographicPoint(point.getX(), point.getY()); + } - /** - * Sets destination point - */ - public void setDestinationGeographicPoint(Point2D point) - throws IllegalArgumentException { - setStartingGeographicPoint(point.getX(), point.getY()); - } + /** + * Sets destination point + */ + public void setDestinationGeographicPoint(double lon, double lat) + throws IllegalArgumentException { + this.destLongitude = checkLongitude(lon); + this.destLatitude = checkLatitude(lat); + validDestination = true; + validDistance = false; + } - /** - * Returns the destination point. - */ - public Point2D getDestinationGeographicPoint() { - GeodeticCalculator gc = new GeodeticCalculator(); - gc.setStartingGeographicPoint(startLongitude, startLatitude); + /** + * Sets destination point + */ + public void setDestinationGeographicPoint(Point2D point) + throws IllegalArgumentException { + setStartingGeographicPoint(point.getX(), point.getY()); + } - if (validDestination) { - gc.setDestinationGeographicPoint(destLongitude, destLatitude); - return gc.getDestinationGeographicPoint(); - } + /** + * Returns the destination point. + */ + public Point2D getDestinationGeographicPoint() { + gc.setStartingGeographicPoint(startLongitude, startLatitude); - Point2D referenceGeographicPoint = gc.getStartingGeographicPoint(); - double dist = distance; - while (dist > MAX_DIST) { - gc.setStartingGeographicPoint(referenceGeographicPoint); - gc.setDirection(azimuth, MAX_DIST); - referenceGeographicPoint = gc.getDestinationGeographicPoint(); - dist -= MAX_DIST; - } + if (validDestination) { + gc.setDestinationGeographicPoint(destLongitude, destLatitude); + return gc.getDestinationGeographicPoint(); + } - gc.setStartingGeographicPoint(referenceGeographicPoint); - gc.setDirection(azimuth, dist); + Point2D referenceGeographicPoint = gc.getStartingGeographicPoint(); + double dist = distance; + while (dist > MAX_DIST) { + gc.setStartingGeographicPoint(referenceGeographicPoint); + gc.setDirection(azimuth, MAX_DIST); + referenceGeographicPoint = gc.getDestinationGeographicPoint(); + dist -= MAX_DIST; + } - return gc.getDestinationGeographicPoint(); - } + gc.setStartingGeographicPoint(referenceGeographicPoint); + gc.setDirection(azimuth, dist); - private static double checkLongitude(final double longitude) - throws IllegalArgumentException { - if (longitude >= -180 && longitude <= 180) { - return longitude; - } - throw new IllegalArgumentException("Longitude out of range: " - + longitude + ". Must be between -180 and 180"); - } + return gc.getDestinationGeographicPoint(); + } - private static double checkLatitude(final double latitude) - throws IllegalArgumentException { - if (latitude >= -90 && latitude <= 90) { - return latitude; - } - throw new IllegalArgumentException("Latitude out of range: " + latitude - + ". Must be between -90 and 90"); + private static double checkLongitude(final double longitude) + throws IllegalArgumentException { + if (longitude >= -180 && longitude <= 180) { + return longitude; + } + throw new IllegalArgumentException("Longitude out of range: " + + longitude + ". Must be between -180 and 180"); + } - } + private static double checkLatitude(final double latitude) + throws IllegalArgumentException { + if (latitude >= -90 && latitude <= 90) { + return latitude; + } + throw new IllegalArgumentException("Latitude out of range: " + latitude + + ". Must be between -90 and 90"); - private static double checkAzimuth(final double azimuth) - throws IllegalArgumentException { - if (azimuth >= -180.0 && azimuth <= 180.0) { - return azimuth; - } - throw new IllegalArgumentException("Azimuth out of range: " + azimuth - + ". Must be between -180 and 180"); - } + } + + private static double checkAzimuth(final double azimuth) + throws IllegalArgumentException { + if (azimuth >= -180.0 && azimuth <= 180.0) { + return azimuth; + } + throw new IllegalArgumentException("Azimuth out of range: " + azimuth + + ". Must be between -180 and 180"); + } } diff --git a/edexOsgi/com.raytheon.uf.common.monitor/src/com/raytheon/uf/common/monitor/data/CommonTableConfig.java b/edexOsgi/com.raytheon.uf.common.monitor/src/com/raytheon/uf/common/monitor/data/CommonTableConfig.java index 3bb19e0fee..02993b5dbb 100644 --- a/edexOsgi/com.raytheon.uf.common.monitor/src/com/raytheon/uf/common/monitor/data/CommonTableConfig.java +++ b/edexOsgi/com.raytheon.uf.common.monitor/src/com/raytheon/uf/common/monitor/data/CommonTableConfig.java @@ -184,45 +184,48 @@ public class CommonTableConfig { * Available Observation History columns for SAFESEAS, Snow, Fog. */ public static enum obsHistCols { - Time, WindSpd, MaxWindSpd, WindGust, WindDir, Vis_mi, Vis_mn, P, PTend, SigWaveHgt, SwellHgt, SwellPer, SwellDir, T, Dewpt, SST, WaveSteep, RelHum, Ceiling, DewptDepr + Time, Lat, Lon, WindSpd, MaxWindSpd, WindGust, WindDir, Vis_mi, Vis_mn, P, PTend, SigWaveHgt, SwellHgt, SwellPer, SwellDir, T, Dewpt, SST, WaveSteep, RelHum, Ceiling, DewptDepr }; /** * SAFESEAS Maritime table columns. */ - private final String[] ssMaritimeTableCols = new String[] { - obsHistCols.Time.name(), obsHistCols.WindSpd.name(), - obsHistCols.MaxWindSpd.name(), obsHistCols.WindGust.name(), - obsHistCols.Vis_mn.name(), obsHistCols.P.name(), - obsHistCols.PTend.name(), obsHistCols.T.name(), - obsHistCols.Dewpt.name(), obsHistCols.SST.name(), - obsHistCols.SigWaveHgt.name(), obsHistCols.WaveSteep.name(), - obsHistCols.SwellHgt.name(), obsHistCols.SwellPer.name(), - obsHistCols.SwellDir.name() }; + private final String[] ssMaritimeTableCols = new String[] { + obsHistCols.Time.name(), obsHistCols.Lat.name(), + obsHistCols.Lon.name(), obsHistCols.WindSpd.name(), + obsHistCols.MaxWindSpd.name(), obsHistCols.WindGust.name(), + obsHistCols.Vis_mn.name(), obsHistCols.P.name(), + obsHistCols.PTend.name(), obsHistCols.T.name(), + obsHistCols.Dewpt.name(), obsHistCols.SST.name(), + obsHistCols.SigWaveHgt.name(), obsHistCols.WaveSteep.name(), + obsHistCols.SwellHgt.name(), obsHistCols.SwellPer.name(), + obsHistCols.SwellDir.name() }; - /** - * SAFESEAS METAR table columns. - */ - private final String[] ssMetarTableCols = new String[] { - obsHistCols.Time.name(), obsHistCols.WindDir.name(), - obsHistCols.WindSpd.name(), obsHistCols.WindGust.name(), - obsHistCols.P.name(), obsHistCols.T.name(), - obsHistCols.Dewpt.name(), obsHistCols.PTend.name() }; + /** + * SAFESEAS METAR table columns. + */ + private final String[] ssMetarTableCols = new String[] { + obsHistCols.Time.name(), obsHistCols.Lat.name(), + obsHistCols.Lon.name(), obsHistCols.WindDir.name(), + obsHistCols.WindSpd.name(), obsHistCols.WindGust.name(), + obsHistCols.P.name(), obsHistCols.T.name(), + obsHistCols.Dewpt.name(), obsHistCols.PTend.name() }; - /** - * Snow METAR table columns. - */ - private final String[] snowMetarTableCols = new String[] { - obsHistCols.Time.name(), obsHistCols.WindDir.name(), - obsHistCols.WindSpd.name(), obsHistCols.WindGust.name(), - obsHistCols.P.name(), obsHistCols.T.name(), - obsHistCols.Dewpt.name(), obsHistCols.PTend.name() }; + /** + * Snow METAR table columns. + */ + private final String[] snowMetarTableCols = new String[] { + obsHistCols.Time.name(), obsHistCols.Lat.name(), + obsHistCols.Lon.name(), obsHistCols.WindDir.name(), + obsHistCols.WindSpd.name(), obsHistCols.WindGust.name(), + obsHistCols.P.name(), obsHistCols.T.name(), + obsHistCols.Dewpt.name(), obsHistCols.PTend.name() }; /** * METAR configure names */ private final String[] metarConfigureNames = new String[] { - "Wind Dir (deg)", "Wind Spd (kt)", "Wind Gust (kt)", "P (in)", + "Lat (deg)", "Lon (deg)", "Wind Dir (deg)", "Wind Spd (kt)", "Wind Gust (kt)", "P (in)", "T (deg F)", "Dewpt (deg F)", "P Tendency (in)" }; /** @@ -230,7 +233,7 @@ public class CommonTableConfig { */ private final String[] metarFogConfigureNames = new String[] { - "Rel Hum (%)", "Vis (mi)", "Ceiling (ft x 100)", "Wind Dir (deg)", + "Lat (deg)", "Lon (deg)", "Rel Hum (%)", "Vis (mi)", "Ceiling (ft x 100)", "Wind Dir (deg)", "Wind Spd (kt)", "Wind Gust (kt)", "P (in)", "T (deg F)", "Dewpt (deg F)", "DewptDepr (deg F)", "P Tendency (in)" }; @@ -239,7 +242,7 @@ public class CommonTableConfig { */ private final String[] maritimeFogConfigureNames = new String[] { - "Wind Dir (deg)", "Wind Spd (kt)", "Wind Gust (kt)", "Vis (nm)", + "Lat (deg)", "Lon (deg)", "Wind Dir (deg)", "Wind Spd (kt)", "Wind Gust (kt)", "Vis (nm)", "P (in)", "P Tendency (in)", "T (deg F)", "Dewpt (deg F)", "SST (deg F)", "Significant Wave Hgt (ft)", "Wave Steep", "Swell Hgt (ft)", "Swell Per (sec)", "Swell Dir (deg)", @@ -250,7 +253,7 @@ public class CommonTableConfig { */ private final String[] maritimeSSConfigureNames = new String[] { - "Wind Spd (kt)", "MaxWindSpd (kt)", "Wind Gust (kt)", "Vis (nm)", + "Lat (deg)", "Lon (deg)", "Wind Spd (kt)", "MaxWindSpd (kt)", "Wind Gust (kt)", "Vis (nm)", "P (in)", "P Tendency (in)", "T (deg F)", "Dewpt (deg F)", "SST (deg F)", "Significant Wave Hgt (ft)", "Wave Steep", "Swell Hgt (ft)", "Swell Per (sec)", "Swell Dir (deg)" }; @@ -258,21 +261,23 @@ public class CommonTableConfig { /** * Fog Maritime table columns. */ - private final String[] fogMaritimeTableCols = new String[] { - obsHistCols.Time.name(), obsHistCols.WindSpd.name(), - obsHistCols.MaxWindSpd.name(), obsHistCols.WindGust.name(), - obsHistCols.Vis_mi.name(), obsHistCols.P.name(), - obsHistCols.PTend.name(), obsHistCols.T.name(), - obsHistCols.Dewpt.name(), obsHistCols.SST.name(), - obsHistCols.SigWaveHgt.name(), obsHistCols.WaveSteep.name(), - obsHistCols.SwellHgt.name(), obsHistCols.SwellPer.name(), - obsHistCols.SwellDir.name(), obsHistCols.RelHum.name() }; + private final String[] fogMaritimeTableCols = new String[] { + obsHistCols.Time.name(), obsHistCols.Lat.name(), + obsHistCols.Lon.name(), obsHistCols.WindSpd.name(), + obsHistCols.MaxWindSpd.name(), obsHistCols.WindGust.name(), + obsHistCols.Vis_mi.name(), obsHistCols.P.name(), + obsHistCols.PTend.name(), obsHistCols.T.name(), + obsHistCols.Dewpt.name(), obsHistCols.SST.name(), + obsHistCols.SigWaveHgt.name(), obsHistCols.WaveSteep.name(), + obsHistCols.SwellHgt.name(), obsHistCols.SwellPer.name(), + obsHistCols.SwellDir.name(), obsHistCols.RelHum.name() }; /** * Fog METAR table columns. */ private final String[] fogMetarTableCols = new String[] { - obsHistCols.Time.name(), obsHistCols.RelHum.name(), + obsHistCols.Time.name(), obsHistCols.Lat.name(), + obsHistCols.Lon.name(),obsHistCols.RelHum.name(), obsHistCols.Vis_mi.name(), obsHistCols.Ceiling.name(), obsHistCols.WindDir.name(), obsHistCols.WindSpd.name(), obsHistCols.WindGust.name(), obsHistCols.P.name(), @@ -493,56 +498,60 @@ public class CommonTableConfig { SortDirection.Decending, GraphType.None)); } - /** - * Create the Observation History column attributes. - */ - private void createObsHistoryColumnAttributes() { - obsHistColumnAttrMap.put(obsHistCols.Time.name(), new ColumnAttribData( - "Time (UTC)", "Time (UTC)")); - obsHistColumnAttrMap.put(obsHistCols.WindSpd.name(), - new ColumnAttribData("Wind Spd (kt)", "Wind Spd\n(kt)")); - obsHistColumnAttrMap - .put(obsHistCols.MaxWindSpd.name(), new ColumnAttribData( - "Max Wind Spd (kt)", "Max Wind\nSpd (kt)")); - obsHistColumnAttrMap.put(obsHistCols.WindGust.name(), - new ColumnAttribData("Wind Gust (kt)", "Wind Gust\n(kt)")); - obsHistColumnAttrMap.put(obsHistCols.WindDir.name(), - new ColumnAttribData("Wind Dir (deg)", "Wind Dir\n(deg)")); - obsHistColumnAttrMap.put(obsHistCols.Vis_mi.name(), - new ColumnAttribData("Vis (mi)", "Vis (mi)")); - obsHistColumnAttrMap.put(obsHistCols.Vis_mn.name(), - new ColumnAttribData("Vis (nm)", "Vis (nm)")); - obsHistColumnAttrMap.put(obsHistCols.P.name(), new ColumnAttribData( - "P (in)", "P (in)")); - obsHistColumnAttrMap.put(obsHistCols.PTend.name(), - new ColumnAttribData("P Tendency (in)", "P Tendency\n(in)")); - obsHistColumnAttrMap.put(obsHistCols.SigWaveHgt.name(), - new ColumnAttribData("Significant Wave Hgt (ft)", - "Significant\nWave Hgt (ft)")); - obsHistColumnAttrMap.put(obsHistCols.SwellHgt.name(), - new ColumnAttribData("Swell Hgt (ft)", "Swell Hgt\n(ft)")); - obsHistColumnAttrMap.put(obsHistCols.SwellPer.name(), - new ColumnAttribData("Swell Per (sec)", "Swell Per\n(sec)")); - obsHistColumnAttrMap.put(obsHistCols.SwellDir.name(), - new ColumnAttribData("Swell Dir (deg)", "Swell Dir\n(deg)")); - obsHistColumnAttrMap.put(obsHistCols.T.name(), new ColumnAttribData( - "T (deg F)", "T (deg F)")); - obsHistColumnAttrMap.put(obsHistCols.Dewpt.name(), - new ColumnAttribData("Dewpt (deg F)", "Dewpt\n(deg F)")); - obsHistColumnAttrMap.put(obsHistCols.SST.name(), new ColumnAttribData( - "SST (deg F)", "SST\n(deg F)")); - obsHistColumnAttrMap.put(obsHistCols.WaveSteep.name(), - new ColumnAttribData("Wave Steep", "Wave\nSteep")); - obsHistColumnAttrMap.put(obsHistCols.RelHum.name(), - new ColumnAttribData("Rel. Humid (%)", "Rel. Humid\n(%)")); - obsHistColumnAttrMap.put(obsHistCols.Ceiling.name(), - new ColumnAttribData("Ceiling (ft x 100)", - "Ceiling\n(ft x 100)")); - obsHistColumnAttrMap - .put(obsHistCols.DewptDepr.name(), new ColumnAttribData( - "DewptDepr (deg F)", "DewptDepr\n(deg F)")); + /** + * Create the Observation History column attributes. + */ + private void createObsHistoryColumnAttributes() { + obsHistColumnAttrMap.put(obsHistCols.Time.name(), new ColumnAttribData( + "Time (UTC)", "Time (UTC)")); + obsHistColumnAttrMap.put(obsHistCols.Lat.name(), new ColumnAttribData( + "Lat (deg)", "Lat (deg)")); + obsHistColumnAttrMap.put(obsHistCols.Lon.name(), new ColumnAttribData( + "Lon (deg)", "Lon (deg)")); + obsHistColumnAttrMap.put(obsHistCols.WindSpd.name(), + new ColumnAttribData("Wind Spd (kt)", "Wind Spd\n(kt)")); + obsHistColumnAttrMap + .put(obsHistCols.MaxWindSpd.name(), new ColumnAttribData( + "Max Wind Spd (kt)", "Max Wind\nSpd (kt)")); + obsHistColumnAttrMap.put(obsHistCols.WindGust.name(), + new ColumnAttribData("Wind Gust (kt)", "Wind Gust\n(kt)")); + obsHistColumnAttrMap.put(obsHistCols.WindDir.name(), + new ColumnAttribData("Wind Dir (deg)", "Wind Dir\n(deg)")); + obsHistColumnAttrMap.put(obsHistCols.Vis_mi.name(), + new ColumnAttribData("Vis (mi)", "Vis (mi)")); + obsHistColumnAttrMap.put(obsHistCols.Vis_mn.name(), + new ColumnAttribData("Vis (nm)", "Vis (nm)")); + obsHistColumnAttrMap.put(obsHistCols.P.name(), new ColumnAttribData( + "P (in)", "P (in)")); + obsHistColumnAttrMap.put(obsHistCols.PTend.name(), + new ColumnAttribData("P Tendency (in)", "P Tendency\n(in)")); + obsHistColumnAttrMap.put(obsHistCols.SigWaveHgt.name(), + new ColumnAttribData("Significant Wave Hgt (ft)", + "Significant\nWave Hgt (ft)")); + obsHistColumnAttrMap.put(obsHistCols.SwellHgt.name(), + new ColumnAttribData("Swell Hgt (ft)", "Swell Hgt\n(ft)")); + obsHistColumnAttrMap.put(obsHistCols.SwellPer.name(), + new ColumnAttribData("Swell Per (sec)", "Swell Per\n(sec)")); + obsHistColumnAttrMap.put(obsHistCols.SwellDir.name(), + new ColumnAttribData("Swell Dir (deg)", "Swell Dir\n(deg)")); + obsHistColumnAttrMap.put(obsHistCols.T.name(), new ColumnAttribData( + "T (deg F)", "T (deg F)")); + obsHistColumnAttrMap.put(obsHistCols.Dewpt.name(), + new ColumnAttribData("Dewpt (deg F)", "Dewpt\n(deg F)")); + obsHistColumnAttrMap.put(obsHistCols.SST.name(), new ColumnAttribData( + "SST (deg F)", "SST\n(deg F)")); + obsHistColumnAttrMap.put(obsHistCols.WaveSteep.name(), + new ColumnAttribData("Wave Steep", "Wave\nSteep")); + obsHistColumnAttrMap.put(obsHistCols.RelHum.name(), + new ColumnAttribData("Rel. Humid (%)", "Rel. Humid\n(%)")); + obsHistColumnAttrMap.put(obsHistCols.Ceiling.name(), + new ColumnAttribData("Ceiling (ft x 100)", + "Ceiling\n(ft x 100)")); + obsHistColumnAttrMap + .put(obsHistCols.DewptDepr.name(), new ColumnAttribData( + "DewptDepr (deg F)", "DewptDepr\n(deg F)")); - } + } /** * Get the Zone/Station column keys. diff --git a/edexOsgi/com.raytheon.uf.common.serialization.comm/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.serialization.comm/META-INF/MANIFEST.MF index 6902fed3de..4bdb30baf4 100644 --- a/edexOsgi/com.raytheon.uf.common.serialization.comm/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.common.serialization.comm/META-INF/MANIFEST.MF @@ -13,3 +13,4 @@ Export-Package: com.raytheon.uf.common.serialization.comm, Require-Bundle: com.raytheon.uf.common.serialization;bundle-version="1.11.12", net.sf.cglib;bundle-version="2.1.3", com.raytheon.uf.common.status +Import-Package: com.raytheon.uf.common.message diff --git a/edexOsgi/com.raytheon.uf.common.serialization.comm/src/com/raytheon/uf/common/serialization/comm/RequestWrapper.java b/edexOsgi/com.raytheon.uf.common.serialization.comm/src/com/raytheon/uf/common/serialization/comm/RequestWrapper.java new file mode 100644 index 0000000000..79c958486c --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.serialization.comm/src/com/raytheon/uf/common/serialization/comm/RequestWrapper.java @@ -0,0 +1,101 @@ +/** + * 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.serialization.comm; + +import com.raytheon.uf.common.message.WsId; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * Wraps an IServerRequest so it can be tracked on both client applications and + * the server. Contains a unique identifier for this particular request and a + * workstation ID which has the network address and process id. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 24, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +@DynamicSerialize +public class RequestWrapper { + + @DynamicSerializeElement + private IServerRequest request; + + @DynamicSerializeElement + private WsId wsId; + + @DynamicSerializeElement + private String uniqueId; + + public RequestWrapper() { + + } + + public RequestWrapper(IServerRequest request, WsId workstationId, + String uniqueId) { + this.request = request; + this.wsId = workstationId; + this.uniqueId = uniqueId; + } + + public IServerRequest getRequest() { + return request; + } + + public void setRequest(IServerRequest request) { + this.request = request; + } + + public WsId getWsId() { + return wsId; + } + + public void setWsId(WsId wsId) { + this.wsId = wsId; + } + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(125); + sb.append("Request[").append(wsId.toPrettyString()).append("][") + .append(uniqueId).append("] ") + .append(request.getClass().getSimpleName()); + return sb.toString(); + } + +} diff --git a/edexOsgi/com.raytheon.uf.common.util/src/com/raytheon/uf/common/util/SizeUtil.java b/edexOsgi/com.raytheon.uf.common.util/src/com/raytheon/uf/common/util/SizeUtil.java new file mode 100644 index 0000000000..e0e7eeaa3b --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.util/src/com/raytheon/uf/common/util/SizeUtil.java @@ -0,0 +1,69 @@ +/** + * 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.util; + +/** + * Utilities for calculating the size of objects + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 24, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +public class SizeUtil { + + private static final int BYTES_PER = 1024; + + private static final String[] REP_PREFIX = new String[] { "B", "kB", "MB", + "GB", "TB", "PB", "EB", "ZB", "YB" }; + + /** + * Transforms a number of bytes to a pretty string based on the total number + * of bytes, e.g. B, kB, MB, or GB as fitting. For example: 1000 -> 1000B, + * 10000 -> 9.7kB, 100000 -> 97.6kB, 1000000 -> 976.5kB, 10000000 -> 9.5MB + * + * @param numberOfBytes + * the number to transform to a pretty string + * @return the pretty String representation of the byte size + */ + public static String prettyByteSize(long numberOfBytes) { + float n = (float) numberOfBytes; + int reps = 0; + while (n > BYTES_PER && reps < REP_PREFIX.length - 1) { + reps++; + n /= BYTES_PER; + } + int tenth = ((int) (n * 10)) % 10; + StringBuilder sb = new StringBuilder(); + sb.append((int) n).append(".").append(tenth); + sb.append(REP_PREFIX[reps]); + return sb.toString(); + } + +} diff --git a/edexOsgi/com.raytheon.uf.edex.auth/src/com/raytheon/uf/edex/auth/RemoteRequestRouteWrapper.java b/edexOsgi/com.raytheon.uf.edex.auth/src/com/raytheon/uf/edex/auth/RemoteRequestRouteWrapper.java index a8464e8833..832be233f8 100644 --- a/edexOsgi/com.raytheon.uf.edex.auth/src/com/raytheon/uf/edex/auth/RemoteRequestRouteWrapper.java +++ b/edexOsgi/com.raytheon.uf.edex.auth/src/com/raytheon/uf/edex/auth/RemoteRequestRouteWrapper.java @@ -19,20 +19,17 @@ **/ package com.raytheon.uf.edex.auth; -import java.text.DecimalFormat; - import com.raytheon.uf.common.auth.AuthException; import com.raytheon.uf.common.auth.resp.AuthServerErrorResponse; import com.raytheon.uf.common.serialization.SerializationException; import com.raytheon.uf.common.serialization.SerializationUtil; import com.raytheon.uf.common.serialization.comm.IServerRequest; +import com.raytheon.uf.common.serialization.comm.RequestWrapper; import com.raytheon.uf.common.serialization.comm.response.ServerErrorResponse; import com.raytheon.uf.common.serialization.comm.util.ExceptionWrapper; 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.props.EnvProperties; -import com.raytheon.uf.edex.core.props.PropertiesFactory; +import com.raytheon.uf.common.util.SizeUtil; /** * Wrapper for camel route so Serialization exceptions can be caught and @@ -44,6 +41,7 @@ import com.raytheon.uf.edex.core.props.PropertiesFactory; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Aug 10, 2009 mschenke Initial creation + * Jul 24, 2012 njensen Enhanced logging * * * @@ -52,62 +50,33 @@ import com.raytheon.uf.edex.core.props.PropertiesFactory; */ public class RemoteRequestRouteWrapper { - private static final transient IUFStatusHandler statusHandler = UFStatus - .getHandler(RemoteRequestRouteWrapper.class); + + private static final IUFStatusHandler thriftSrvLogger = UFStatus + .getNamedHandler("ThriftSrvRequestLogger"); private RemoteRequestServer server; - private static final int MEGABYTE = 1024 * 1024; - - private static final int timeLogLevel; - - private static final long sizeLogLevel; - - static { - EnvProperties props = PropertiesFactory.getInstance() - .getEnvProperties(); - int tmp = 0; - String prop = props.getEnvValue("REQUEST_TIME_FILTER"); - if (prop != null) { - try { - tmp = Integer.parseInt(prop); - } catch (NumberFormatException e) { - - } - } - timeLogLevel = (tmp <= 0 ? Integer.MAX_VALUE : tmp); - - tmp = 0; - prop = props.getEnvValue("RESPONSE_SIZE_FILTER"); - if (prop != null) { - try { - tmp = Integer.parseInt(prop) * MEGABYTE; - } catch (NumberFormatException e) { - - } - } - sizeLogLevel = (tmp <= 0 ? Integer.MAX_VALUE : tmp); - } - public byte[] executeThrift(byte[] data) { try { long startTime = System.currentTimeMillis(); Object obj = SerializationUtil.transformFromThrift(data); - Object rvalObj = server.handleThriftRequest((IServerRequest) obj); + IServerRequest request = null; + if (obj instanceof RequestWrapper) { + request = ((RequestWrapper) obj).getRequest(); + } else { + request = (IServerRequest) obj; + } + Object rvalObj = server.handleThriftRequest(request); byte[] rval = SerializationUtil.transformToThrift(rvalObj); long endTime = System.currentTimeMillis(); - if (rval.length > sizeLogLevel - || (endTime - startTime) > timeLogLevel) { - DecimalFormat df = new DecimalFormat("0.##"); - statusHandler.handle( - Priority.INFO, - "Request " + obj + " took " + (endTime - startTime) - + "ms, request was size " - + df.format((double) data.length / 1024) - + "kb, and has response size " - + df.format(((double) rval.length / MEGABYTE)) - + "mb"); - } + StringBuilder sb = new StringBuilder(300); + sb.append("Handled ").append(obj.toString()).append(" in ") + .append((endTime - startTime)).append("ms, "); + sb.append("request was size ").append( + SizeUtil.prettyByteSize(data.length)); + sb.append(", response was size ").append( + SizeUtil.prettyByteSize(rval.length)); + thriftSrvLogger.info(sb.toString()); return rval; } catch (AuthException e) { AuthServerErrorResponse resp = new AuthServerErrorResponse(); diff --git a/edexOsgi/com.raytheon.uf.edex.auth/src/com/raytheon/uf/edex/auth/RemoteRequestServer.java b/edexOsgi/com.raytheon.uf.edex.auth/src/com/raytheon/uf/edex/auth/RemoteRequestServer.java index 0d3b4c0f25..d735acef38 100644 --- a/edexOsgi/com.raytheon.uf.edex.auth/src/com/raytheon/uf/edex/auth/RemoteRequestServer.java +++ b/edexOsgi/com.raytheon.uf.edex.auth/src/com/raytheon/uf/edex/auth/RemoteRequestServer.java @@ -44,6 +44,7 @@ import com.raytheon.uf.edex.auth.resp.ResponseFactory; * ------------ ---------- ----------- -------------------------- * Aug 3, 2009 mschenke Initial creation * + * * * * @author mschenke @@ -54,8 +55,6 @@ public class RemoteRequestServer { private static final transient IUFStatusHandler statusHandler = UFStatus .getHandler(RemoteRequestServer.class); - private static final long LOG_TIME_THRESHOLD = 200; // milliseconds - private static final RemoteRequestServer instance = new RemoteRequestServer(); private HandlerRegistry registry; @@ -131,16 +130,7 @@ public class RemoteRequestServer { } } - long t0 = System.currentTimeMillis(); - String requestAsString = request.toString(); - Object response = handler.handleRequest(request); - long t1 = System.currentTimeMillis(); - long diff = t1 - t0; - if (diff > LOG_TIME_THRESHOLD) { - statusHandler.info("Handled " + requestAsString + " in " + diff - + "ms"); - } - return response; + return handler.handleRequest(request); } public void setRegistry(HandlerRegistry registry) { diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.nwsauth/utility/edex_static/base/roles/userRoles.xml b/edexOsgi/com.raytheon.uf.edex.plugin.nwsauth/utility/edex_static/base/roles/userRoles.xml index 910eab1ac4..c4a9488fad 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.nwsauth/utility/edex_static/base/roles/userRoles.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.nwsauth/utility/edex_static/base/roles/userRoles.xml @@ -133,6 +133,16 @@ + + diff --git a/edexOsgi/com.raytheon.uf.tools.gfesuite.servicebackup/svcBackup/ServiceBackup/configuration/svcbu.properties b/edexOsgi/com.raytheon.uf.tools.gfesuite.servicebackup/svcBackup/ServiceBackup/configuration/svcbu.properties index d3d412f86f..2405687e6d 100644 --- a/edexOsgi/com.raytheon.uf.tools.gfesuite.servicebackup/svcBackup/ServiceBackup/configuration/svcbu.properties +++ b/edexOsgi/com.raytheon.uf.tools.gfesuite.servicebackup/svcBackup/ServiceBackup/configuration/svcbu.properties @@ -114,14 +114,14 @@ LOCK_DIR=${GFESUITE_HOME}/ServiceBackup/locks SCRIPTS_DIR=${GFESUITE_HOME}/ServiceBackup/scripts CAVE_LAUNCH_SCRIPT=${AWIPS_HOME}/cave/cave.sh -SVCBU_HOST=localhost +SVCBU_HOST=ec MSG_SEND_COMMAND=msg_send CDSPORT=9581 SVCBU_DB=Official SVCBU_TRIM_ELEMS=1 SVCBU_FAILED_SITE_PORT=98000001 SVCBU_GRIDAREA=ISC_Send_Area -SVCBU_ADDRESSEE=TNCF +SVCBU_ADDRESSEE="ANCF,BNCF" SVCBU_WMO_HEADER=SVCBKPIFP SVCBU_USER=0 SVCBU_USER_ID="" diff --git a/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/src/ifpservertext/ifpServerText.py b/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/src/ifpservertext/ifpServerText.py index d3924bae35..9c53af54f7 100644 --- a/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/src/ifpservertext/ifpServerText.py +++ b/edexOsgi/com.raytheon.uf.tools.gfesuite/cli/src/ifpservertext/ifpServerText.py @@ -72,26 +72,18 @@ class textInventoryRecord: return str(self.localCtx) + self.path + "/" + self.fileName ## Logging methods ## +logger = None def __initLogger(): - logger = logging.getLogger("ifpServerText.py") - logger.setLevel(logging.INFO) + global logger + logger = logging.getLogger("purgeAllModelData") + logger.setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setLevel(logging.INFO) + # Uncomment line below to enable debug-level logging + # ch.setLevel(logging.DEBUG) formatter = logging.Formatter("%(asctime)s %(name)s %(levelname)s: %(message)s", "%H:%M:%S") ch.setFormatter(formatter) logger.addHandler(ch) - -def logEvent(msg): - logging.getLogger("ifpServerText.py").info(msg) - -def logProblem(msg): - logging.getLogger("ifpServerText.py").error(msg) - -def logException(msg): - logging.getLogger("ifpServerText.py").exception(msg) - -def logVerbose(msg): - logging.getLogger("ifpServerText.py").debug(msg) class ifpServerText: @@ -110,7 +102,9 @@ class ifpServerText: "TextProduct": ".py", "TextUtility": ".py", "Utility": ".py", - "Combinations": ".py"} + "Combinations": ".py", + "ISCUtility": ".py" + } LOCALIZATION_DICT = {"Config": ("CAVE_STATIC", "gfe/userPython/gfeConfig"), "EditArea": ("COMMON_STATIC", "gfe/editAreas"), @@ -124,7 +118,9 @@ class ifpServerText: "TextProduct": ("CAVE_STATIC", "gfe/userPython/textProducts"), "TextUtility": ("CAVE_STATIC", "gfe/userPython/textUtilities/regular"), "Utility": ("CAVE_STATIC", "gfe/userPython/utilities"), - "Combinations": ("CAVE_STATIC", "gfe/combinations")} + "Combinations": ("CAVE_STATIC", "gfe/combinations"), + "ISCUtility": ("COMMON_STATIC", "isc/utilities") + } def __init__(self): self.__host = None @@ -237,7 +233,7 @@ class ifpServerText: options = ["Tool", "Procedure", "Utility", "TextUtility", "TextProduct", "Config", "EditArea", "SelectTR", "EditAreaGroup", "SampleSet", "WeatherElementGroup", - "ColorTable", "Combinations", "SmartTool"] + "ColorTable", "Combinations", "SmartTool", "ISCUtility"] if opt[1] not in options: self.__usage() s = "Error: Illegal class specified " + opt[1] @@ -254,7 +250,7 @@ class ifpServerText: "SelectTR": "SELECTTR", "Tool": "Tool", "Procedure": "Procedure", "TextProduct": "TextProduct", "TextUtility": "TextUtility", "Utility": "Utility", - "Combinations": "COMBINATIONS"} + "Combinations": "COMBINATIONS", "ISCUtility": "ISCUtility"} self.__textCategory = dic[self.__classType] elif opt[0] == '-s': if self.__mode is not None: @@ -501,7 +497,7 @@ Usage: ifpServerText -h hostname -p rpcPortNumber -o siteID [-u user] except Exception, e: raise RuntimeError("Could not send file to localization server: " + str(e)) - logEvent("Saved file " + self.__filename + " under " + self.__name) + logger.info("Saved file " + self.__filename + " under " + self.__name) def __deleteText(self): #Deletes a text file @@ -546,7 +542,7 @@ Usage: ifpServerText -h hostname -p rpcPortNumber -o siteID [-u user] except Exception, e: raise RuntimeError("Could not delete file from localization server: " + str(e)) - logEvent("Deleted " + self.__name) + logger.info("Deleted " + self.__name) def __getText(self): #Gets the text file @@ -591,7 +587,7 @@ Usage: ifpServerText -h hostname -p rpcPortNumber -o siteID [-u user] f = open(self.__filename, 'w', 0644) f.write(txt) f.close() - logEvent("Got " + self.__name + " --- written to " + self.__filename) + logger.info("Got " + self.__name + " --- written to " + self.__filename) def __inventoryText(self): #Returns the inventory @@ -759,21 +755,21 @@ Usage: ifpServerText -h hostname -p rpcPortNumber -o siteID [-u user] f = open(self.__filename, 'w', 0644) f.write(txt) f.close() - logEvent("Got MetaInfo " + self.__metaInfo + " --- written to " + self.__filename) + logger.info("Got MetaInfo " + self.__metaInfo + " --- written to " + self.__filename) def main(): __initLogger() - logEvent("ifpServerText Starting") + logger.info("ifpServerText Starting") try: obj = ifpServerText() obj.process() except Exception, e: - logException("Error encountered running ifpServerText:") + logger.exception("Error encountered running ifpServerText:") sys.exit(1) - logEvent("ifpServerText Finished") + logger.info("ifpServerText Finished") sys.exit(0) diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncuair/META-INF/MANIFEST.MF b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncuair/META-INF/MANIFEST.MF index 3f5d50b99d..9e03f7165b 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.ncuair/META-INF/MANIFEST.MF +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.ncuair/META-INF/MANIFEST.MF @@ -22,5 +22,4 @@ Export-Package: gov.noaa.nws.ncep.common.dataplugin.ncuair, Import-Package: com.raytheon.uf.common.pointdata, com.raytheon.uf.edex.pointdata, com.raytheon.uf.common.pointdata.spatial, - gov.noaa.flddb, com.vividsolutions.jts.geom diff --git a/rpms/awips2.cave/setup/scripts/prepare_dist.sh b/rpms/awips2.cave/setup/scripts/prepare_dist.sh index a29e6f1756..8f1208c1cd 100644 --- a/rpms/awips2.cave/setup/scripts/prepare_dist.sh +++ b/rpms/awips2.cave/setup/scripts/prepare_dist.sh @@ -66,7 +66,7 @@ fi # Execute the P2 Repo PDE Build. # The Sun JDK Build. -time ant -f p2-build.xml -Dbuild.version=${BUILD_VERSION} \ +time /awips2/ant/bin/ant -f p2-build.xml -Dbuild.version=${BUILD_VERSION} \ -Dbuild.arch=${CAVE_BUILD_ARCH} RC=$? diff --git a/rpms/awips2.core/Installer.rcm/component.spec b/rpms/awips2.core/Installer.rcm/component.spec index 7f95784693..8bece00fb9 100644 --- a/rpms/awips2.core/Installer.rcm/component.spec +++ b/rpms/awips2.core/Installer.rcm/component.spec @@ -68,7 +68,7 @@ RCM_PROPS_DIR="build.rcm/pdeprops" DEPLOY_SCRIPT="build.rcm/build.xml" # Deploy Radar Server To Our Temporary Build Directory. -ant -file ${WORKSPACE_DIR}/${DEPLOY_SCRIPT} \ +/awips2/ant/bin/ant -file ${WORKSPACE_DIR}/${DEPLOY_SCRIPT} \ -Ddeploy.dir=${RPM_BUILD_ROOT}/awips2/rcm \ -Dinstaller=true -Dprops.dir=${WORKSPACE_DIR}/${RCM_PROPS_DIR} @@ -148,4 +148,4 @@ rm -rf ${RPM_BUILD_ROOT} %dir /awips2/rcm/lib /awips2/rcm/lib/* -%attr(744,root,root) /etc/init.d/edex_rcm \ No newline at end of file +%attr(744,root,root) /etc/init.d/edex_rcm diff --git a/rpms/awips2.edex/deploy.builder/build.sh b/rpms/awips2.edex/deploy.builder/build.sh index 94cad246e2..547a79ee95 100644 --- a/rpms/awips2.edex/deploy.builder/build.sh +++ b/rpms/awips2.edex/deploy.builder/build.sh @@ -112,4 +112,5 @@ buildRPM "Installer.edex-satellite" buildRPM "Installer.edex-text" buildRPM "Installer.edex-native" buildRPM "Installer.edex-shapefiles" +buildRPM "Installer.edex-ost" #buildRPM "Installer.edex-npp" diff --git a/tools/scripts/commit-msg b/tools/scripts/commit-msg new file mode 100644 index 0000000000..65ddbda5e3 --- /dev/null +++ b/tools/scripts/commit-msg @@ -0,0 +1,104 @@ +#!/bin/sh +# From Gerrit Code Review 2.1.6.1 +# +# Part of Gerrit Code Review (http://code.google.com/p/gerrit/) +# +# Copyright (C) 2009 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +CHANGE_ID_AFTER="Bug|Issue" +MSG="$1" + +# Check for, and add if missing, a unique Change-Id +# +add_ChangeId() { + clean_message=$(sed -e ' + /^diff --git a\/.*/{ + s/// + q + } + /^Signed-off-by:/d + /^#/d + ' "$MSG" | git stripspace) + if test -z "$clean_message" + then + return + fi + + if grep -i '^Change-Id:' "$MSG" >/dev/null + then + return + fi + + id=$(_gen_ChangeId) + perl -e ' + $MSG = shift; + $id = shift; + $CHANGE_ID_AFTER = shift; + + undef $/; + open(I, $MSG); $_ = ; close I; + s|^diff --git a/.*||ms; + s|^#.*$||mg; + exit unless $_; + + @message = split /\n/; + $haveFooter = 0; + $startFooter = @message; + for($line = @message - 1; $line >= 0; $line--) { + $_ = $message[$line]; + + if (/^[a-zA-Z0-9-]+:/ && !m,^[a-z0-9-]+://,) { + $haveFooter++; + next; + } + next if /^[ []/; + $startFooter = $line if ($haveFooter && /^\r?$/); + last; + } + + @footer = @message[$startFooter+1..@message]; + @message = @message[0..$startFooter]; + push(@footer, "") unless @footer; + + for ($line = 0; $line < @footer; $line++) { + $_ = $footer[$line]; + next if /^($CHANGE_ID_AFTER):/i; + last; + } + splice(@footer, $line, 0, "Change-Id: I$id"); + + $_ = join("\n", @message, @footer); + open(O, ">$MSG"); print O; close O; + ' "$MSG" "$id" "$CHANGE_ID_AFTER" +} +_gen_ChangeIdInput() { + echo "tree $(git write-tree)" + if parent=$(git rev-parse HEAD^0 2>/dev/null) + then + echo "parent $parent" + fi + echo "author $(git var GIT_AUTHOR_IDENT)" + echo "committer $(git var GIT_COMMITTER_IDENT)" + echo + printf '%s' "$clean_message" +} +_gen_ChangeId() { + _gen_ChangeIdInput | + git hash-object -t commit --stdin +} + + +add_ChangeId diff --git a/tools/scripts/git-u-setup b/tools/scripts/git-u-setup new file mode 100644 index 0000000000..b209c712eb --- /dev/null +++ b/tools/scripts/git-u-setup @@ -0,0 +1,58 @@ +#!/bin/bash + +# +# where am I? +# +PWD=`pwd` + +# +# where is this script? +# +MY_PATH=`dirname $0` + +# +# Figure out repository path +# +if [ $MY_PATH == "." ]; then + GIT_REPO_DIR=`dirname $PWD` + GIT_REPO_DIR=`dirname $GIT_REPO_DIR` +elif [ $MY_PATH == "tools/scripts" ]; then + GIT_REPO_DIR=$PWD +else + cd $MY_PATH + cd ../../ + GIT_REPO_DIR=`pwd` +fi + +# +# Is this a Gerrit clone? +# +grep "lightning.omaha.us.ray.com:29418" ${GIT_REPO_DIR}/.git/config >/dev/null 2>&1 +if [ "$?" == "0" ]; then + GERRIT_CLONE=1 +else + GERRIT_CLONE=0 +fi + +# +# Disclaimer / preface / continue prompt +# +echo " " +echo "This script will:" +if [ "$GERRIT_CLONE" == "1" ]; then + echo " Copy the Gerrit commit-msg (for inserting the change-id) hook to your repository hooks directory " +else + echo " Do nothing since this repository is not a Gerrit clone" +fi +echo " " +read -p "Press [Enter] key to continue (ctrl-c to quit).." + + + +if [ "$GERRIT_CLONE" == "1" ]; then + # cp change id hook + echo "Copying Gerrit commit-msg hook to ${GIT_REPO_DIR}/.git/hooks .." + cp ${GIT_REPO_DIR}/tools/scripts/commit-msg ${GIT_REPO_DIR}/.git/hooks +else + echo "Doing nothing .." +fi