Manual merge of SS OB12.1.2-4 changes into ss_sync

Former-commit-id: c209d6de36 [formerly 93f6535bd8] [formerly b137302802 [formerly 0ccca40d35e50072218a1da1db474075f8ad0393]]
Former-commit-id: b137302802
Former-commit-id: 65b22abd24
This commit is contained in:
Steve Harris 2012-02-17 10:55:02 -06:00
parent 98b223d08e
commit 1ac6b36d1f
55 changed files with 3052 additions and 1559 deletions

View file

@ -1,4 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
Update:
12/26/2011 Xiaochuan DR14236 (trac 11710) request to fix SCAN Alert Visualization BASE
configuring file. Changed true or false setting on popup, text,
blink and color items followed the A1 configuring master.gcf file.
-->
<alertConfiguration name="DEFAULT"> <alertConfiguration name="DEFAULT">
<globalConfiguration height="37" width="-1" yPosition="-1" xPosition="-1" logLength="10" audioDuration="30" blinkDuration="5" expandedPopup="false" categoryShown="false" sourceKeyShown="false" priorityShown="false" mode="H2"/> <globalConfiguration height="37" width="-1" yPosition="-1" xPosition="-1" logLength="10" audioDuration="30" blinkDuration="5" expandedPopup="false" categoryShown="false" sourceKeyShown="false" priorityShown="false" mode="H2"/>
<category textBox="1" categoryName="FRCST" longName="Forecast Related" locked="true"/> <category textBox="1" categoryName="FRCST" longName="Forecast Related" locked="true"/>
@ -273,11 +280,11 @@
</source> </source>
<source locked="true" name="SCAN" longName="Scan default"> <source locked="true" name="SCAN" longName="Scan default">
<configurationItem forced="false"> <configurationItem forced="false">
<metadata foreground="#000000" background="#00ff00" pythonEnabled="false" log="false" priority="EVENTA" popup="false" blink="false" text="false" audioEnabled="false"/> <metadata foreground="#000000" background="#008000" pythonEnabled="false" log="false" priority="EVENTA" popup="false" blink="false" text="false" audioEnabled="false"/>
<metadata foreground="#ffffff" background="#ff0000" pythonEnabled="false" log="true" priority="SIGNIFICANT" popup="false" blink="false" text="false" audioEnabled="false"/> <metadata foreground="#ffffff" background="#ff0000" pythonEnabled="false" log="true" priority="SIGNIFICANT" popup="false" blink="false" text="false" audioEnabled="false"/>
<metadata foreground="#000000" background="#7e7e7e" pythonEnabled="false" log="false" priority="VERBOSE" popup="false" blink="false" text="false" audioEnabled="false"/> <metadata foreground="#000000" background="#808080" pythonEnabled="false" log="false" priority="VERBOSE" popup="false" blink="false" text="false" audioEnabled="false"/>
<metadata foreground="#ff0000" background="#0000ff" pythonEnabled="false" log="true" priority="CRITICAL" popup="false" blink="false" text="false" audioEnabled="false"/> <metadata foreground="#000000" background="#ff0000" pythonEnabled="false" log="true" priority="CRITICAL" popup="true" blink="false" text="false" audioEnabled="false"/>
<metadata foreground="#000006" background="#ffff00" pythonEnabled="false" log="false" priority="PROBLEM" popup="false" blink="false" text="false" audioEnabled="false"/> <metadata foreground="#000000" background="#ffff00" pythonEnabled="false" log="false" priority="PROBLEM" popup="false" blink="false" text="false" audioEnabled="false"/>
<metadata foreground="#000000" background="#ffffff" pythonEnabled="false" log="false" priority="EVENTB" popup="false" blink="false" text="false" audioEnabled="false"/> <metadata foreground="#000000" background="#ffffff" pythonEnabled="false" log="false" priority="EVENTB" popup="false" blink="false" text="false" audioEnabled="false"/>
</configurationItem> </configurationItem>
<configurationMonitor> <configurationMonitor>

View file

@ -890,21 +890,15 @@ class SmartScript(BaseTool.BaseTool):
else: else:
timeRange = timeRange.toJavaObj() timeRange = timeRange.toJavaObj()
from com.raytheon.viz.gfe.smarttool.script import SmartToolRequest, SmartToolFinishedListener, SmartToolJob
from com.raytheon.viz.gfe.smarttool import SmartUtil from com.raytheon.viz.gfe.smarttool import SmartUtil
req = SmartUtil.callFromSmartScript(self.__dataMgr, toolName, elementName, editArea, result = SmartUtil.callFromSmartScript(self.__dataMgr, toolName, elementName, editArea,
timeRange, varDict, emptyEditAreaFlag, timeRange, varDict, emptyEditAreaFlag,
JUtil.pylistToJavaStringList(passErrors), JUtil.pylistToJavaStringList(passErrors),
missingDataMode, parm) missingDataMode, parm)
listener = SmartToolFinishedListener() if result:
req.setListener(listener) raise Exceptions.EditActionError(errorType="Error", errorInfo=str(result))
SmartToolJob.enqueue(self.__dataMgr, req)
while not listener.isDone():
time.sleep(0.2)
if listener.getResult():
raise Exceptions.EditActionError(errorType="Error", errorInfo=str(listener.getResult()))
return None return None
def callProcedure(self, name, editArea=None, timeRange=None, varDict=None, def callProcedure(self, name, editArea=None, timeRange=None, varDict=None,
@ -919,20 +913,15 @@ class SmartScript(BaseTool.BaseTool):
else: else:
timeRange = timeRange.toJavaObj() timeRange = timeRange.toJavaObj()
from com.raytheon.viz.gfe.procedures import ProcedureUtil, ProcedureRequest, ProcedureFinishedListener,ProcedureJob from com.raytheon.viz.gfe.procedures import ProcedureUtil
if varDict: if varDict:
varDict = str(varDict) varDict = str(varDict)
listener = ProcedureFinishedListener()
req = ProcedureUtil.callFromSmartScript(self.__dataMgr, name, editArea, timeRange, varDict) result = ProcedureUtil.callFromSmartScript(self.__dataMgr, name, editArea, timeRange, varDict)
req.setListener(listener)
ProcedureJob.enqueue(self.__dataMgr, req)
while not listener.isDone():
time.sleep(0.2)
# callSmartTool raises the exception put here it is returned. # callSmartTool raises the exception put here it is returned.
if listener.getResult(): if result:
return Exceptions.EditActionError(errorType="Error", errorInfo=str(listener.getResult())) return Exceptions.EditActionError(errorType="Error", errorInfo=str(result))
return None return None

View file

@ -30,22 +30,41 @@
<dataURI>/redbook/%/PMNV88/%</dataURI> <dataURI>/redbook/%/PMNV88/%</dataURI>
<substitute key="wmo" value="PMNV88"/> <substitute key="wmo" value="PMNV88"/>
</contribute> </contribute>
<contribute xsi:type="separator" id="separator1"/>
<contribute xsi:type="titleItem" <contribute xsi:type="titleItem"
titleText="------ 3-10 Day Threat Assessment ------" id="threeTo10DayThreatAssessLine"/> titleText="------ 3-7 Day Hazard Outlook ------" id="threeTo7DayHazardOutlook"/>
<contribute xsi:type="bundleItem" file="bundles/Redbook.xml" <contribute xsi:type="bundleItem" file="bundles/Redbook.xml"
menuText="Precipitation Fcst" id="precipFcst"> menuText="3-7 day Precipitation Fcst" id="threeTo7DayPrecipFcst">
<dataURI>/redbook/%/PEIY50/%</dataURI> <dataURI>/redbook/%/PEIY97/%</dataURI>
<substitute key="wmo" value="PEIY50"/> <substitute key="wmo" value="PEIY97"/>
</contribute> </contribute>
<contribute xsi:type="bundleItem" file="bundles/Redbook.xml" <contribute xsi:type="bundleItem" file="bundles/Redbook.xml"
menuText="Temp/Wind Fcst" id="tempWindFcst"> menuText="3-7 day Soil/Wildfire Fcst" id="threeTo7DaySoilWildfireFcst">
<dataURI>/redbook/%/PTIY98/%</dataURI> <dataURI>/redbook/%/PYIY97/%</dataURI>
<substitute key="wmo" value="PTIY98"/> <substitute key="wmo" value="PYIY97"/>
</contribute> </contribute>
<contribute xsi:type="bundleItem" file="bundles/Redbook.xml" <contribute xsi:type="bundleItem" file="bundles/Redbook.xml"
menuText="Soil/Wildfire Fcst" id="soilWildfireFcst"> menuText="3-7 day Temperature/Wind Fcst" id="threeTo7DayTempWindFcst">
<dataURI>/redbook/%/PYIY88/%</dataURI> <dataURI>/redbook/%/PTIY97/%</dataURI>
<substitute key="wmo" value="PYIY88"/> <substitute key="wmo" value="PTIY97"/>
</contribute>
<contribute xsi:type="separator" id="separator1"/>
<contribute xsi:type="titleItem"
titleText="------ 8-14 Day Hazard Outlook ------" id="eightTo14DayHazardOutlook"/>
<contribute xsi:type="bundleItem" file="bundles/Redbook.xml"
menuText="8-14 day Precipitation Fcst" id="eightTo14DayPrecipFcst">
<dataURI>/redbook/%/PEIY96/%</dataURI>
<substitute key="wmo" value="PEIY96"/>
</contribute>
<contribute xsi:type="bundleItem" file="bundles/Redbook.xml"
menuText="8-14 day Soil/Wildfire Fcst" id="eightTo14DaySoilWildfireFcst">
<dataURI>/redbook/%/PYIY96/%</dataURI>
<substitute key="wmo" value="PYIY96"/>
</contribute>
<contribute xsi:type="bundleItem" file="bundles/Redbook.xml"
menuText="8-14 day Temperature/Wind Fcst" id="eightTo14DayTempWindFcst">
<dataURI>/redbook/%/PTIY96/%</dataURI>
<substitute key="wmo" value="PTIY96"/>
</contribute> </contribute>
<contribute xsi:type="separator" id="separator1"/> <contribute xsi:type="separator" id="separator1"/>
<contribute xsi:type="titleItem" <contribute xsi:type="titleItem"
@ -71,6 +90,8 @@
<substitute key="wmo" value="PTNR98"/> <substitute key="wmo" value="PTNR98"/>
</contribute> </contribute>
<contribute xsi:type="separator" id="separator2"/> <contribute xsi:type="separator" id="separator2"/>
<contribute xsi:type="titleItem"
titleText="------ 8-14 Day Heat Index Fcst ------" id="eightTo14DayHeatIndexFcstLine"/>
<contribute xsi:type="bundleItem" file="bundles/Redbook.xml" <contribute xsi:type="bundleItem" file="bundles/Redbook.xml"
menuText=">=85F for 3 days of 7" id="gt85For3daysOf7"> menuText=">=85F for 3 days of 7" id="gt85For3daysOf7">
<dataURI>/redbook/%/PTAT90/%</dataURI> <dataURI>/redbook/%/PTAT90/%</dataURI>

View file

@ -163,11 +163,18 @@
<key>PPKA01</key> <key>PPKA01</key>
<value><name>gfs 00hr MSLP *</name></value> <value><name>gfs 00hr MSLP *</name></value>
</entry> </entry>
<entry> <entry>
<key>PEIK98</key> <key>PEIK98</key>
<value><name>Day 3 QPF - Time Proj 60-72Hrs</name></value> <value><name>Day 3 QPF - Time Proj 60-72Hrs</name></value>
</entry> </entry>
<entry>
<key>PEIY96</key>
<value><name>8-14 Day Precip Hazards </name></value>
</entry>
<entry>
<key>PEIY97</key>
<value><name>3-7 Day Precip Hazards</name></value>
</entry>
<entry> <entry>
<key>PLQI51</key> <key>PLQI51</key>
<value><name>redbook graphic</name></value> <value><name>redbook graphic</name></value>
@ -175,7 +182,7 @@
<entry> <entry>
<key>PEIY50</key> <key>PEIY50</key>
<value><name>3-10 Day Threat Assess Precip</name></value> <value><name>3-10 Day Threat Assess Precip</name></value>
</entry> </entry>
<entry> <entry>
<key>PYMA70</key> <key>PYMA70</key>
<value><name>700mb UA plot</name></value> <value><name>700mb UA plot</name></value>
@ -243,6 +250,14 @@
<entry> <entry>
<key>PTNR98</key> <key>PTNR98</key>
<value><name>6-10 Day Maximum Heat Index Outlook</name></value> <value><name>6-10 Day Maximum Heat Index Outlook</name></value>
</entry>
<entry>
<key>PTIY96</key>
<value><name>8-14 Temp/Wind Hazards</name></value>
</entry>
<entry>
<key>PTIY97</key>
<value><name>3-7 Day Temp/Wind Hazards</name></value>
</entry> </entry>
<entry> <entry>
<key>PNWA68</key> <key>PNWA68</key>
@ -264,7 +279,6 @@
<key>PYAA98</key> <key>PYAA98</key>
<value><name>Sfc Frontal Analysis</name></value> <value><name>Sfc Frontal Analysis</name></value>
</entry> </entry>
<entry> <entry>
<key>PTAT00</key> <key>PTAT00</key>
<value><name>8-14 Day Heat Index &gt;=95F</name></value> <value><name>8-14 Day Heat Index &gt;=95F</name></value>
@ -277,13 +291,18 @@
<key>PPAM89</key> <key>PPAM89</key>
<value><name>96Hr North Atlantic Fronts/Pressure/Winds FCST</name></value> <value><name>96Hr North Atlantic Fronts/Pressure/Winds FCST</name></value>
</entry> </entry>
<entry> <entry>
<key>PYAA89</key> <key>PYAA89</key>
<value><name>N Atlantic Surface Anal</name></value> <value><name>N Atlantic Surface Anal</name></value>
</entry> </entry>
<entry>
<key>PYIY96</key>
<value><name>8-14 Day Soil/Wildfire Hazards</name></value>
</entry>
<entry>
<key>PYIY97</key>
<value><name>3-7 Day Soil/Wildfire Hazards</name></value>
</entry>
<entry> <entry>
<key>PSBD25</key> <key>PSBD25</key>
<value><name>Day 3 Prob .25+&quot; Ice</name></value> <value><name>Day 3 Prob .25+&quot; Ice</name></value>
@ -342,7 +361,6 @@
<key>PYMA25</key> <key>PYMA25</key>
<value><name>250mb UA plot</name></value> <value><name>250mb UA plot</name></value>
</entry> </entry>
<entry> <entry>
<key>POWA31</key> <key>POWA31</key>
<value><name>redbook graphic</name></value> <value><name>redbook graphic</name></value>
@ -358,8 +376,7 @@
<entry> <entry>
<key>PEIW01,PEIW02,PEIW03,PEIW04,PEIW05,PEIW06,PEIW07,PEIW08,PEIW09,PEIW10,PEIW11,PEIW12,PEIW13</key> <key>PEIW01,PEIW02,PEIW03,PEIW04,PEIW05,PEIW06,PEIW07,PEIW08,PEIW09,PEIW10,PEIW11,PEIW12,PEIW13</key>
<value><name>90 Day Seasonal Precip Outlook</name></value> <value><name>90 Day Seasonal Precip Outlook</name></value>
</entry> </entry>
<entry> <entry>
<key>PTIW01,PTIW02,PTIW03,PTIW04,PTIW05,PTIW06,PTIW07,PTIW08,PTIW09,PTIW10,PTIW11,PTIW12,PTIW13</key> <key>PTIW01,PTIW02,PTIW03,PTIW04,PTIW05,PTIW06,PTIW07,PTIW08,PTIW09,PTIW10,PTIW11,PTIW12,PTIW13</key>
<value><name>90 Day Seasonal Temp Outlook</name></value> <value><name>90 Day Seasonal Temp Outlook</name></value>

View file

@ -21,7 +21,6 @@ package com.raytheon.uf.viz.core.notification.jobs;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Timer; import java.util.Timer;
@ -119,23 +118,30 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable {
*/ */
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) if (this == obj) {
return true; return true;
if (obj == null) }
if (obj == null) {
return false; return false;
if (getClass() != obj.getClass()) }
if (getClass() != obj.getClass()) {
return false; return false;
}
ListenerKey other = (ListenerKey) obj; ListenerKey other = (ListenerKey) obj;
if (queryString == null) { if (queryString == null) {
if (other.queryString != null) if (other.queryString != null) {
return false; return false;
} else if (!queryString.equals(other.queryString)) }
} else if (!queryString.equals(other.queryString)) {
return false; return false;
}
if (topic == null) { if (topic == null) {
if (other.topic != null) if (other.topic != null) {
return false; return false;
} else if (!topic.equals(other.topic)) }
} else if (!topic.equals(other.topic)) {
return false; return false;
}
return true; return true;
} }
} }
@ -529,13 +535,13 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable {
sendToObserver(obs, msg); sendToObserver(obs, msg);
} }
Iterator<JobWrapper> iterator = jobWrappers.values().iterator(); // Iterator<JobWrapper> iterator = jobWrappers.values().iterator();
while (iterator.hasNext()) { // while (iterator.hasNext()) {
JobWrapper wrapper = iterator.next(); // JobWrapper wrapper = iterator.next();
if (!wrapper.isEmpty() && wrapper.getState() != Job.RUNNING) { // if (!wrapper.isEmpty() && wrapper.getState() != Job.RUNNING) {
wrapper.schedule(); // wrapper.schedule();
} // }
} // }
} }
public synchronized void addObserver(INotificationObserver obs) { public synchronized void addObserver(INotificationObserver obs) {
@ -656,6 +662,7 @@ public class NotificationManagerJob implements ExceptionListener, IDisposable {
lastErrorPrintTime = System.currentTimeMillis(); lastErrorPrintTime = System.currentTimeMillis();
} }
} }
this.schedule();
} }
/** /**

View file

@ -20,6 +20,7 @@
package com.raytheon.uf.viz.monitor.scan.commondialogs; package com.raytheon.uf.viz.monitor.scan.commondialogs;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.TreeMap; import java.util.TreeMap;
@ -50,6 +51,8 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Mar 10, 2010 lvenable Initial creation * Mar 10, 2010 lvenable Initial creation
* Dec 23, 2011 13608 mgamazay Updated populateIdentCombo so the drop down menu
* shows the current feature ident instead of being blank.
* *
* </pre> * </pre>
* *
@ -291,11 +294,19 @@ public class TimeHeightDlg extends CaveSWTDialog implements ITimeHeightInfo {
* Populate the ident combo control. * Populate the ident combo control.
*/ */
private void populateIdentCombo() { private void populateIdentCombo() {
for (String str : identArray) {
identCbo.add(str); if ( Arrays.asList(identArray).contains(ident) ) {
for (String str : identArray) {
identCbo.add(str);
}
identCbo.select(identCbo.indexOf(ident));
} }
identCbo.select(identCbo.indexOf(ident)); else {
identCbo.add(ident);
identCbo.select(identCbo.indexOf(ident));
}
} }
/** /**

View file

@ -43,6 +43,7 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Apr 25, 2011 mpduff Initial creation * Apr 25, 2011 mpduff Initial creation
* Dec 23, 2011 13608 mgamazay Added initialization of ident to the constructor
* *
* </pre> * </pre>
* *
@ -65,6 +66,7 @@ public class TimeHeightMsgBox extends CaveSWTDialog implements
protected TimeHeightMsgBox(Shell parentShell, String ident) { protected TimeHeightMsgBox(Shell parentShell, String ident) {
super(parentShell, SWT.DIALOG_TRIM | SWT.MODELESS); super(parentShell, SWT.DIALOG_TRIM | SWT.MODELESS);
setText("Unavailable T-H Trend"); setText("Unavailable T-H Trend");
this.ident = ident;
} }

View file

@ -506,6 +506,7 @@ public class DataManager {
private void dispose() { private void dispose() {
selectTimeRangeManager.dispose(); selectTimeRangeManager.dispose();
refManager.dispose(); refManager.dispose();
parmManager.dispose();
autoSaveJob.dispose(); autoSaveJob.dispose();
autoSaveJob = null; autoSaveJob = null;

View file

@ -27,6 +27,7 @@ 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.db.objects.ParmID;
import com.raytheon.uf.common.dataplugin.gfe.slice.IGridSlice; import com.raytheon.uf.common.dataplugin.gfe.slice.IGridSlice;
import com.raytheon.uf.common.time.TimeRange; import com.raytheon.uf.common.time.TimeRange;
import com.raytheon.uf.viz.core.jobs.JobPool;
import com.raytheon.viz.gfe.GFEOperationFailedException; import com.raytheon.viz.gfe.GFEOperationFailedException;
import com.raytheon.viz.gfe.core.msgs.IAvailableSourcesChangedListener; import com.raytheon.viz.gfe.core.msgs.IAvailableSourcesChangedListener;
import com.raytheon.viz.gfe.core.msgs.IDisplayedParmListChangedListener; import com.raytheon.viz.gfe.core.msgs.IDisplayedParmListChangedListener;
@ -567,4 +568,6 @@ public interface IParmManager extends IParmInventoryChangedListener,
* @return * @return
*/ */
public ParmID fromExpression(String parmName); public ParmID fromExpression(String parmName);
public JobPool getNotificationPool();
} }

View file

@ -69,12 +69,13 @@ public class ISCParmInitJob extends Job {
protected IStatus run(IProgressMonitor monitor) { protected IStatus run(IProgressMonitor monitor) {
IISCDataAccess iscAccess = dataMgr.getIscDataAccess(); IISCDataAccess iscAccess = dataMgr.getIscDataAccess();
for (Parm parm : parms) { for (Parm parm : parms) {
// if (parm != null) { if (!monitor.isCanceled()) {
iscAccess.getISCParm(parm); iscAccess.getISCParm(parm);
// } } else {
return Status.CANCEL_STATUS;
}
} }
return Status.OK_STATUS; return Status.OK_STATUS;
} }
} }

View file

@ -34,6 +34,8 @@ import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.eclipse.core.runtime.ListenerList;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID; import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID.DataType; import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID.DataType;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.ParmID; import com.raytheon.uf.common.dataplugin.gfe.db.objects.ParmID;
@ -53,6 +55,7 @@ import com.raytheon.uf.common.time.SimulatedTime;
import com.raytheon.uf.common.time.TimeRange; import com.raytheon.uf.common.time.TimeRange;
import com.raytheon.uf.common.util.FileUtil; import com.raytheon.uf.common.util.FileUtil;
import com.raytheon.uf.common.util.RWLArrayList; import com.raytheon.uf.common.util.RWLArrayList;
import com.raytheon.uf.viz.core.jobs.JobPool;
import com.raytheon.viz.core.mode.CAVEMode; import com.raytheon.viz.core.mode.CAVEMode;
import com.raytheon.viz.gfe.Activator; import com.raytheon.viz.gfe.Activator;
import com.raytheon.viz.gfe.GFEServerException; import com.raytheon.viz.gfe.GFEServerException;
@ -71,7 +74,7 @@ import com.raytheon.viz.gfe.core.msgs.Message;
import com.raytheon.viz.gfe.core.msgs.ShowISCGridsMsg; import com.raytheon.viz.gfe.core.msgs.ShowISCGridsMsg;
import com.raytheon.viz.gfe.core.parm.ABVParmID; import com.raytheon.viz.gfe.core.parm.ABVParmID;
import com.raytheon.viz.gfe.core.parm.Parm; import com.raytheon.viz.gfe.core.parm.Parm;
import com.raytheon.viz.gfe.core.parm.VCModule; import com.raytheon.viz.gfe.core.parm.vcparm.VCModule;
/** /**
* Implements common parm manager functionality shared between concrete and mock * Implements common parm manager functionality shared between concrete and mock
@ -90,6 +93,8 @@ import com.raytheon.viz.gfe.core.parm.VCModule;
*/ */
public abstract class AbstractParmManager implements IParmManager { public abstract class AbstractParmManager implements IParmManager {
private static final int NOTIFICATION_THREADS = 4;
protected class ParmIDVis { protected class ParmIDVis {
private ParmID pid; private ParmID pid;
@ -196,17 +201,17 @@ public abstract class AbstractParmManager implements IParmManager {
// virtual parm definitions (modulename = key) // virtual parm definitions (modulename = key)
protected List<VCModule> vcModules; protected List<VCModule> vcModules;
protected List<IAvailableSourcesChangedListener> availableSourcesListeners; protected ListenerList availableSourcesListeners;
protected List<IDisplayedParmListChangedListener> displayedParmListListeners; protected ListenerList displayedParmListListeners;
protected List<INewModelAvailableListener> newModelListeners; protected ListenerList newModelListeners;
protected List<IParmIDChangedListener> parmIdChangedListeners; protected ListenerList parmIdChangedListeners;
protected List<IParmListChangedListener> parmListChangedListeners; protected ListenerList parmListChangedListeners;
protected List<ISystemTimeRangeChangedListener> systemTimeRangeChangedListeners; protected ListenerList systemTimeRangeChangedListeners;
protected TimeRange systemTimeRange; protected TimeRange systemTimeRange;
@ -230,15 +235,19 @@ public abstract class AbstractParmManager implements IParmManager {
private AbstractGFENotificationObserver<SiteActivationNotification> siteActivationListener; private AbstractGFENotificationObserver<SiteActivationNotification> siteActivationListener;
private ISCParmInitJob iscInit;
private JobPool notificationPool;
protected AbstractParmManager(final DataManager dataManager) { protected AbstractParmManager(final DataManager dataManager) {
this.dataManager = dataManager; this.dataManager = dataManager;
this.parms = new RWLArrayList<Parm>(); this.parms = new RWLArrayList<Parm>();
this.displayedParmListListeners = new ArrayList<IDisplayedParmListChangedListener>(); this.displayedParmListListeners = new ListenerList();
this.parmListChangedListeners = new ArrayList<IParmListChangedListener>(); this.parmListChangedListeners = new ListenerList();
this.systemTimeRangeChangedListeners = new ArrayList<ISystemTimeRangeChangedListener>(); this.systemTimeRangeChangedListeners = new ListenerList();
this.availableSourcesListeners = new ArrayList<IAvailableSourcesChangedListener>(); this.availableSourcesListeners = new ListenerList();
this.newModelListeners = new ArrayList<INewModelAvailableListener>(); this.newModelListeners = new ListenerList();
this.parmIdChangedListeners = new ArrayList<IParmIDChangedListener>(); this.parmIdChangedListeners = new ListenerList();
// Get virtual parm definitions // Get virtual parm definitions
vcModules = initVirtualCalcParmDefinitions(); vcModules = initVirtualCalcParmDefinitions();
@ -364,6 +373,9 @@ public abstract class AbstractParmManager implements IParmManager {
dataManager.getNotificationRouter().addObserver( dataManager.getNotificationRouter().addObserver(
this.siteActivationListener); this.siteActivationListener);
notificationPool = new JobPool("Parm Manager notification job",
NOTIFICATION_THREADS, true);
} }
/* /*
@ -384,6 +396,16 @@ public abstract class AbstractParmManager implements IParmManager {
dataManager.getNotificationRouter().removeObserver( dataManager.getNotificationRouter().removeObserver(
this.siteActivationListener); this.siteActivationListener);
for (VCModule module : vcModules) {
module.dispose();
}
if (iscInit != null) {
iscInit.cancel();
}
notificationPool.cancel();
} }
protected DatabaseID decodeDbString(final String string) { protected DatabaseID decodeDbString(final String string) {
@ -1126,8 +1148,10 @@ public abstract class AbstractParmManager implements IParmManager {
} }
setParms(addParms, deletions); setParms(addParms, deletions);
ISCParmInitJob iscInit = new ISCParmInitJob(dataManager, if (iscInit != null) {
getDisplayedParms()); iscInit.cancel();
}
iscInit = new ISCParmInitJob(dataManager, getDisplayedParms());
iscInit.schedule(); iscInit.schedule();
return; return;
@ -1390,10 +1414,20 @@ public abstract class AbstractParmManager implements IParmManager {
* @param deletes * @param deletes
* parms that were deleted * parms that were deleted
*/ */
protected void fireDisplayedParmListChanged(Parm[] parms, Parm[] adds, protected void fireDisplayedParmListChanged(final Parm[] parms,
Parm[] deletes) { final Parm[] adds, final Parm[] deletes) {
for (IDisplayedParmListChangedListener listener : this.displayedParmListListeners) { for (Object listener : this.displayedParmListListeners.getListeners()) {
listener.displayedParmListChanged(parms, deletes, adds); final IDisplayedParmListChangedListener casted = (IDisplayedParmListChangedListener) listener;
Runnable notTask = new Runnable() {
@Override
public void run() {
casted.displayedParmListChanged(parms, deletes, adds);
}
};
notificationPool.schedule(notTask);
} }
} }
@ -1405,9 +1439,18 @@ public abstract class AbstractParmManager implements IParmManager {
* @param newParmId * @param newParmId
* The new ParmID associated with parm. * The new ParmID associated with parm.
*/ */
protected void fireParmIDChanged(Parm parm, ParmID newParmId) { protected void fireParmIDChanged(final Parm parm, final ParmID newParmId) {
for (IParmIDChangedListener listener : this.parmIdChangedListeners) { for (Object listener : this.parmIdChangedListeners.getListeners()) {
listener.parmIDChanged(parm, newParmId); final IParmIDChangedListener casted = (IParmIDChangedListener) listener;
Runnable notTask = new Runnable() {
@Override
public void run() {
casted.parmIDChanged(parm, newParmId);
}
};
notificationPool.schedule(notTask);
} }
} }
@ -1421,9 +1464,19 @@ public abstract class AbstractParmManager implements IParmManager {
* @param deletes * @param deletes
* parms that were deleted * parms that were deleted
*/ */
protected void fireParmListChanged(Parm[] parms, Parm[] adds, Parm[] deletes) { protected void fireParmListChanged(final Parm[] parms, final Parm[] adds,
for (IParmListChangedListener listener : this.parmListChangedListeners) { final Parm[] deletes) {
listener.parmListChanged(parms, deletes, adds); for (Object listener : this.parmListChangedListeners.getListeners()) {
final IParmListChangedListener casted = (IParmListChangedListener) listener;
Runnable notTask = new Runnable() {
@Override
public void run() {
casted.parmListChanged(parms, deletes, adds);
}
};
notificationPool.schedule(notTask);
} }
} }
@ -1433,9 +1486,19 @@ public abstract class AbstractParmManager implements IParmManager {
* @param systemTimeRange * @param systemTimeRange
* new system time range * new system time range
*/ */
protected void fireSystemTimeRangeChanged(TimeRange systemTimeRange) { protected void fireSystemTimeRangeChanged(final TimeRange systemTimeRange) {
for (ISystemTimeRangeChangedListener listener : this.systemTimeRangeChangedListeners) { for (Object listener : this.systemTimeRangeChangedListeners
listener.systemTimeRangeChanged(systemTimeRange); .getListeners()) {
final ISystemTimeRangeChangedListener casted = (ISystemTimeRangeChangedListener) listener;
Runnable notTask = new Runnable() {
@Override
public void run() {
casted.systemTimeRangeChanged(systemTimeRange);
}
};
notificationPool.schedule(notTask);
} }
} }
@ -1449,10 +1512,22 @@ public abstract class AbstractParmManager implements IParmManager {
* @param additions * @param additions
* The items added to the inventory * The items added to the inventory
*/ */
protected void fireAvailableSourcesChanged(List<DatabaseID> inventory, protected void fireAvailableSourcesChanged(
List<DatabaseID> deletions, List<DatabaseID> additions) { final List<DatabaseID> inventory, final List<DatabaseID> deletions,
for (IAvailableSourcesChangedListener listener : this.availableSourcesListeners) { final List<DatabaseID> additions) {
listener.availableSourcesChanged(inventory, deletions, additions); for (Object listener : this.availableSourcesListeners.getListeners()) {
final IAvailableSourcesChangedListener casted = (IAvailableSourcesChangedListener) listener;
Runnable notTask = new Runnable() {
@Override
public void run() {
casted.availableSourcesChanged(inventory, deletions,
additions);
}
};
notificationPool.schedule(notTask);
} }
} }
@ -1462,9 +1537,18 @@ public abstract class AbstractParmManager implements IParmManager {
* @param additions * @param additions
* The DatabaseID of the newly-available model * The DatabaseID of the newly-available model
*/ */
protected void fireNewModelAvailable(DatabaseID newModel) { protected void fireNewModelAvailable(final DatabaseID newModel) {
for (INewModelAvailableListener listener : this.newModelListeners) { for (Object listener : this.newModelListeners.getListeners()) {
listener.newModelAvailable(newModel); final INewModelAvailableListener casted = (INewModelAvailableListener) listener;
Runnable notTask = new Runnable() {
@Override
public void run() {
casted.newModelAvailable(newModel);
}
};
notificationPool.schedule(notTask);
} }
} }
@ -1862,6 +1946,7 @@ public abstract class AbstractParmManager implements IParmManager {
deleteParm(tempParms.toArray(new Parm[tempParms.size()])); deleteParm(tempParms.toArray(new Parm[tempParms.size()]));
} }
@Override
public ParmID fromExpression(String expression) { public ParmID fromExpression(String expression) {
return new ABVParmID(this).parse(expression); return new ABVParmID(this).parse(expression);
} }
@ -1918,4 +2003,9 @@ public abstract class AbstractParmManager implements IParmManager {
return -1; return -1;
} }
@Override
public JobPool getNotificationPool() {
return notificationPool;
}
} }

View file

@ -51,7 +51,7 @@ import com.raytheon.viz.gfe.core.DataManager;
import com.raytheon.viz.gfe.core.parm.DbParm; import com.raytheon.viz.gfe.core.parm.DbParm;
import com.raytheon.viz.gfe.core.parm.Parm; import com.raytheon.viz.gfe.core.parm.Parm;
import com.raytheon.viz.gfe.core.parm.ParmDisplayAttributes.VisMode; import com.raytheon.viz.gfe.core.parm.ParmDisplayAttributes.VisMode;
import com.raytheon.viz.gfe.core.parm.VCModule; import com.raytheon.viz.gfe.core.parm.vcparm.VCModule;
import com.raytheon.viz.gfe.core.parm.VCParm; import com.raytheon.viz.gfe.core.parm.VCParm;
import com.raytheon.viz.gfe.core.parm.VParm; import com.raytheon.viz.gfe.core.parm.VParm;
import com.raytheon.viz.gfe.types.MutableInteger; import com.raytheon.viz.gfe.types.MutableInteger;

View file

@ -326,7 +326,8 @@ public abstract class Parm implements Comparable<Parm> {
this.parmState = new ParmState(this); this.parmState = new ParmState(this);
this.displayAttributes = new ParmDisplayAttributes(displayable, this); this.displayAttributes = new ParmDisplayAttributes(displayable, this);
this.parmListeners = new ParmListeners(); this.parmListeners = new ParmListeners(this.dataManager
.getParmManager().getNotificationPool());
// Construct an empty lock table // Construct an empty lock table
// Subclasses who utilize locks will override this // Subclasses who utilize locks will override this

View file

@ -25,6 +25,7 @@ import org.eclipse.core.runtime.ListenerList;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.ParmID; import com.raytheon.uf.common.dataplugin.gfe.db.objects.ParmID;
import com.raytheon.uf.common.dataplugin.gfe.server.lock.LockTable; import com.raytheon.uf.common.dataplugin.gfe.server.lock.LockTable;
import com.raytheon.uf.common.time.TimeRange; import com.raytheon.uf.common.time.TimeRange;
import com.raytheon.uf.viz.core.jobs.JobPool;
import com.raytheon.viz.gfe.core.msgs.GridDataChangedMsg; import com.raytheon.viz.gfe.core.msgs.GridDataChangedMsg;
import com.raytheon.viz.gfe.core.msgs.IColorTableModifiedListener; import com.raytheon.viz.gfe.core.msgs.IColorTableModifiedListener;
import com.raytheon.viz.gfe.core.msgs.ICombineModeChangedListener; import com.raytheon.viz.gfe.core.msgs.ICombineModeChangedListener;
@ -83,7 +84,9 @@ public class ParmListeners {
private final ListenerList lockTableChangedListeners; private final ListenerList lockTableChangedListeners;
protected ParmListeners() { private final JobPool notificationPool;
protected ParmListeners(JobPool pool) {
this.gridChangedListeners = new ListenerList(); this.gridChangedListeners = new ListenerList();
this.parmInventoryChangedListeners = new ListenerList(); this.parmInventoryChangedListeners = new ListenerList();
this.parmIDChangedListeners = new ListenerList(); this.parmIDChangedListeners = new ListenerList();
@ -94,81 +97,171 @@ public class ParmListeners {
this.pickupValueChangedListeners = new ListenerList(); this.pickupValueChangedListeners = new ListenerList();
this.colorTableModifiedListeners = new ListenerList(); this.colorTableModifiedListeners = new ListenerList();
this.lockTableChangedListeners = new ListenerList(); this.lockTableChangedListeners = new ListenerList();
this.notificationPool = pool;
} }
public void fireGridChangedListener(ParmID parmID, TimeRange validTime) { public void fireGridChangedListener(final ParmID parmID,
final TimeRange validTime) {
for (Object listener : this.gridChangedListeners.getListeners()) { for (Object listener : this.gridChangedListeners.getListeners()) {
((IGridDataChangedListener) listener).gridDataChanged(parmID, final IGridDataChangedListener casted = (IGridDataChangedListener) listener;
validTime);
}
Runnable notTask = new Runnable() {
@Override
public void run() {
casted.gridDataChanged(parmID, validTime);
}
};
notificationPool.schedule(notTask);
}
new GridDataChangedMsg(parmID, validTime).send(); new GridDataChangedMsg(parmID, validTime).send();
} }
protected void fireParmInventoryChangedListener(Parm parm, protected void fireParmInventoryChangedListener(final Parm parm,
TimeRange validTime) { final TimeRange validTime) {
for (Object listener : this.parmInventoryChangedListeners for (Object listener : this.parmInventoryChangedListeners
.getListeners()) { .getListeners()) {
((IParmInventoryChangedListener) listener).parmInventoryChanged( final IParmInventoryChangedListener casted = (IParmInventoryChangedListener) listener;
parm, validTime);
Runnable notTask = new Runnable() {
@Override
public void run() {
casted.parmInventoryChanged(parm, validTime);
}
};
notificationPool.schedule(notTask);
} }
} }
protected void fireParmIDChangedListener(Parm parm, ParmID newParmID) { protected void fireParmIDChangedListener(final Parm parm,
final ParmID newParmID) {
for (Object listener : this.parmIDChangedListeners.getListeners()) { for (Object listener : this.parmIDChangedListeners.getListeners()) {
((IParmIDChangedListener) listener).parmIDChanged(parm, newParmID); final IParmIDChangedListener casted = (IParmIDChangedListener) listener;
Runnable notTask = new Runnable() {
@Override
public void run() {
casted.parmIDChanged(parm, newParmID);
}
};
notificationPool.schedule(notTask);
} }
} }
public void fireSelectionTimeRangeChanged(Parm parm, public void fireSelectionTimeRangeChanged(final Parm parm,
TimeRange selectionTimeRange) { final TimeRange selectionTimeRange) {
for (Object listener : this.selectionTimeRangeChangedListeners for (Object listener : this.selectionTimeRangeChangedListeners
.getListeners()) { .getListeners()) {
((ISelectionTimeRangeChangedListener) listener) final ISelectionTimeRangeChangedListener casted = (ISelectionTimeRangeChangedListener) listener;
.selectionTimeRangeChanged(parm, selectionTimeRange);
Runnable notTask = new Runnable() {
@Override
public void run() {
casted.selectionTimeRangeChanged(parm, selectionTimeRange);
}
};
notificationPool.schedule(notTask);
} }
} }
public void fireParameterSelectionChangedListener(Parm parm, public void fireParameterSelectionChangedListener(final Parm parm,
boolean selected) { final boolean selected) {
for (Object listener : this.parameterSelectionChangedListeners for (Object listener : this.parameterSelectionChangedListeners
.getListeners()) { .getListeners()) {
((IParameterSelectionChangedListener) listener) final IParameterSelectionChangedListener casted = (IParameterSelectionChangedListener) listener;
.parameterSelectionChanged(parm, selected);
Runnable notTask = new Runnable() {
@Override
public void run() {
casted.parameterSelectionChanged(parm, selected);
}
};
notificationPool.schedule(notTask);
} }
} }
public void fireCombineModeChangedListener(Parm parm, CombineMode mode) { public void fireCombineModeChangedListener(final Parm parm,
final CombineMode mode) {
for (Object listener : this.combineModeChangedListeners.getListeners()) { for (Object listener : this.combineModeChangedListeners.getListeners()) {
((ICombineModeChangedListener) listener).combineModeChanged(parm, final ICombineModeChangedListener casted = (ICombineModeChangedListener) listener;
mode);
Runnable notTask = new Runnable() {
@Override
public void run() {
casted.combineModeChanged(parm, mode);
}
};
notificationPool.schedule(notTask);
} }
} }
public void fireVectorModeChangedListener(Parm parm, VectorMode mode) { public void fireVectorModeChangedListener(final Parm parm,
final VectorMode mode) {
for (Object listener : this.vectorModeChangedListeners.getListeners()) { for (Object listener : this.vectorModeChangedListeners.getListeners()) {
((IVectorModeChangedListener) listener).vectorModeChanged(parm, final IVectorModeChangedListener casted = (IVectorModeChangedListener) listener;
mode);
Runnable notTask = new Runnable() {
@Override
public void run() {
casted.vectorModeChanged(parm, mode);
}
};
notificationPool.schedule(notTask);
} }
} }
public void firePickupValueChangedListener(Parm parm, WxValue pickupValue) { public void firePickupValueChangedListener(final Parm parm,
final WxValue pickupValue) {
for (Object listener : this.pickupValueChangedListeners.getListeners()) { for (Object listener : this.pickupValueChangedListeners.getListeners()) {
((IPickupValueChangedListener) listener).pickupValueChanged(parm, final IPickupValueChangedListener casted = (IPickupValueChangedListener) listener;
pickupValue);
Runnable notTask = new Runnable() {
@Override
public void run() {
casted.pickupValueChanged(parm, pickupValue);
}
};
notificationPool.schedule(notTask);
} }
} }
public void fireColorTableModified(Parm parm) { public void fireColorTableModified(final Parm parm) {
for (Object listener : this.colorTableModifiedListeners.getListeners()) { for (Object listener : this.colorTableModifiedListeners.getListeners()) {
((IColorTableModifiedListener) listener).colorTableModified(parm); final IColorTableModifiedListener casted = (IColorTableModifiedListener) listener;
Runnable notTask = new Runnable() {
@Override
public void run() {
casted.colorTableModified(parm);
}
};
notificationPool.schedule(notTask);
} }
} }
public void fireLockTableChanged(Parm parm, LockTable lockTable) { public void fireLockTableChanged(final Parm parm, final LockTable lockTable) {
for (Object listener : this.lockTableChangedListeners.getListeners()) { for (Object listener : this.lockTableChangedListeners.getListeners()) {
((ILockTableChangedListener) listener).lockTableChanged(parm, final ILockTableChangedListener casted = (ILockTableChangedListener) listener;
lockTable);
Runnable notTask = new Runnable() {
@Override
public void run() {
casted.lockTableChanged(parm, lockTable);
}
};
notificationPool.schedule(notTask);
} }
} }

View file

@ -1,662 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.viz.gfe.core.parm;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import jep.JepException;
import com.raytheon.uf.common.dataplugin.gfe.GridDataHistory;
import com.raytheon.uf.common.dataplugin.gfe.GridDataHistory.OriginType;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID.DataType;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GFERecord.GridType;
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.db.objects.TimeConstraints;
import com.raytheon.uf.common.dataplugin.gfe.discrete.DiscreteKey;
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.python.GfePyIncludeUtil;
import com.raytheon.uf.common.dataplugin.gfe.slice.DiscreteGridSlice;
import com.raytheon.uf.common.dataplugin.gfe.slice.IGridSlice;
import com.raytheon.uf.common.dataplugin.gfe.slice.ScalarGridSlice;
import com.raytheon.uf.common.dataplugin.gfe.slice.VectorGridSlice;
import com.raytheon.uf.common.dataplugin.gfe.slice.WeatherGridSlice;
import com.raytheon.uf.common.dataplugin.gfe.weather.WeatherKey;
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.viz.core.VizApp;
import com.raytheon.viz.gfe.GFEException;
import com.raytheon.viz.gfe.core.DataManager;
import com.raytheon.viz.gfe.core.IParmManager;
import com.raytheon.viz.gfe.core.griddata.IGridData;
/**
* Virtual Calculated Module. Serves as interface between the VCParm and the
* actual python algorithms.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Oct 17, 2011 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class VCModule {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(VCModule.class);
public class DepParmInv {
private ParmID parmID;
private List<TimeRange> times;
public DepParmInv(ParmID pid, List<TimeRange> trs) {
this.parmID = pid;
this.times = trs;
}
public ParmID getParmID() {
return parmID;
}
public List<TimeRange> getTimes() {
return times;
}
@Override
public String toString() {
StringBuilder tmp = new StringBuilder();
tmp.append("(pid=");
tmp.append(parmID.toString());
tmp.append(",times=");
tmp.append(times.toString());
tmp.append(')');
return tmp.toString();
}
}
public class VCInventory {
private TimeRange gridTimeRange;
private List<DepParmInv> depParmInv;
public VCInventory(TimeRange gridTimeRange, List<DepParmInv> depParmInv) {
this.gridTimeRange = gridTimeRange;
this.depParmInv = depParmInv;
}
public TimeRange getGridTimeRange() {
return gridTimeRange;
}
public List<DepParmInv> getDepParmInv() {
return depParmInv;
}
@Override
public String toString() {
StringBuilder tmp = new StringBuilder();
tmp.append("gtr=");
tmp.append(gridTimeRange.toString());
tmp.append(",dpi=");
tmp.append(depParmInv.toString());
return tmp.toString();
}
}
protected class GetInventoryArg {
public List<long[]> trs;
public GetInventoryArg(List<long[]> trs) {
this.trs = new ArrayList<long[]>(trs);
}
}
protected class CalcHistoryArg {
// simulates the AWIPS1 tuple used, which contained an encoded time
// range (long[]) and the list of GridDataHistory entries that
// correspond to that grid time range (List<String>).
public List<Object[]> histEntries;
public CalcHistoryArg(List<Object[]> histEntries) {
this.histEntries = new ArrayList<Object[]>(histEntries);
}
}
protected class CalcGridArg {
// simulates the AWIPS1 tuple used, which contained an encoded time
// range (long[]), the grid data (IGridData), and a bit mask of valid
// points in the grid data (Grid2DBit).
public List<Object[]> argTuples;
public CalcGridArg(List<Object[]> argTuples) {
this.argTuples = new ArrayList<Object[]>(argTuples);
}
}
private VCModuleScript module;
private Throwable error;
private GridParmInfo gpi;
private Collection<ParmID> depParms;
private DataManager dataMgr;
private IParmManager parmMgr;
@SuppressWarnings("unused")
private String id;
// To prevent invalid thread access errors from Jep all public interface
// functions run within a VizApp.runSync(). This is not a desirable
// long-term solution and would be faster if they could run on some other
// common thread.
// FIXME: Restructure this class to work from a common thread that is
// not the UI thread.
public VCModule(DataManager dataMgr, IParmManager parmMgr, final File module) {
this.dataMgr = dataMgr;
this.parmMgr = parmMgr;
this.id = module.getName();
// Let's do something unfortunately hacky here--we're going to force
// creation of the module object to be on the UI thread. Thus, any of
// the notifications received by VCParm can call methods within this
// class from a VizApp.runAsync and not receive invalid thread errors.
VizApp.runSync(new Runnable() {
@Override
public void run() {
try {
VCModule.this.module = new VCModuleScript(module
.getAbsolutePath(), GfePyIncludeUtil
.getCommonPythonIncludePath(), VCModule.this
.getClass().getClassLoader());
} catch (JepException e) {
VCModule.this.error = e;
}
}
});
}
public boolean isValid() {
return (this.error == null);
}
public Throwable getErrorString() {
Throwable rVal = error;
error = null;
return rVal;
}
private List<String> getMethodArgs(String method) throws JepException {
// statusHandler.debug("getMethodArgs: " + id);
return module.getArgumentNames(method);
}
public Collection<ParmID> dependentParms() {
if (this.depParms != null) {
return this.depParms;
}
final Collection<String> parameters = new ArrayList<String>();
VizApp.runSync(new Runnable() {
@Override
public void run() {
try {
parameters.addAll(getMethodArgs("getInventory"));
} catch (JepException e) {
error = e;
// statusHandler.handle(Priority.DEBUG, "dependentParms: " +
// id
// + " error", e);
VCModule.this.depParms = Collections.emptyList();
}
}
});
if (this.depParms == null) {
Collection<ParmID> rval = new ArrayList<ParmID>();
for (String parmName : parameters) {
ParmID pid = parmMgr.fromExpression(parmName);
if (pid.isValid()) {
rval.add(pid);
} else {
error = new IllegalArgumentException(
"Can't find Weather Element for " + parmName);
this.depParms = Collections.emptyList();
}
}
this.depParms = rval;
}
return this.depParms;
}
private long[] encodeTR(final TimeRange tr) {
long[] ptime = { tr.getStart().getTime(), tr.getEnd().getTime() };
return ptime;
}
private List<long[]> pyInventory(Parm p) {
IGridData[] gridInv = p.getGridInventory();
List<long[]> inv = new ArrayList<long[]>(gridInv.length);
for (IGridData gd : gridInv) {
inv.add(encodeTR(gd.getGridTime()));
}
return inv;
}
private Object[] encodeGD(IGridData gd) {
Object[] item = new Object[3];
item[0] = encodeTR(gd.getGridTime());
// since we have to go through a bunch of hoops in VCModuleScript to get
// the IGridData in python-useable format, no need doing anything here
// but storing the data
item[1] = gd;
// add a mask indicating the set of valid points. Note for all data
// other than ISC data, the mask is all points. ISC data values depend
// upon the masking of the Grid Data History.
Grid2DBit validBits;
if (gd.getParm().isIscParm()) {
List<String> hs = gd.getHistorySites();
validBits = dataMgr.getRefManager().siteGridpoints(hs, true);
} else {
validBits = dataMgr.getRefManager().fullRefSet().getGrid();
}
item[2] = validBits;
return item;
}
@SuppressWarnings("unchecked")
private IGridSlice decodeGD(Object o, VCInventory invEntry)
throws GFEException, JepException {
TimeRange tr = invEntry.getGridTimeRange();
List<GridDataHistory> gdh = calcHistory(invEntry);
if (!isValid()) {
throw new GFEException(getErrorString());
}
GridParmInfo gpi = getGpi();
switch (gpi.getGridType()) {
case SCALAR:
return new ScalarGridSlice(tr, gpi, gdh, (Grid2DFloat) o);
case VECTOR:
Grid2DFloat[] s = (Grid2DFloat[]) o;
return new VectorGridSlice(tr, gpi, gdh, s[0], s[1]);
case WEATHER:
Object[] wxGrid = (Object[]) o;
List<WeatherKey> key = new ArrayList<WeatherKey>();
List<String> pkey = (List<String>) wxGrid[1];
for (String wKey : pkey) {
key.add(new WeatherKey(gpi.getParmID().getDbId().getSiteId(),
wKey));
}
return new WeatherGridSlice(tr, gpi, gdh, (Grid2DByte) wxGrid[0],
key);
case DISCRETE:
Object[] discGrid = (Object[]) o;
List<DiscreteKey> keys = new ArrayList<DiscreteKey>();
List<String> pkeys = (List<String>) discGrid[1];
for (String dKey : pkeys) {
keys.add(new DiscreteKey(gpi.getParmID().getDbId().getSiteId(),
dKey, gpi.getParmID()));
}
return new DiscreteGridSlice(tr, gpi, gdh,
(Grid2DByte) discGrid[0], keys);
default:
statusHandler.handle(Priority.EVENTB, "Unknown parm type: "
+ gpi.getGridType().toString());
break;
}
return null;
}
@SuppressWarnings("unchecked")
private TimeRange decodeTR(Object o) {
List<Long> ptr = (List<Long>) o;
return new TimeRange(ptr.get(0), ptr.get(1));
}
@SuppressWarnings("unchecked")
public List<VCInventory> getInventory() {
// statusHandler.debug("getInventory: " + id);
final List<VCInventory> rval = new ArrayList<VCInventory>();
VizApp.runSync(new Runnable() {
@Override
public void run() {
try {
List<String> args = getMethodArgs("getInventory");
Map<String, Object> cargs = new HashMap<String, Object>(
args.size());
List<Parm> pargs = new ArrayList<Parm>(args.size());
for (String arg : args) {
ParmID pid = parmMgr.fromExpression(arg);
Parm tp = parmMgr.getParm(pid);
if (tp == null) {
throw new IllegalArgumentException(
"Can't locate Weather Element: " + arg);
}
cargs.put(arg, new GetInventoryArg(pyInventory(tp)));
pargs.add(tp);
}
// what's returned from the script here is a list of tuples.
// Each tuple contains:
// 1. A TimeRange.
// 2. A list of TimeRanges that correspond to the Fcst grids
// that should be used for that time
// 3. A list of TimeRanges that correspond to the ISC grids
// that should be used for that time
List<List<Object>> result = (List<List<Object>>) module
.execute("getInventory", cargs);
for (List<Object> item : result) {
List<DepParmInv> dpi = new ArrayList<DepParmInv>();
for (int i = 1; i < item.size(); i++) {
List<Object> ditem = (List<Object>) item.get(i);
List<TimeRange> trs = new ArrayList<TimeRange>(
ditem.size());
for (Object tr : ditem) {
trs.add(decodeTR(tr));
}
dpi.add(new DepParmInv(
pargs.get(i - 1).getParmID(), trs));
}
rval.add(new VCInventory(decodeTR(item.get(0)), dpi));
}
} catch (Throwable t) {
error = t;
}
}
});
return rval;
}
private List<String> encodeGDH(final List<GridDataHistory> gdh) {
List<String> l = new ArrayList<String>(gdh.size());
for (GridDataHistory hist : gdh) {
l.add(hist.getCodedString());
}
return l;
}
@SuppressWarnings("unchecked")
private List<GridDataHistory> decodeGDH(final Object o) {
List<String> s = (List<String>) o;
List<GridDataHistory> rval = new ArrayList<GridDataHistory>(s.size());
for (String entry : s) {
GridDataHistory gdh = new GridDataHistory(entry);
rval.add(gdh);
}
return rval;
}
@SuppressWarnings("unchecked")
public List<GridDataHistory> calcHistory(final VCInventory invEntry) {
// statusHandler.debug("calcHistory: " + id + " " +
// invEntry.toString());
final List<String> result = new ArrayList<String>();
VizApp.runSync(new Runnable() {
@Override
public void run() {
boolean hasattr = false;
try {
hasattr = module.hasAttr("calcHistory");
} catch (JepException e) {
// swallow exception and move on
statusHandler.handle(Priority.EVENTB,
"Could not retrieve calcHistory attribute", e);
}
if (hasattr) {
try {
final List<DepParmInv> dpi = invEntry.getDepParmInv();
List<String> args = getMethodArgs("calcHistory");
Map<String, Object> cargs = new HashMap<String, Object>(
args.size());
for (String arg : args) {
Parm tp = parmMgr.getParm(parmMgr
.fromExpression(arg));
if (tp != null) {
List<Object[]> l = new ArrayList<Object[]>();
for (DepParmInv dpiEntry : dpi) {
if (dpiEntry.getParmID().equals(
tp.getParmID())) {
for (TimeRange tr : dpiEntry.getTimes()) {
IGridData gd = tp
.overlappingGrid(tr
.getStart());
if (gd == null) {
throw new IllegalArgumentException(
"Unable to retrieve overlapping grid for parm: "
+ tp.getParmID()
.toString()
+ " for time: "
+ tr.toString());
}
Object[] tl = new Object[2];
tl[0] = encodeTR(gd.getGridTime());
tl[1] = encodeGDH(Arrays.asList(gd
.getHistory()));
l.add(tl);
}
}
}
cargs.put(arg, new CalcHistoryArg(l));
} else {
throw new IllegalArgumentException(
"Unable to find parm " + arg);
}
}
result.addAll((List<String>) module.execute(
"calcHistory", cargs));
} catch (Throwable t) {
error = t;
}
}
}
});
if (error == null) {
return decodeGDH(result);
} else {
// the default
return Arrays.asList(new GridDataHistory(OriginType.CALCULATED,
getGpi().getParmID(), invEntry.getGridTimeRange()));
}
}
public IGridSlice calcGrid(VCInventory invEntry) {
// statusHandler.debug("calcGrid: " + id + " " + invEntry.toString());
final List<DepParmInv> dpi = invEntry.getDepParmInv();
final List<Object> holder = new ArrayList<Object>(1);
VizApp.runSync(new Runnable() {
@Override
public void run() {
try {
List<String> args = getMethodArgs("calcGrid");
Map<String, Object> cargs = new HashMap<String, Object>(
args.size());
for (String arg : args) {
ParmID id = parmMgr.fromExpression(arg);
Parm tp = parmMgr.getParm(id);
if (tp != null) {
List<Object[]> l = new ArrayList<Object[]>();
for (DepParmInv dpiEntry : dpi) {
if (dpiEntry.getParmID().equals(tp.getParmID())) {
for (TimeRange tr : dpiEntry.getTimes()) {
IGridData gd = tp.overlappingGrid(tr
.getStart());
if (gd == null) {
throw new IllegalArgumentException(
"Unable to retrieve overlapping grid for parm: "
+ tp.getParmID()
.toString()
+ " for time: "
+ tr.toString());
}
l.add(encodeGD(gd));
}
}
}
cargs.put(arg, new CalcGridArg(l));
} else {
throw new IllegalArgumentException(
"Unable to find parm " + arg);
}
}
Object result = module.executeCalcGrid(cargs, getGpi()
.getGridType());
holder.add(result);
} catch (Throwable t) {
error = t;
}
}
});
if (error == null) {
try {
return decodeGD(holder.get(0), invEntry);
} catch (Throwable t) {
error = t;
return null;
}
} else {
return null;
}
}
@SuppressWarnings("unchecked")
public GridParmInfo getGpi() {
if (this.gpi != null) {
return this.gpi;
}
// statusHandler.debug("getGpi(): " + id);
try {
final List<List<Object>> result = new ArrayList<List<Object>>();
VizApp.runSync(new Runnable() {
@Override
public void run() {
try {
result.addAll((List<List<Object>>) VCModule.this.module
.execute("getWEInfo", null));
} catch (JepException e) {
VCModule.this.error = e;
}
}
});
if (error != null) {
return null;
}
List<Object> s = result.get(1);
String site = parmMgr.getMutableDatabase().getSiteId();
DatabaseID dbid = new DatabaseID(site, DataType.GRID, s.get(1)
.toString(), s.get(0).toString(), DatabaseID.NO_MODEL_TIME);
s = result.get(2);
TimeConstraints tc = new TimeConstraints((Integer) s.get(0),
(Integer) s.get(1), (Integer) s.get(2));
s = result.get(0);
ParmID pid = new ParmID(s.get(0).toString(), dbid);
GridType type = GridType.NONE;
try {
type = GridType.valueOf(s.get(1).toString().toUpperCase());
} catch (IllegalArgumentException e) {
// just want to swallow the exception here as we've already
// defaulted type to NONE
statusHandler
.handle(Priority.EVENTB, "Invalid GridType specified: "
+ s.get(1).toString(), e);
}
// Double check for all the various valid parm lengths from
// serverConfig
GridParmInfo gpi = new GridParmInfo(pid,
parmMgr.compositeGridLocation(), type, s.get(2).toString(),
s.get(3).toString(), (Float) s.get(5), (Float) s.get(4),
(Integer) s.get(6), false, tc, (Boolean) s.get(7));
this.gpi = gpi;
} catch (Exception e) {
error = e;
}
return this.gpi;
}
}

View file

@ -1,402 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.viz.gfe.core.parm;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import jep.JepException;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GFERecord.GridType;
import com.raytheon.uf.common.dataplugin.gfe.discrete.DiscreteKey;
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.weather.WeatherKey;
import com.raytheon.uf.common.python.PyUtil;
import com.raytheon.uf.common.python.PythonScript;
import com.raytheon.viz.gfe.core.griddata.DiscreteGridData;
import com.raytheon.viz.gfe.core.griddata.IGridData;
import com.raytheon.viz.gfe.core.griddata.ScalarGridData;
import com.raytheon.viz.gfe.core.griddata.VectorGridData;
import com.raytheon.viz.gfe.core.griddata.WeatherGridData;
import com.raytheon.viz.gfe.core.parm.VCModule.CalcGridArg;
import com.raytheon.viz.gfe.core.parm.VCModule.CalcHistoryArg;
import com.raytheon.viz.gfe.core.parm.VCModule.GetInventoryArg;
/**
* A PythonScript subclass that replaces the Python/C++ interface that was
* available to AWIPS1's <code>VCModule</code> class. Primarily used for
* Python->Java data type conversions.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 17, 2011 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class VCModuleScript extends PythonScript {
private static final String INSTANCE_NAME = "instance";
private List<String> tempGridNames;
/**
* Constructor.
*
* @param aFilePath
* the path to the python script
* @param anIncludePath
* the python include path, with multiple directories being
* separated by ":"
* @param aClassLoader
* the Java classloader to use for importing Java classes inside
* python
* @throws JepException
*/
public VCModuleScript(String aFilePath, String anIncludePath,
ClassLoader aClassLoader) throws JepException {
super(aFilePath, anIncludePath, aClassLoader, Arrays.asList(
"import JUtil", "import numpy"));
instantiatePythonClass(INSTANCE_NAME, "VCParm", null);
this.tempGridNames = new ArrayList<String>();
}
/**
* Retrieves a list of argument names for the specified Python method.
*
* @param method
* The name of the method.
* @return List of argument names for the specified Python method, except
* for "self".
* @throws JepException
*/
public List<String> getArgumentNames(String method) throws JepException {
String[] argNames = getArgumentNames(method, INSTANCE_NAME);
List<String> retVal = new ArrayList<String>(argNames.length);
for (String arg : argNames) {
if (!arg.equals("self")) {
retVal.add(arg);
}
}
return retVal;
}
/**
* Executes the calcGrid() method.
*
* @param methodArgs
* A <code>Map</code> containing argument names and values.
* @param type
* The <code>GridType</code> of the grid being calculated.
* @return The virtual grid. For SCALARs, this will be a
* <code>Grid2DFloat</code>. For VECTORs, this will be an array
* containing 2 <code>Grid2DFloat</code> objects (mag, dir). For
* WEATHER and DISCRETE, this will be an array containing a
* <code>Grid2DByte</code> and a list of keys.
* @throws JepException
*/
public Object executeCalcGrid(Map<String, Object> methodArgs, GridType type)
throws JepException {
internalExecute("calcGrid", INSTANCE_NAME, methodArgs);
Object obj = decodeGD(type);
jep.eval(RESULT + " = None");
return obj;
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.common.python.PythonScript#execute(java.lang.String,
* java.util.Map)
*/
@Override
public Object execute(String methodName, Map<String, Object> args)
throws JepException {
internalExecute(methodName, INSTANCE_NAME, args);
jep.eval(RESULT + " = JUtil.pyValToJavaObj(" + RESULT + ")");
Object obj = jep.getValue(RESULT);
jep.eval(RESULT + " = None");
return obj;
}
/**
* Override of the evaluateArgument() method which handles the custom
* argument structures defined in <code>VCModule</code>. Important so that
* we can convert the Java datatypes to Python native objects (and numpy
* arrays for the grids).
*
* @param argName
* The argument name.
* @param argValue
* the value of the argument
*
* @see com.raytheon.uf.common.python.PythonInterpreter#evaluateArgument(java
* .lang.String, java.lang.Object)
*/
@SuppressWarnings("unchecked")
@Override
protected void evaluateArgument(String argName, Object argValue)
throws JepException {
if (argValue instanceof GetInventoryArg) {
GetInventoryArg arg = (GetInventoryArg) argValue;
StringBuilder sb = new StringBuilder(512);
sb.append(argName + " = [");
for (int i = 0; i < arg.trs.size(); i++) {
long[] tuple = arg.trs.get(i);
sb.append('(');
sb.append(tuple[0]);
sb.append(", ");
sb.append(tuple[1]);
sb.append(')');
if (i < arg.trs.size() - 1) {
sb.append(',');
}
}
sb.append(']');
jep.eval(sb.toString());
} else if (argValue instanceof CalcHistoryArg) {
CalcHistoryArg castedArg = (CalcHistoryArg) argValue;
StringBuilder sb = new StringBuilder(1024);
sb.append(argName + " = [");
for (int i = 0; i < castedArg.histEntries.size(); i++) {
Object[] timeAndHistList = castedArg.histEntries.get(i);
long[] tr = (long[]) timeAndHistList[0];
List<String> hist = (List<String>) timeAndHistList[1];
sb.append("((");
sb.append(tr[0]);
sb.append(", ");
sb.append(tr[1]);
sb.append("), [");
for (int j = 0; j < hist.size(); j++) {
sb.append("\"" + hist.get(j) + "\"");
if (j < hist.size() - 1) {
sb.append(',');
}
}
sb.append("])");
if (i < castedArg.histEntries.size() - 1) {
sb.append(',');
}
}
sb.append(']');
jep.eval(sb.toString());
} else if (argValue instanceof CalcGridArg) {
CalcGridArg castedArg = (CalcGridArg) argValue;
StringBuilder sb = new StringBuilder(768);
sb.append(argName + " = [");
for (int i = 0; i < castedArg.argTuples.size(); i++) {
Object[] tuple = castedArg.argTuples.get(i);
long[] tr = (long[]) tuple[0];
IGridData gd = (IGridData) tuple[1];
Grid2DBit mask = (Grid2DBit) tuple[2];
sb.append("((");
sb.append(tr[0]);
sb.append(", ");
sb.append(tr[1]);
sb.append("), ");
sb.append(encodeGridAndMask(gd, mask, i));
sb.append(')');
if (i < castedArg.argTuples.size() - 1) {
sb.append(',');
}
}
sb.append(']');
jep.eval(sb.toString());
} else {
super.evaluateArgument(argName, argValue);
}
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.python.PythonScript#cleanupArgs(java.util.List)
*/
@Override
protected void cleanupArgs(List<String> args) throws JepException {
super.cleanupArgs(args);
for (String gridName : tempGridNames) {
jep.eval(gridName + " = None");
}
tempGridNames.clear();
}
private String encodeGridAndMask(IGridData gd, Grid2DBit mask, int offset)
throws JepException {
StringBuilder jepString = new StringBuilder(256);
String prefix = gd.getParm().getParmID().getParmName()
+ Integer.toHexString(gd.getParm().getParmID().hashCode())
+ "_" + offset + "_";
if (gd instanceof ScalarGridData) {
ScalarGridData grid = (ScalarGridData) gd;
Grid2DFloat f = (grid.getScalarSlice()).getScalarGrid();
String name = prefix + "grid";
jep.setNumeric(name, f.getFloats(), f.getXdim(), f.getYdim());
jepString.append(name);
jepString.append(", ");
tempGridNames.add(name);
} else if (gd instanceof VectorGridData) {
VectorGridData grid = (VectorGridData) gd;
Grid2DFloat mag = (grid.getVectorSlice()).getMagGrid();
Grid2DFloat dir = (grid.getVectorSlice()).getDirGrid();
String magName = prefix + "Mag";
String dirName = prefix + "Dir";
jep.setNumeric(magName, mag.getFloats(), mag.getXdim(),
mag.getYdim());
jep.setNumeric(dirName, dir.getFloats(), dir.getXdim(),
dir.getYdim());
jepString.append('(');
jepString.append(magName);
jepString.append(',');
jepString.append(dirName);
jepString.append("), ");
tempGridNames.add(magName);
tempGridNames.add(dirName);
} else if (gd instanceof WeatherGridData) {
WeatherGridData grid = (WeatherGridData) gd;
Grid2DByte bytes = grid.getWeatherSlice().getWeatherGrid();
String name = prefix + "grid";
jep.setNumeric(name, bytes.getBytes(), bytes.getXdim(),
bytes.getYdim());
jepString.append('(');
jepString.append(name);
jepString.append(',');
WeatherKey[] keys = grid.getWeatherSlice().getKeys();
ArrayList<String> stringKeys = new ArrayList<String>(keys.length);
for (WeatherKey k : keys) {
stringKeys.add(k.toString());
}
jepString.append(PyUtil.listToTuple(stringKeys));
jepString.append("), ");
tempGridNames.add(name);
} else if (gd instanceof DiscreteGridData) {
DiscreteGridData grid = (DiscreteGridData) gd;
Grid2DByte bytes = grid.getDiscreteSlice().getDiscreteGrid();
String name = prefix + "grid";
jep.setNumeric(name, bytes.getBytes(), bytes.getXdim(),
bytes.getYdim());
jepString.append('(');
jepString.append(name);
jepString.append(',');
DiscreteKey[] keys = grid.getDiscreteSlice().getKey();
ArrayList<String> stringKeys = new ArrayList<String>(keys.length);
for (DiscreteKey k : keys) {
stringKeys.add(k.toString());
}
jepString.append(PyUtil.listToTuple(stringKeys));
jepString.append("), ");
tempGridNames.add(name);
}
String maskName = prefix + "mask";
jep.setNumeric(maskName, mask.getBytes(), mask.getXdim(),
mask.getYdim());
jepString.append(maskName);
tempGridNames.add(maskName);
return jepString.toString();
}
private Object decodeGD(GridType type) throws JepException {
Object result = null;
boolean resultFound = (Boolean) jep.getValue(RESULT + " is not None");
if (resultFound) {
int xDim, yDim = 0;
switch (type) {
case SCALAR:
float[] scalarData = (float[]) jep.getValue(RESULT
+ ".astype(numpy.float32)");
xDim = (Integer) jep.getValue(RESULT + ".shape[1]");
yDim = (Integer) jep.getValue(RESULT + ".shape[0]");
result = new Grid2DFloat(xDim, yDim, scalarData);
break;
case VECTOR:
float[] mag = (float[]) jep.getValue(RESULT
+ "[0].astype(numpy.float32)");
float[] dir = (float[]) jep.getValue(RESULT
+ "[1].astype(numpy.float32)");
xDim = (Integer) jep.getValue(RESULT + "[0].shape[1]");
yDim = (Integer) jep.getValue(RESULT + "[0].shape[0]");
Grid2DFloat magGrid = new Grid2DFloat(xDim, yDim, mag);
Grid2DFloat dirGrid = new Grid2DFloat(xDim, yDim, dir);
result = new Grid2DFloat[] { magGrid, dirGrid };
break;
case WEATHER:
case DISCRETE:
byte[] bytes = (byte[]) jep.getValue(RESULT
+ "[0].astype(numpy.int8)");
String[] keys = (String[]) jep.getValue(RESULT + "[1]");
xDim = (Integer) jep.getValue(RESULT + "[0].shape[1]");
yDim = (Integer) jep.getValue(RESULT + "[0].shape[0]");
Grid2DByte grid = new Grid2DByte(xDim, yDim, bytes);
List<String> keysList = new ArrayList<String>();
Collections.addAll(keysList, keys);
result = new Object[] { grid, keysList };
break;
}
}
return result;
}
/**
* Calls hasattr() against the <code>VCModule</code> instance and returns
* whether or not the specified attribute exists.
*
* @param attribute
* Attribute name.
* @return Whether or not the specified attribute exists.
* @throws JepException
*/
public boolean hasAttr(String attribute) throws JepException {
jep.eval(RESULT + " = hasattr(" + INSTANCE_NAME + ", \"" + attribute
+ "\")");
boolean result = ((Boolean) jep.getValue(RESULT)).booleanValue();
jep.eval(RESULT + " = None");
return result;
}
}

View file

@ -38,15 +38,15 @@ import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.time.TimeRange; import com.raytheon.uf.common.time.TimeRange;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.viz.gfe.core.DataManager; import com.raytheon.viz.gfe.core.DataManager;
import com.raytheon.viz.gfe.core.griddata.AbstractGridData; import com.raytheon.viz.gfe.core.griddata.AbstractGridData;
import com.raytheon.viz.gfe.core.griddata.IGridData; import com.raytheon.viz.gfe.core.griddata.IGridData;
import com.raytheon.viz.gfe.core.msgs.IGridDataChangedListener; import com.raytheon.viz.gfe.core.msgs.IGridDataChangedListener;
import com.raytheon.viz.gfe.core.msgs.IParmInventoryChangedListener; import com.raytheon.viz.gfe.core.msgs.IParmInventoryChangedListener;
import com.raytheon.viz.gfe.core.msgs.IParmListChangedListener; import com.raytheon.viz.gfe.core.msgs.IParmListChangedListener;
import com.raytheon.viz.gfe.core.parm.VCModule.DepParmInv; import com.raytheon.viz.gfe.core.parm.vcparm.VCModule;
import com.raytheon.viz.gfe.core.parm.VCModule.VCInventory; import com.raytheon.viz.gfe.core.parm.vcparm.VCModule.DepParmInv;
import com.raytheon.viz.gfe.core.parm.vcparm.VCModule.VCInventory;
/** /**
* A VC (virtual calculated) parm is virtual (non-database ifpServer) and is * A VC (virtual calculated) parm is virtual (non-database ifpServer) and is
@ -145,39 +145,32 @@ public class VCParm extends VParm implements IParmListChangedListener,
// statusHandler.handle(Priority.DEBUG, "gridDataChanged for: " + parmId // statusHandler.handle(Priority.DEBUG, "gridDataChanged for: " + parmId
// + " " + validTime); // + " " + validTime);
VizApp.runAsync(new Runnable() { for (VCInventory inv : this.vcInventory) {
for (DepParmInv dpi : inv.getDepParmInv()) {
@Override if (dpi.getParmID().equals(parmId)) {
public void run() { for (TimeRange tr : dpi.getTimes()) {
for (VCInventory inv : VCParm.this.vcInventory) { if (tr.getStart().equals(validTime.getStart())) {
for (DepParmInv dpi : inv.getDepParmInv()) { this.grids.acquireReadLock();
if (dpi.getParmID().equals(parmId)) { try {
for (TimeRange tr : dpi.getTimes()) { for (IGridData grid : this.grids) {
if (tr.getStart().equals(validTime.getStart())) { if (inv.getGridTimeRange().equals(
VCParm.this.grids.acquireReadLock(); grid.getGridTime())) {
try { grid.depopulate();
for (IGridData grid : VCParm.this.grids) { gridDataHasChanged(grid,
if (inv.getGridTimeRange().equals( getDisplayAttributes()
grid.getGridTime())) { .getDisplayMask(),
grid.depopulate(); false);
gridDataHasChanged( return;
grid,
getDisplayAttributes()
.getDisplayMask(),
false);
return;
}
}
} finally {
VCParm.this.grids.releaseReadLock();
} }
} }
} finally {
this.grids.releaseReadLock();
} }
} }
} }
} }
} }
}); }
} }
@ -196,13 +189,8 @@ public class VCParm extends VParm implements IParmListChangedListener,
// statusHandler.handle(Priority.DEBUG, // statusHandler.handle(Priority.DEBUG,
// "ParmListChangedMsg received: "); // "ParmListChangedMsg received: ");
VizApp.runAsync(new Runnable() { registerParmClients(parms, true);
@Override
public void run() {
registerParmClients(parms, true);
}
});
} }
/* /*
@ -222,13 +210,8 @@ public class VCParm extends VParm implements IParmListChangedListener,
// approach. // approach.
// statusHandler.debug("ParmInventoryChanged notification for: " // statusHandler.debug("ParmInventoryChanged notification for: "
// + getParmID().toString()); // + getParmID().toString());
VizApp.runAsync(new Runnable() {
@Override recalcInventory(true);
public void run() {
recalcInventory(true);
}
});
} }
/* /*
@ -366,7 +349,7 @@ public class VCParm extends VParm implements IParmListChangedListener,
// If there is an error in calcHistory() it // If there is an error in calcHistory() it
// will still give us one to use. So, we can just logProblem // will still give us one to use. So, we can just logProblem
if (!mod.isValid()) { if (!mod.isValid()) {
statusHandler.handle(Priority.PROBLEM, statusHandler.handle(Priority.EVENTB,
"Error in history calculation for " "Error in history calculation for "
+ getParmID().toString(), mod.getErrorString()); + getParmID().toString(), mod.getErrorString());
} }

View file

@ -0,0 +1,187 @@
/**
* 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.viz.gfe.core.parm.vcparm;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import jep.Jep;
import jep.JepException;
import com.raytheon.uf.common.dataplugin.gfe.discrete.DiscreteKey;
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.weather.WeatherKey;
import com.raytheon.uf.common.python.PyUtil;
import com.raytheon.viz.gfe.core.griddata.DiscreteGridData;
import com.raytheon.viz.gfe.core.griddata.IGridData;
import com.raytheon.viz.gfe.core.griddata.ScalarGridData;
import com.raytheon.viz.gfe.core.griddata.VectorGridData;
import com.raytheon.viz.gfe.core.griddata.WeatherGridData;
/**
* TODO Add Description
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 12, 2012 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class CalcVcModGridArg implements IVcModuleArgument {
// simulates the AWIPS1 tuple used, which contained an encoded time
// range (long[]), the grid data (IGridData), and a bit mask of valid
// points in the grid data (Grid2DBit).
private List<Object[]> argTuples;
public CalcVcModGridArg(List<Object[]> argTuples) {
this.argTuples = new ArrayList<Object[]>(argTuples);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.viz.gfe.core.parm.vcparm.IVcModuleArgument#evaluateArgument
* (jep.Jep)
*/
@Override
public Collection<String> evaluateArgument(final Jep instance,
String argName) throws JepException {
StringBuilder sb = new StringBuilder(768);
Collection<String> tempNames = new ArrayList<String>(
(argTuples.size() * 2));
sb.append(argName + " = [");
for (int i = 0; i < argTuples.size(); i++) {
Object[] tuple = argTuples.get(i);
long[] tr = (long[]) tuple[0];
IGridData gd = (IGridData) tuple[1];
Grid2DBit mask = (Grid2DBit) tuple[2];
sb.append("((");
sb.append(tr[0]);
sb.append("L, ");
sb.append(tr[1]);
sb.append("L), ");
tempNames.addAll(encodeGridAndMask(gd, mask, i, sb, instance));
sb.append(')');
if (i < argTuples.size() - 1) {
sb.append(',');
}
}
sb.append(']');
instance.eval(sb.toString());
return tempNames;
}
private Collection<String> encodeGridAndMask(IGridData gd, Grid2DBit mask,
int offset, StringBuilder sb, Jep jep) throws JepException {
StringBuilder jepString = new StringBuilder(256);
String prefix = gd.getParm().getParmID().getParmName()
+ Integer.toHexString(gd.getParm().getParmID().hashCode())
+ "_" + offset + "_";
Collection<String> tempGridNames = new ArrayList<String>(2);
if (gd instanceof ScalarGridData) {
ScalarGridData grid = (ScalarGridData) gd;
Grid2DFloat f = (grid.getScalarSlice()).getScalarGrid();
String name = prefix + "grid";
jep.setNumeric(name, f.getFloats(), f.getXdim(), f.getYdim());
jepString.append(name);
jepString.append(", ");
tempGridNames.add(name);
} else if (gd instanceof VectorGridData) {
VectorGridData grid = (VectorGridData) gd;
Grid2DFloat mag = (grid.getVectorSlice()).getMagGrid();
Grid2DFloat dir = (grid.getVectorSlice()).getDirGrid();
String magName = prefix + "Mag";
String dirName = prefix + "Dir";
jep.setNumeric(magName, mag.getFloats(), mag.getXdim(),
mag.getYdim());
jep.setNumeric(dirName, dir.getFloats(), dir.getXdim(),
dir.getYdim());
jepString.append('(');
jepString.append(magName);
jepString.append(',');
jepString.append(dirName);
jepString.append("), ");
tempGridNames.add(magName);
tempGridNames.add(dirName);
} else if (gd instanceof WeatherGridData) {
WeatherGridData grid = (WeatherGridData) gd;
Grid2DByte bytes = grid.getWeatherSlice().getWeatherGrid();
String name = prefix + "grid";
jep.setNumeric(name, bytes.getBytes(), bytes.getXdim(),
bytes.getYdim());
jepString.append('(');
jepString.append(name);
jepString.append(',');
WeatherKey[] keys = grid.getWeatherSlice().getKeys();
ArrayList<String> stringKeys = new ArrayList<String>(keys.length);
for (WeatherKey k : keys) {
stringKeys.add(k.toString());
}
jepString.append(PyUtil.listToTuple(stringKeys));
jepString.append("), ");
tempGridNames.add(name);
} else if (gd instanceof DiscreteGridData) {
DiscreteGridData grid = (DiscreteGridData) gd;
Grid2DByte bytes = grid.getDiscreteSlice().getDiscreteGrid();
String name = prefix + "grid";
jep.setNumeric(name, bytes.getBytes(), bytes.getXdim(),
bytes.getYdim());
jepString.append('(');
jepString.append(name);
jepString.append(',');
DiscreteKey[] keys = grid.getDiscreteSlice().getKey();
ArrayList<String> stringKeys = new ArrayList<String>(keys.length);
for (DiscreteKey k : keys) {
stringKeys.add(k.toString());
}
jepString.append(PyUtil.listToTuple(stringKeys));
jepString.append("), ");
tempGridNames.add(name);
}
String maskName = prefix + "mask";
jep.setNumeric(maskName, mask.getBytes(), mask.getXdim(),
mask.getYdim());
jepString.append(maskName);
sb.append(jepString);
tempGridNames.add(maskName);
return tempGridNames;
}
}

View file

@ -0,0 +1,99 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.viz.gfe.core.parm.vcparm;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import jep.Jep;
import jep.JepException;
/**
* TODO Add Description
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 12, 2012 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class CalcVcModHistoryArg implements IVcModuleArgument {
// simulates the AWIPS1 tuple used, which contained an encoded time
// range (long[]) and the list of GridDataHistory entries that
// correspond to that grid time range (List<String>).
private List<Object[]> histEntries;
public CalcVcModHistoryArg(List<Object[]> histEntries) {
this.histEntries = new ArrayList<Object[]>(histEntries);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.viz.gfe.core.parm.vcparm.IVcModuleArgument#evaluateArgument
* (jep.Jep)
*/
@Override
public Collection<String> evaluateArgument(final Jep instance,
String argName) throws JepException {
StringBuilder sb = new StringBuilder(1024);
sb.append(argName + " = [");
for (int i = 0; i < histEntries.size(); i++) {
Object[] timeAndHistList = histEntries.get(i);
long[] tr = (long[]) timeAndHistList[0];
@SuppressWarnings("unchecked")
List<String> hist = (List<String>) timeAndHistList[1];
sb.append("((");
sb.append(tr[0]);
sb.append("L, ");
sb.append(tr[1]);
sb.append("L), [");
for (int j = 0; j < hist.size(); j++) {
sb.append("\"" + hist.get(j) + "\"");
if (j < hist.size() - 1) {
sb.append(',');
}
}
sb.append("])");
if (i < histEntries.size() - 1) {
sb.append(',');
}
}
sb.append(']');
instance.eval(sb.toString());
return Collections.emptyList();
}
}

View file

@ -0,0 +1,85 @@
/**
* 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.viz.gfe.core.parm.vcparm;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import jep.Jep;
import jep.JepException;
/**
* TODO Add Description
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 12, 2012 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class GetVcModInventoryArg implements IVcModuleArgument {
public List<long[]> trs;
public GetVcModInventoryArg(List<long[]> trs) {
this.trs = new ArrayList<long[]>(trs);
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.viz.gfe.core.parm.vcparm.IVcModuleArgument#evaluateArgument
* (jep.Jep, java.lang.String)
*/
@Override
public Collection<String> evaluateArgument(final Jep instance,
String argName) throws JepException {
StringBuilder sb = new StringBuilder(512);
sb.append(argName + " = [");
for (int i = 0; i < trs.size(); i++) {
long[] tuple = trs.get(i);
sb.append('(');
sb.append(tuple[0]);
sb.append("L, ");
sb.append(tuple[1]);
sb.append("L)");
if (i < trs.size() - 1) {
sb.append(',');
}
}
sb.append(']');
instance.eval(sb.toString());
return Collections.emptyList();
}
}

View file

@ -17,9 +17,12 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for * See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information. * further licensing information.
**/ **/
package com.raytheon.viz.gfe.procedures; package com.raytheon.viz.gfe.core.parm.vcparm;
import com.raytheon.uf.viz.core.jobs.IRequestCompleteListener; import java.util.Collection;
import jep.Jep;
import jep.JepException;
/** /**
* TODO Add Description * TODO Add Description
@ -27,34 +30,19 @@ import com.raytheon.uf.viz.core.jobs.IRequestCompleteListener;
* <pre> * <pre>
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
*
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Nov 30, 2011 rferrel Initial creation * Jan 12, 2012 dgilling Initial creation
* *
* </pre> * </pre>
* *
* @author rferrel * @author dgilling
* @version 1.0 * @version 1.0
*/ */
public class ProcedureFinishedListener implements public interface IVcModuleArgument {
IRequestCompleteListener<Object> {
private boolean done = false; public Collection<String> evaluateArgument(final Jep instance, String argName) throws JepException;
private Object result;
@Override
public void requestComplete(Object result) {
done = true;
this.result = result;
}
public boolean isDone() {
return done;
}
public Object getResult() {
return result;
}
} }

View file

@ -0,0 +1,564 @@
/**
* 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.viz.gfe.core.parm.vcparm;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import jep.JepException;
import com.raytheon.uf.common.dataplugin.gfe.GridDataHistory;
import com.raytheon.uf.common.dataplugin.gfe.GridDataHistory.OriginType;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID.DataType;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GFERecord.GridType;
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.db.objects.TimeConstraints;
import com.raytheon.uf.common.dataplugin.gfe.discrete.DiscreteKey;
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.slice.DiscreteGridSlice;
import com.raytheon.uf.common.dataplugin.gfe.slice.IGridSlice;
import com.raytheon.uf.common.dataplugin.gfe.slice.ScalarGridSlice;
import com.raytheon.uf.common.dataplugin.gfe.slice.VectorGridSlice;
import com.raytheon.uf.common.dataplugin.gfe.slice.WeatherGridSlice;
import com.raytheon.uf.common.dataplugin.gfe.weather.WeatherKey;
import com.raytheon.uf.common.python.PyConstants;
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.viz.gfe.GFEException;
import com.raytheon.viz.gfe.core.DataManager;
import com.raytheon.viz.gfe.core.IParmManager;
import com.raytheon.viz.gfe.core.griddata.IGridData;
import com.raytheon.viz.gfe.core.parm.Parm;
/**
* Virtual Calculated Module. Serves as interface between the VCParm and the
* actual python algorithms.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Oct 17, 2011 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class VCModule {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(VCModule.class);
public class DepParmInv {
private ParmID parmID;
private List<TimeRange> times;
public DepParmInv(ParmID pid, List<TimeRange> trs) {
this.parmID = pid;
this.times = trs;
}
public ParmID getParmID() {
return parmID;
}
public List<TimeRange> getTimes() {
return times;
}
@Override
public String toString() {
StringBuilder tmp = new StringBuilder();
tmp.append("(pid=");
tmp.append(parmID.toString());
tmp.append(",times=");
tmp.append(times.toString());
tmp.append(')');
return tmp.toString();
}
}
public class VCInventory {
private TimeRange gridTimeRange;
private List<DepParmInv> depParmInv;
public VCInventory(TimeRange gridTimeRange, List<DepParmInv> depParmInv) {
this.gridTimeRange = gridTimeRange;
this.depParmInv = depParmInv;
}
public TimeRange getGridTimeRange() {
return gridTimeRange;
}
public List<DepParmInv> getDepParmInv() {
return depParmInv;
}
@Override
public String toString() {
StringBuilder tmp = new StringBuilder();
tmp.append("gtr=");
tmp.append(gridTimeRange.toString());
tmp.append(",dpi=");
tmp.append(depParmInv.toString());
return tmp.toString();
}
}
private Throwable error;
private GridParmInfo gpi;
private VCModuleJob python;
private DataManager dataMgr;
private IParmManager parmMgr;
private String id;
public VCModule(DataManager dataMgr, IParmManager parmMgr, final File module) {
this.dataMgr = dataMgr;
this.parmMgr = parmMgr;
this.id = module.getName().split("\\.(?=[^\\.]+$)")[0];
this.python = new VCModuleJob(this.dataMgr);
this.python.schedule();
}
public void dispose() {
this.python.cancel();
}
public boolean isValid() {
return (this.error == null);
}
public Throwable getErrorString() {
Throwable rVal = error;
error = null;
return rVal;
}
private List<String> getMethodArgs(String method) throws Throwable {
// statusHandler.debug("getMethodArgs: " + id);
Map<String, Object> args = new HashMap<String, Object>();
args.put(PyConstants.METHOD_NAME, method);
VCModuleRequest req = new VCModuleRequest(id, "getMethodArgs", args);
python.enqueue(req);
Object result = req.getResult();
String[] argNames = (String[]) result;
return Arrays.asList(argNames);
}
public Collection<ParmID> dependentParms() {
Collection<ParmID> rval = new ArrayList<ParmID>();
try {
Collection<String> parameters = getMethodArgs("getInventory");
for (String parmName : parameters) {
ParmID pid = parmMgr.fromExpression(parmName);
if (pid.isValid()) {
rval.add(pid);
} else {
throw new IllegalArgumentException(
"Can't find Weather Element for " + parmName);
}
}
} catch (Throwable t) {
error = t;
// statusHandler.handle(Priority.DEBUG, "dependentParms: " + id
// + " error", t);
return Collections.emptyList();
}
return rval;
}
private long[] encodeTR(final TimeRange tr) {
long[] ptime = { tr.getStart().getTime(), tr.getEnd().getTime() };
return ptime;
}
private List<long[]> pyInventory(Parm p) {
IGridData[] gridInv = p.getGridInventory();
List<long[]> inv = new ArrayList<long[]>(gridInv.length);
for (IGridData gd : gridInv) {
inv.add(encodeTR(gd.getGridTime()));
}
return inv;
}
private Object[] encodeGD(IGridData gd) {
Object[] item = new Object[3];
item[0] = encodeTR(gd.getGridTime());
// since we have to go through a bunch of hoops in VCModuleScript to get
// the IGridData in python-useable format, no need doing anything here
// but storing the data
item[1] = gd;
// add a mask indicating the set of valid points. Note for all data
// other than ISC data, the mask is all points. ISC data values depend
// upon the masking of the Grid Data History.
Grid2DBit validBits;
if (gd.getParm().isIscParm()) {
List<String> hs = gd.getHistorySites();
validBits = dataMgr.getRefManager().siteGridpoints(hs, true);
} else {
validBits = dataMgr.getRefManager().fullRefSet().getGrid();
}
item[2] = validBits;
return item;
}
@SuppressWarnings("unchecked")
private IGridSlice decodeGD(Object o, VCInventory invEntry)
throws GFEException, JepException {
TimeRange tr = invEntry.getGridTimeRange();
List<GridDataHistory> gdh = calcHistory(invEntry);
if (!isValid()) {
throw new GFEException(getErrorString());
}
GridParmInfo gpi = getGpi();
switch (gpi.getGridType()) {
case SCALAR:
return new ScalarGridSlice(tr, gpi, gdh, (Grid2DFloat) o);
case VECTOR:
Grid2DFloat[] s = (Grid2DFloat[]) o;
return new VectorGridSlice(tr, gpi, gdh, s[0], s[1]);
case WEATHER:
Object[] wxGrid = (Object[]) o;
List<WeatherKey> key = new ArrayList<WeatherKey>();
List<String> pkey = (List<String>) wxGrid[1];
for (String wKey : pkey) {
key.add(new WeatherKey(gpi.getParmID().getDbId().getSiteId(),
wKey));
}
return new WeatherGridSlice(tr, gpi, gdh, (Grid2DByte) wxGrid[0],
key);
case DISCRETE:
Object[] discGrid = (Object[]) o;
List<DiscreteKey> keys = new ArrayList<DiscreteKey>();
List<String> pkeys = (List<String>) discGrid[1];
for (String dKey : pkeys) {
keys.add(new DiscreteKey(gpi.getParmID().getDbId().getSiteId(),
dKey, gpi.getParmID()));
}
return new DiscreteGridSlice(tr, gpi, gdh,
(Grid2DByte) discGrid[0], keys);
default:
statusHandler.handle(Priority.EVENTB, "Unknown parm type: "
+ gpi.getGridType().toString());
break;
}
return null;
}
@SuppressWarnings("unchecked")
private TimeRange decodeTR(Object o) {
List<Long> ptr = (List<Long>) o;
return new TimeRange(ptr.get(0), ptr.get(1));
}
@SuppressWarnings("unchecked")
public List<VCInventory> getInventory() {
// statusHandler.debug("getInventory: " + id);
final List<VCInventory> rval = new ArrayList<VCInventory>();
try {
List<String> args = getMethodArgs("getInventory");
Map<String, Object> cargs = new HashMap<String, Object>(args.size());
List<Parm> pargs = new ArrayList<Parm>(args.size());
for (String arg : args) {
ParmID pid = parmMgr.fromExpression(arg);
Parm tp = parmMgr.getParm(pid);
if (tp == null) {
throw new IllegalArgumentException(
"Can't locate Weather Element: " + arg);
}
cargs.put(arg, new GetVcModInventoryArg(pyInventory(tp)));
pargs.add(tp);
}
VCModuleRequest req = new VCModuleRequest(id, "getInventory", cargs);
python.enqueue(req);
Object reqResult = req.getResult();
// what's returned from the script here is a list of tuples.
// Each tuple contains:
// 1. A TimeRange.
// 2. A list of TimeRanges that correspond to the Fcst grids that
// should be used for that time
// 3. A list of TimeRanges that correspond to the ISC grids that
// should be used for that time
List<List<Object>> result = (List<List<Object>>) reqResult;
for (List<Object> item : result) {
List<DepParmInv> dpi = new ArrayList<DepParmInv>();
for (int i = 1; i < item.size(); i++) {
List<Object> ditem = (List<Object>) item.get(i);
List<TimeRange> trs = new ArrayList<TimeRange>(ditem.size());
for (Object tr : ditem) {
trs.add(decodeTR(tr));
}
dpi.add(new DepParmInv(pargs.get(i - 1).getParmID(), trs));
}
rval.add(new VCInventory(decodeTR(item.get(0)), dpi));
}
} catch (Throwable t) {
error = t;
}
return rval;
}
private List<String> encodeGDH(final List<GridDataHistory> gdh) {
List<String> l = new ArrayList<String>(gdh.size());
for (GridDataHistory hist : gdh) {
l.add(hist.getCodedString());
}
return l;
}
@SuppressWarnings("unchecked")
private List<GridDataHistory> decodeGDH(final Object o) {
List<String> s = (List<String>) o;
List<GridDataHistory> rval = new ArrayList<GridDataHistory>(s.size());
for (String entry : s) {
GridDataHistory gdh = new GridDataHistory(entry);
rval.add(gdh);
}
return rval;
}
@SuppressWarnings("unchecked")
public List<GridDataHistory> calcHistory(final VCInventory invEntry) {
// statusHandler.debug("calcHistory: " + id + " " +
// invEntry.toString());
// commenting out this python call because it is completely
// superfluous--all the baseline VCMODULE files have a calcHistory
// method so there's no point in checking and it saves a call into the
// VCModuleJob queue. If at some point there's a desire to support
// user/site-defined modules, this check should probably return.
// TODO: Reimplement using a call to BaseGfePyController.hasMethod().
// boolean hasattr = false;
// try {
// hasattr = module.hasAttr("calcHistory");
// } catch (JepException e) {
// // swallow exception and move on
// statusHandler.handle(Priority.EVENTB,
// "Could not retrieve calcHistory attribute", e);
// }
// if (hasattr) {
try {
final List<DepParmInv> dpi = invEntry.getDepParmInv();
List<String> args = getMethodArgs("calcHistory");
Map<String, Object> cargs = new HashMap<String, Object>(args.size());
for (String arg : args) {
Parm tp = parmMgr.getParm(parmMgr.fromExpression(arg));
if (tp != null) {
List<Object[]> l = new ArrayList<Object[]>();
for (DepParmInv dpiEntry : dpi) {
if (dpiEntry.getParmID().equals(tp.getParmID())) {
for (TimeRange tr : dpiEntry.getTimes()) {
IGridData gd = tp
.overlappingGrid(tr.getStart());
if (gd == null) {
throw new IllegalArgumentException(
"Unable to retrieve overlapping grid for parm: "
+ tp.getParmID().toString()
+ " for time: "
+ tr.toString());
}
Object[] tl = new Object[2];
tl[0] = encodeTR(gd.getGridTime());
tl[1] = encodeGDH(Arrays
.asList(gd.getHistory()));
l.add(tl);
}
}
}
cargs.put(arg, new CalcVcModHistoryArg(l));
} else {
throw new IllegalArgumentException("Unable to find parm "
+ arg);
}
}
VCModuleRequest req = new VCModuleRequest(id, "calcHistory", cargs);
python.enqueue(req);
Object reqResult = req.getResult();
List<String> result = (List<String>) reqResult;
return decodeGDH(result);
} catch (Throwable t) {
error = t;
}
// }
// the default
return Arrays.asList(new GridDataHistory(OriginType.CALCULATED,
getGpi().getParmID(), invEntry.getGridTimeRange()));
}
public IGridSlice calcGrid(VCInventory invEntry) {
// statusHandler.debug("calcGrid: " + id + " " + invEntry.toString());
final List<DepParmInv> dpi = invEntry.getDepParmInv();
try {
List<String> args = getMethodArgs("calcGrid");
Map<String, Object> cargs = new HashMap<String, Object>(args.size());
for (String arg : args) {
ParmID id = parmMgr.fromExpression(arg);
Parm tp = parmMgr.getParm(id);
if (tp != null) {
List<Object[]> l = new ArrayList<Object[]>();
for (DepParmInv dpiEntry : dpi) {
if (dpiEntry.getParmID().equals(tp.getParmID())) {
for (TimeRange tr : dpiEntry.getTimes()) {
IGridData gd = tp
.overlappingGrid(tr.getStart());
if (gd == null) {
throw new IllegalArgumentException(
"Unable to retrieve overlapping grid for parm: "
+ tp.getParmID().toString()
+ " for time: "
+ tr.toString());
}
l.add(encodeGD(gd));
}
}
}
cargs.put(arg, new CalcVcModGridArg(l));
} else {
throw new IllegalArgumentException("Unable to find parm "
+ arg);
}
}
VCModuleRequest req = new VCModuleRequest(id, "calcGrid", cargs,
getGpi().getGridType());
python.enqueue(req);
Object reqResult = req.getResult();
return decodeGD(reqResult, invEntry);
} catch (Throwable t) {
error = t;
}
return null;
}
@SuppressWarnings("unchecked")
public GridParmInfo getGpi() {
if (this.gpi != null) {
return this.gpi;
}
// statusHandler.debug("getGpi(): " + id);
try {
VCModuleRequest req = new VCModuleRequest(id, "getWEInfo", null);
python.enqueue(req);
Object reqResult = req.getResult();
List<List<Object>> result = (List<List<Object>>) reqResult;
List<Object> s = result.get(1);
String site = parmMgr.getMutableDatabase().getSiteId();
DatabaseID dbid = new DatabaseID(site, DataType.GRID, s.get(1)
.toString(), s.get(0).toString(), DatabaseID.NO_MODEL_TIME);
s = result.get(2);
TimeConstraints tc = new TimeConstraints((Integer) s.get(0),
(Integer) s.get(1), (Integer) s.get(2));
s = result.get(0);
ParmID pid = new ParmID(s.get(0).toString(), dbid);
GridType type = GridType.NONE;
try {
type = GridType.valueOf(s.get(1).toString().toUpperCase());
} catch (IllegalArgumentException e) {
// just want to swallow the exception here as we've already
// defaulted type to NONE
statusHandler.handle(Priority.EVENTB,
"Invalid GridType specified: " + s.get(1).toString());
}
// Double check for all the various valid parm lengths from
// serverConfig
GridParmInfo gpi = new GridParmInfo(pid,
parmMgr.compositeGridLocation(), type, s.get(2).toString(),
s.get(3).toString(), (Float) s.get(5), (Float) s.get(4),
(Integer) s.get(6), false, tc, (Boolean) s.get(7));
this.gpi = gpi;
} catch (Throwable t) {
error = t;
}
return this.gpi;
}
}

View file

@ -0,0 +1,234 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.viz.gfe.core.parm.vcparm;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import jep.JepException;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GFERecord.GridType;
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.python.GfePyIncludeUtil;
import com.raytheon.uf.common.python.PyConstants;
import com.raytheon.viz.gfe.BaseGfePyController;
import com.raytheon.viz.gfe.core.DataManager;
/**
* A PythonScript subclass that replaces the Python/C++ interface that was
* available to AWIPS1's <code>VCModule</code> class. Primarily used for
* Python->Java data type conversions.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 17, 2011 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class VCModuleController extends BaseGfePyController {
private static final String CLASS_NAME = "VCParm";
private List<String> tempGridNames;
/**
* Constructor.
*
* @param aFilePath
* the path to the python script
* @param anIncludePath
* the python include path, with multiple directories being
* separated by ":"
* @param aClassLoader
* the Java classloader to use for importing Java classes inside
* python
* @param dataMgr
* TODO
* @throws JepException
*/
protected VCModuleController(String aFilePath, String anIncludePath,
ClassLoader aClassLoader, DataManager dataMgr) throws JepException {
super(aFilePath, anIncludePath, aClassLoader, dataMgr, CLASS_NAME);
this.tempGridNames = new ArrayList<String>();
String scriptPath = GfePyIncludeUtil.getVCModulesIncludePath();
jep.eval(INTERFACE + " = VCModuleInterface('" + scriptPath + "')");
}
/**
* Retrieves a list of argument names for the specified Python method.
*
* @param moduleName
* TODO
* @param method
* The name of the method.
* @return List of argument names for the specified Python method, except
* for "self".
* @throws JepException
*/
public List<String> getMethodArgs(String moduleName, String method)
throws JepException {
String[] argNames = getMethodArguments(moduleName, method);
List<String> retVal = new ArrayList<String>(argNames.length);
for (String arg : argNames) {
if (!arg.equals("self")) {
retVal.add(arg);
}
}
return retVal;
}
public Object executeMethod(String moduleName, String methodName,
Map<String, Object> args, GridType type) throws JepException {
if (!isInstantiated(moduleName)) {
instantiatePythonTool(moduleName);
}
args.put(PyConstants.METHOD_NAME, methodName);
args.put(PyConstants.MODULE_NAME, moduleName);
args.put(PyConstants.CLASS_NAME, pythonClassName);
internalExecute("runMethod", INTERFACE, args);
Object obj = null;
if (!methodName.equals("calcGrid")) {
jep.eval(RESULT + " = JUtil.pyValToJavaObj(" + RESULT + ")");
obj = jep.getValue(RESULT);
} else {
obj = decodeGD(type);
}
jep.eval(RESULT + " = None");
return obj;
}
/**
* Override of the <code>evaluateArgument</code> method which handles the
* custom argument structures defined in <code>VCModule</code>. Important so
* that we can convert the Java datatypes to Python native objects (and
* numpy arrays for the grids).
*
* @param argName
* The argument name.
* @param argValue
* the value of the argument
*
* @see com.raytheon.uf.common.python.PythonInterpreter#evaluateArgument(java
* .lang.String, java.lang.Object)
*/
@Override
protected void evaluateArgument(String argName, Object argValue)
throws JepException {
if (argValue instanceof IVcModuleArgument) {
IVcModuleArgument castedArg = (IVcModuleArgument) argValue;
Collection<String> tempGrids = castedArg.evaluateArgument(jep,
argName);
tempGridNames.addAll(tempGrids);
} else {
super.evaluateArgument(argName, argValue);
}
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.common.python.PythonScript#cleanupArgs(java.util.List)
*/
@Override
protected void cleanupArgs(List<String> args) throws JepException {
super.cleanupArgs(args);
for (String gridName : tempGridNames) {
jep.eval("del " + gridName);
}
tempGridNames.clear();
}
private Object decodeGD(GridType type) throws JepException {
Object result = null;
boolean resultFound = (Boolean) jep.getValue(RESULT + " is not None");
if (resultFound) {
int xDim, yDim = 0;
switch (type) {
case SCALAR:
float[] scalarData = (float[]) jep.getValue(RESULT
+ ".astype(numpy.float32)");
xDim = (Integer) jep.getValue(RESULT + ".shape[1]");
yDim = (Integer) jep.getValue(RESULT + ".shape[0]");
result = new Grid2DFloat(xDim, yDim, scalarData);
break;
case VECTOR:
float[] mag = (float[]) jep.getValue(RESULT
+ "[0].astype(numpy.float32)");
float[] dir = (float[]) jep.getValue(RESULT
+ "[1].astype(numpy.float32)");
xDim = (Integer) jep.getValue(RESULT + "[0].shape[1]");
yDim = (Integer) jep.getValue(RESULT + "[0].shape[0]");
Grid2DFloat magGrid = new Grid2DFloat(xDim, yDim, mag);
Grid2DFloat dirGrid = new Grid2DFloat(xDim, yDim, dir);
result = new Grid2DFloat[] { magGrid, dirGrid };
break;
case WEATHER:
case DISCRETE:
byte[] bytes = (byte[]) jep.getValue(RESULT
+ "[0].astype(numpy.int8)");
String[] keys = (String[]) jep.getValue(RESULT + "[1]");
xDim = (Integer) jep.getValue(RESULT + "[0].shape[1]");
yDim = (Integer) jep.getValue(RESULT + "[0].shape[0]");
Grid2DByte grid = new Grid2DByte(xDim, yDim, bytes);
List<String> keysList = new ArrayList<String>();
Collections.addAll(keysList, keys);
result = new Object[] { grid, keysList };
break;
}
}
return result;
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.viz.gfe.BaseGfePyController#instantiatePythonTool(java.lang
* .String)
*/
@Override
public void instantiatePythonTool(String moduleName) throws JepException {
Map<String, Object> instanceMap = getStarterMap(moduleName);
execute("instantiate", INTERFACE, instanceMap);
}
}

View file

@ -0,0 +1,80 @@
/**
* 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.viz.gfe.core.parm.vcparm;
import jep.JepException;
import com.raytheon.uf.common.dataplugin.gfe.python.GfePyIncludeUtil;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.python.PyUtil;
import com.raytheon.uf.common.util.FileUtil;
import com.raytheon.viz.gfe.core.DataManager;
/**
* Factory for the <code>VCModuleController</code> class.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec 20, 2011 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class VCModuleControllerFactory {
/**
* A private constructor so that Java does not attempt to create one for us.
* As this class should not be instantiated, do not attempt to ever call
* this constructor; it will simply throw an AssertionError.
*/
private VCModuleControllerFactory() {
throw new AssertionError();
}
private static String getScriptPath() {
LocalizationContext baseCtx = PathManagerFactory.getPathManager()
.getContext(LocalizationType.COMMON_STATIC,
LocalizationLevel.BASE);
String scriptPath = GfePyIncludeUtil.getVCModUtilsLF(baseCtx).getFile()
.getPath();
return FileUtil.join(scriptPath, "VCModuleInterface.py");
}
public static VCModuleController buildInstance(DataManager dataMgr)
throws JepException {
String includePath = PyUtil.buildJepIncludePath(
GfePyIncludeUtil.getVCModUtilsIncludePath(),
GfePyIncludeUtil.getVCModulesIncludePath(),
GfePyIncludeUtil.getCommonPythonIncludePath());
return new VCModuleController(getScriptPath(), includePath,
VCModuleControllerFactory.class.getClassLoader(), dataMgr);
}
}

View file

@ -0,0 +1,134 @@
/**
* 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.viz.gfe.core.parm.vcparm;
import java.util.concurrent.TimeUnit;
import jep.JepException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import com.raytheon.uf.common.dataplugin.gfe.StatusConstants;
import com.raytheon.uf.common.python.PyConstants;
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.jobs.AbstractQueueJob;
import com.raytheon.viz.gfe.core.DataManager;
/**
* <code>Job</code> which allows <code>VCModule</code> python calls to run off a
* common thread.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec 20, 2011 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class VCModuleJob extends AbstractQueueJob<VCModuleRequest> {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(VCModuleJob.class);
private VCModuleController python = null;
private DataManager dataMgr;
public VCModuleJob(DataManager dataMgr) {
super("GFE Virtual ISC Python executor");
setSystem(true);
this.dataMgr = dataMgr;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.
* IProgressMonitor)
*/
@Override
protected IStatus run(IProgressMonitor monitor) {
try {
try {
python = VCModuleControllerFactory.buildInstance(dataMgr);
} catch (JepException e) {
return new Status(IStatus.ERROR, StatusConstants.PLUGIN_ID,
"Error initializing VCModule python object", e);
}
while (!monitor.isCanceled()) {
VCModuleRequest request = null;
try {
request = queue.poll(1000L, TimeUnit.MILLISECONDS);
if (request != null) {
processRequest(request);
}
// TODO: Reinstate this call, if we ever want to support
// dynamic editing of VCMODULE files through the
// Localization perspective.
// python.processFileUpdates();
} catch (InterruptedException e) {
statusHandler.handle(Priority.PROBLEM,
"VC Module python thread interrupted.", e);
break;
} catch (Throwable t) {
// statusHandler.handle(Priority.DEBUG,
// "Error running VCModule method.", t);
request.setResult(t);
}
}
} finally {
if (python != null) {
python.dispose();
python = null;
}
}
return Status.OK_STATUS;
}
private void processRequest(VCModuleRequest request) throws JepException {
Object result = null;
if (request.getMethodName().equals("getMethodArgs")) {
result = python.getMethodArguments(request.getModuleName(),
(String) request.getArgMap().get(PyConstants.METHOD_NAME));
} else {
result = python.executeMethod(request.getModuleName(),
request.getMethodName(), request.getJepArgs(),
request.getType());
}
request.setResult(result);
}
}

View file

@ -0,0 +1,134 @@
/**
* 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.viz.gfe.core.parm.vcparm;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Semaphore;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GFERecord.GridType;
import com.raytheon.uf.viz.core.jobs.QueueJobRequest;
/**
* TODO Add Description
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec 20, 2011 dgilling Initial creation
*
* </pre>
*
* @author dgilling
* @version 1.0
*/
public class VCModuleRequest extends QueueJobRequest<Object> {
private String moduleName;
private String methodName;
private Map<String, Object> argMap;
private GridType type;
private Object result;
private Semaphore completionMutex;
public VCModuleRequest(String moduleName, String method,
Map<String, Object> argMap) {
this(moduleName, method, argMap, null);
}
public VCModuleRequest(String moduleName, String method,
Map<String, Object> argMap, GridType type) {
this.moduleName = moduleName;
this.methodName = method;
this.argMap = argMap;
this.type = type;
this.completionMutex = new Semaphore(1);
// always leave the mutex locked until we're ready to return a result
try {
this.completionMutex.acquire();
} catch (InterruptedException e) {
// don't care
}
}
public String getModuleName() {
return moduleName;
}
public String getMethodName() {
return methodName;
}
public Map<String, Object> getArgMap() {
return argMap;
}
public Map<String, Object> getJepArgs() {
if (argMap != null) {
return new HashMap<String, Object>(argMap);
} else {
return new HashMap<String, Object>();
}
}
public GridType getType() {
return type;
}
/**
* Returns the result from executing this request. Because
* <code>VCModuleRequest</code>s are executed asynchronously, this method
* blocks until the <code>VCModule</code> method has completed execution.
*
* @return The result of executing the request.
* @throws Throwable
* If an exception occurred while processing the request.
*/
public Object getResult() throws Throwable {
try {
// because we initially locked the mutex in the constructor, this
// will block until something has called setResult
completionMutex.acquire();
if (!(result instanceof Throwable)) {
return result;
} else {
throw (Throwable) result;
}
} catch (InterruptedException e) {
throw e;
} finally {
completionMutex.release();
}
}
public void setResult(Object result) {
this.result = result;
completionMutex.release();
}
}

View file

@ -51,7 +51,6 @@ import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.time.SimulatedTime; import com.raytheon.uf.common.time.SimulatedTime;
import com.raytheon.uf.common.time.TimeRange; import com.raytheon.uf.common.time.TimeRange;
import com.raytheon.uf.viz.core.RGBColors; import com.raytheon.uf.viz.core.RGBColors;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.drawables.FillPatterns; import com.raytheon.uf.viz.core.drawables.FillPatterns;
import com.raytheon.viz.gfe.Activator; import com.raytheon.viz.gfe.Activator;
import com.raytheon.viz.gfe.GFEPreference; import com.raytheon.viz.gfe.GFEPreference;
@ -96,7 +95,7 @@ public class GridBar implements IMessageClient, IParmInventoryChangedListener,
IGridVisibilityChangedListener, IActivatedParmChangedListener, IGridVisibilityChangedListener, IActivatedParmChangedListener,
IGridDataChangedListener, ISelectionTimeRangeChangedListener, IGridDataChangedListener, ISelectionTimeRangeChangedListener,
IParameterSelectionChangedListener, ILockTableChangedListener, IParameterSelectionChangedListener, ILockTableChangedListener,
IParmIDChangedListener, DisposeListener, Runnable IParmIDChangedListener, DisposeListener
{ {
private static final transient IUFStatusHandler statusHandler = UFStatus private static final transient IUFStatusHandler statusHandler = UFStatus
@ -309,6 +308,7 @@ public class GridBar implements IMessageClient, IParmInventoryChangedListener,
this.canvas.addDisposeListener(this); this.canvas.addDisposeListener(this);
} }
@Override
public void widgetDisposed(DisposeEvent e) { public void widgetDisposed(DisposeEvent e) {
this.dispose(); this.dispose();
} }
@ -1339,20 +1339,7 @@ public class GridBar implements IMessageClient, IParmInventoryChangedListener,
} }
public void redraw() { public void redraw() {
if (this.display.getThread() == Thread.currentThread()) { canvas.markDirty(getBounds());
run();
} else {
VizApp.runAsync(this);
}
}
@Override
public void run() {
if (!canvas.isDisposed()) {
Rectangle bounds = getBounds();
canvas.redraw(bounds.x, bounds.y, bounds.width, bounds.height, true);
// this.redrawCount++;
}
} }
/** /**

View file

@ -31,7 +31,6 @@ import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator; import org.eclipse.jface.action.Separator;
import org.eclipse.swt.SWT; import org.eclipse.swt.SWT;
@ -51,6 +50,7 @@ import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.progress.UIJob;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GFERecord.GridType; import com.raytheon.uf.common.dataplugin.gfe.db.objects.GFERecord.GridType;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.TimeConstraints; import com.raytheon.uf.common.dataplugin.gfe.db.objects.TimeConstraints;
@ -125,7 +125,7 @@ public class GridCanvas extends Canvas implements IMessageClient {
private static Color SEPARATOR_COLOR = new Color(Display.getDefault(), private static Color SEPARATOR_COLOR = new Color(Display.getDefault(),
RGBColors.getRGBColor("CornflowerBlue")); RGBColors.getRGBColor("CornflowerBlue"));
private class ScrollJob extends Job { private class ScrollJob extends UIJob {
private int increment = 0; private int increment = 0;
/** /**
@ -138,34 +138,72 @@ public class GridCanvas extends Canvas implements IMessageClient {
public ScrollJob() { public ScrollJob() {
super("GridCanvasScrollJob"); super("GridCanvasScrollJob");
setSystem(true);
} }
@Override @Override
protected IStatus run(IProgressMonitor monitor) { public IStatus runInUIThread(IProgressMonitor monitor) {
VizApp.runSync(new Runnable() { Point p = scrolledComp.getOrigin();
if ((increment < 0 && p.y > 0)
|| (increment > 0 && p.y < (getSize().y - scrolledComp
.getClientArea().height))) {
p.y += increment;
scrolledComp.setOrigin(p);
@Override if (increment < 0) {
public void run() { selection.y += increment;
Point p = scrolledComp.getOrigin(); }
if ((increment < 0 && p.y > 0) selection.height += Math.abs(increment);
|| (increment > 0 && p.y < (getSize().y - scrolledComp setSelection(selection);
.getClientArea().height))) {
p.y += increment;
scrolledComp.setOrigin(p);
if (increment < 0) { schedule(100);
selection.y += increment; } else {
} cancel();
selection.height += Math.abs(increment); }
setSelection(selection); return Status.OK_STATUS;
}
}
schedule(100); private class RepaintJob extends UIJob {
} else { private Rectangle dirtyRect;
cancel();
} public RepaintJob() {
super("GridCanvasRepaintJob");
setSystem(true);
}
public void markDirty(Rectangle rect) {
synchronized (this) {
if (this.dirtyRect != null) {
this.dirtyRect = this.dirtyRect.union(rect);
} else {
this.dirtyRect = rect;
}
}
this.schedule();
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime
* .IProgressMonitor)
*/
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
if (!GridCanvas.this.isDisposed() && dirtyRect != null) {
Rectangle rect;
synchronized (this) {
rect = dirtyRect;
dirtyRect = null;
} }
}); GridCanvas.this.redraw(rect.x, rect.y, rect.width, rect.height,
true);
}
return Status.OK_STATUS; return Status.OK_STATUS;
} }
@ -198,6 +236,8 @@ public class GridCanvas extends Canvas implements IMessageClient {
private ScrollJob scrollJob = new ScrollJob(); private ScrollJob scrollJob = new ScrollJob();
private RepaintJob repaintJob = new RepaintJob();
private ScrolledComposite scrolledComp; private ScrolledComposite scrolledComp;
private Point stretchStart = new Point(0, 0); private Point stretchStart = new Point(0, 0);
@ -1120,4 +1160,8 @@ public class GridCanvas extends Canvas implements IMessageClient {
} }
} }
} }
public void markDirty(Rectangle rect) {
this.repaintJob.markDirty(rect);
}
} }

View file

@ -44,6 +44,7 @@ import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Slider; import org.eclipse.swt.widgets.Slider;
import org.eclipse.ui.PlatformUI; import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService; import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.progress.UIJob;
import com.raytheon.uf.common.time.SimulatedTime; import com.raytheon.uf.common.time.SimulatedTime;
import com.raytheon.uf.common.time.TimeRange; import com.raytheon.uf.common.time.TimeRange;
@ -140,7 +141,7 @@ public class GridManager implements IGridManager {
/** /**
* Job to update the time display * Job to update the time display
*/ */
private static class UpdateJob extends Job { private static class UpdateJob extends UIJob {
public UpdateJob() { public UpdateJob() {
super("GridManagerUpdate"); super("GridManagerUpdate");
@ -154,22 +155,15 @@ public class GridManager implements IGridManager {
* IProgressMonitor) * IProgressMonitor)
*/ */
@Override @Override
protected IStatus run(IProgressMonitor monitor) { public IStatus runInUIThread(IProgressMonitor monitor) {
// if any displays are active // if any displays are active
if (activeList.size() > 0) { if (!activeList.isEmpty()) {
// update the state of all active displays // update the state of all active displays
Display.getDefault().syncExec(new Runnable() { for (GridManager gm : activeList) {
gm.redraw();
@Override }
public void run() { long t = System.currentTimeMillis() % 60000;
for (GridManager gm : activeList) { this.schedule(60000 - t);
gm.redraw();
}
}
});
this.schedule(60000);
} }
return Status.OK_STATUS; return Status.OK_STATUS;
@ -347,6 +341,7 @@ public class GridManager implements IGridManager {
return widthIncrement; return widthIncrement;
} }
@Override
public void expandTimeScale() { public void expandTimeScale() {
if (widthIncrement < GridManagerUtil.SECONDS_PER_PIXEL.length - 1) { if (widthIncrement < GridManagerUtil.SECONDS_PER_PIXEL.length - 1) {
widthIncrement++; widthIncrement++;
@ -355,6 +350,7 @@ public class GridManager implements IGridManager {
} }
} }
@Override
public void contractTimeScale() { public void contractTimeScale() {
if (widthIncrement > 0) { if (widthIncrement > 0) {
widthIncrement--; widthIncrement--;
@ -642,6 +638,7 @@ public class GridManager implements IGridManager {
* *
* @see com.raytheon.viz.gfe.gridmanager2.IGridManager#redraw() * @see com.raytheon.viz.gfe.gridmanager2.IGridManager#redraw()
*/ */
@Override
public void redraw() { public void redraw() {
if (!parent.isDisposed()) { if (!parent.isDisposed()) {
timeScale.redraw(); timeScale.redraw();
@ -793,6 +790,7 @@ public class GridManager implements IGridManager {
/** /**
* @return the lockSelectionTRtoTimeStep * @return the lockSelectionTRtoTimeStep
*/ */
@Override
public boolean isLockSelectionTRtoTimeStep() { public boolean isLockSelectionTRtoTimeStep() {
return lockSelectionTRtoTimeStep; return lockSelectionTRtoTimeStep;
} }
@ -801,6 +799,7 @@ public class GridManager implements IGridManager {
* @param lockSelectionTRtoTimeStep * @param lockSelectionTRtoTimeStep
* the lockSelectionTRtoTimeStep to set * the lockSelectionTRtoTimeStep to set
*/ */
@Override
public void setLockSelectionTRtoTimeStep(boolean lockSelectionTRtoTimeStep) { public void setLockSelectionTRtoTimeStep(boolean lockSelectionTRtoTimeStep) {
this.lockSelectionTRtoTimeStep = lockSelectionTRtoTimeStep; this.lockSelectionTRtoTimeStep = lockSelectionTRtoTimeStep;

View file

@ -26,6 +26,9 @@ import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.TimeZone; import java.util.TimeZone;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.IPropertyChangeListener;
@ -48,11 +51,11 @@ import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.PlatformUI; import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.menus.CommandContributionItem; import org.eclipse.ui.menus.CommandContributionItem;
import org.eclipse.ui.menus.CommandContributionItemParameter; import org.eclipse.ui.menus.CommandContributionItemParameter;
import org.eclipse.ui.progress.UIJob;
import com.raytheon.uf.common.time.SimulatedTime; import com.raytheon.uf.common.time.SimulatedTime;
import com.raytheon.uf.common.time.TimeRange; import com.raytheon.uf.common.time.TimeRange;
import com.raytheon.uf.viz.core.RGBColors; import com.raytheon.uf.viz.core.RGBColors;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.viz.gfe.Activator; import com.raytheon.viz.gfe.Activator;
import com.raytheon.viz.gfe.GFEPreference; import com.raytheon.viz.gfe.GFEPreference;
import com.raytheon.viz.gfe.GFEServerException; import com.raytheon.viz.gfe.GFEServerException;
@ -79,7 +82,7 @@ import com.raytheon.viz.gfe.ui.SelectTRMenu;
* @version 1.0 * @version 1.0
*/ */
public class TimeScale extends Canvas implements IMessageClient, Runnable { public class TimeScale extends Canvas implements IMessageClient {
private static final int MINOR_TICK = 5; private static final int MINOR_TICK = 5;
private static final int MAJOR_TICK = 10; private static final int MAJOR_TICK = 10;
@ -107,6 +110,32 @@ public class TimeScale extends Canvas implements IMessageClient, Runnable {
} }
} }
private class RepaintJob extends UIJob {
public RepaintJob() {
super("TimeScaleRepaintJob");
setSystem(true);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime
* .IProgressMonitor)
*/
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
if (!TimeScale.this.isDisposed()) {
TimeScale.this.redraw();
}
return Status.OK_STATUS;
}
}
private final GridManager gridManager; private final GridManager gridManager;
private String[] displayedPeriods; private String[] displayedPeriods;
@ -125,10 +154,13 @@ public class TimeScale extends Canvas implements IMessageClient, Runnable {
private MenuManager menuMgr; private MenuManager menuMgr;
private RepaintJob repaintJob;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
TimeScale(final Composite aParent, final GridManager aGridManager) { TimeScale(final Composite aParent, final GridManager aGridManager) {
super(aParent, SWT.NONE); super(aParent, SWT.NONE);
gridManager = aGridManager; gridManager = aGridManager;
repaintJob = new RepaintJob();
displayedPeriods = TimeScaleDisplayedPeriodsPreference displayedPeriods = TimeScaleDisplayedPeriodsPreference
.getTimeScaleDisplayedPeriods(); .getTimeScaleDisplayedPeriods();
@ -513,18 +545,7 @@ public class TimeScale extends Canvas implements IMessageClient, Runnable {
* *
*/ */
private void refresh() { private void refresh() {
if (this.getDisplay().getThread() == Thread.currentThread()) { this.repaintJob.schedule();
run();
} else {
VizApp.runAsync(this);
}
}
@Override
public void run() {
if (!isDisposed()) {
redraw();
}
} }
@Override @Override

View file

@ -146,8 +146,8 @@ public class ProcedureJob extends AbstractQueueJob<ProcedureRequest> {
if (request != null) { if (request != null) {
python.processFileUpdates(); python.processFileUpdates();
processRequest(request); processRequest(request);
if (request.getListener() != null) { if (request != null) {
request.getListener().requestComplete(null); request.requestComplete(null);
} }
} else if (expireJob } else if (expireJob
&& ((instanceMap.get(dataMgr).size() > maxJobs) || (System && ((instanceMap.get(dataMgr).size() > maxJobs) || (System
@ -158,8 +158,8 @@ public class ProcedureJob extends AbstractQueueJob<ProcedureRequest> {
} catch (Throwable t) { } catch (Throwable t) {
statusHandler.handle(Priority.PROBLEM, statusHandler.handle(Priority.PROBLEM,
"Error running tool ", t); "Error running tool ", t);
if (request != null && request.getListener() != null) { if (request != null) {
request.getListener().requestComplete(t); request.requestComplete(t);
} }
} finally { } finally {
request = null; request = null;

View file

@ -19,6 +19,8 @@
**/ **/
package com.raytheon.viz.gfe.procedures; package com.raytheon.viz.gfe.procedures;
import java.util.concurrent.Semaphore;
import com.raytheon.uf.common.dataplugin.gfe.reference.ReferenceData; import com.raytheon.uf.common.dataplugin.gfe.reference.ReferenceData;
import com.raytheon.uf.common.time.TimeRange; import com.raytheon.uf.common.time.TimeRange;
import com.raytheon.uf.viz.core.jobs.QueueJobRequest; import com.raytheon.uf.viz.core.jobs.QueueJobRequest;
@ -52,6 +54,21 @@ public class ProcedureRequest extends QueueJobRequest<Object> {
private PreviewInfo preview; private PreviewInfo preview;
private Semaphore completedSemaphore;
private Object result;
public ProcedureRequest() {
super();
completedSemaphore = new Semaphore(1);
try {
completedSemaphore.acquire();
} catch (InterruptedException e) {
// don't care
}
}
public String getProcedureName() { public String getProcedureName() {
return procedureName; return procedureName;
} }
@ -92,4 +109,20 @@ public class ProcedureRequest extends QueueJobRequest<Object> {
this.preview = preview; this.preview = preview;
} }
public void requestComplete(Object result) {
this.result = result;
completedSemaphore.release();
}
public Object getResult() {
try {
completedSemaphore.acquire();
return result;
} catch (InterruptedException e) {
return e;
} finally {
completedSemaphore.release();
}
}
} }

View file

@ -75,7 +75,7 @@ public class ProcedureUtil {
return pi; return pi;
} }
public static ProcedureRequest callFromSmartScript(final DataManager dm, public static Object callFromSmartScript(final DataManager dm,
final String procName, ReferenceData editArea, TimeRange timeRange, final String procName, ReferenceData editArea, TimeRange timeRange,
String varDict) { String varDict) {
PreviewInfo pi = dm.getEditActionProcessor().prepareExecute( PreviewInfo pi = dm.getEditActionProcessor().prepareExecute(
@ -122,6 +122,7 @@ public class ProcedureUtil {
}); });
} }
return req; ProcedureJob.enqueue(dm, req);
return req.getResult();
} }
} }

View file

@ -128,7 +128,7 @@ public class SmartUtil {
return pi; return pi;
} }
public static SmartToolRequest callFromSmartScript(final DataManager dm, public static Object callFromSmartScript(final DataManager dm,
final String toolName, final String elementName, final String toolName, final String elementName,
ReferenceData editArea, TimeRange timeRange, String varDict, ReferenceData editArea, TimeRange timeRange, String varDict,
boolean emptyEditAreaFlag, List<String> passErrors, boolean emptyEditAreaFlag, List<String> passErrors,
@ -176,6 +176,7 @@ public class SmartUtil {
}); });
} }
return req; SmartToolJob.enqueue(dm, req);
return req.getResult();
} }
} }

View file

@ -1,61 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.viz.gfe.smarttool.script;
import com.raytheon.uf.viz.core.jobs.IRequestCompleteListener;
/**
* TODO Add Description
*
* <pre>
*
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 23, 2010 njensen Initial creation
*
* </pre>
*
* @author njensen
* @version 1.0
*/
public class SmartToolFinishedListener implements
IRequestCompleteListener<Object> {
private boolean done = false;
private Object result;
@Override
public void requestComplete(Object result) {
done = true;
this.result = result;
}
public boolean isDone() {
return done;
}
public Object getResult() {
return result;
}
}

View file

@ -155,9 +155,7 @@ public class SmartToolJob extends AbstractQueueJob<SmartToolRequest> {
ea.getRefSet(), ea.getTimeRange(), ea.getRefSet(), ea.getTimeRange(),
request.getVarDict(), ea request.getVarDict(), ea
.getMissingDataMode(), monitor); .getMissingDataMode(), monitor);
if (request.getListener() != null) { request.requestComplete(null);
request.getListener().requestComplete(null);
}
pjResult = Status.OK_STATUS; pjResult = Status.OK_STATUS;
} catch (SmartToolException e) { } catch (SmartToolException e) {
@ -184,14 +182,14 @@ public class SmartToolJob extends AbstractQueueJob<SmartToolRequest> {
} catch (SmartToolException e) { } catch (SmartToolException e) {
statusHandler.handle(Priority.PROBLEM, statusHandler.handle(Priority.PROBLEM,
"Error running tool ", e); "Error running tool ", e);
if (req != null && req.getListener() != null) { if (req != null) {
req.getListener().requestComplete(e); req.requestComplete(e);
} }
} catch (Throwable t) { } catch (Throwable t) {
statusHandler.handle(Priority.PROBLEM, statusHandler.handle(Priority.PROBLEM,
"Error running tool ", t); "Error running tool ", t);
if (req != null && req.getListener() != null) { if (req != null) {
req.getListener().requestComplete(t); req.requestComplete(t);
} }
} finally { } finally {
if (req != null && req.getPreview() != null) { if (req != null && req.getPreview() != null) {

View file

@ -19,6 +19,8 @@
**/ **/
package com.raytheon.viz.gfe.smarttool.script; package com.raytheon.viz.gfe.smarttool.script;
import java.util.concurrent.Semaphore;
import com.raytheon.uf.viz.core.jobs.QueueJobRequest; import com.raytheon.uf.viz.core.jobs.QueueJobRequest;
import com.raytheon.viz.gfe.core.parm.Parm; import com.raytheon.viz.gfe.core.parm.Parm;
import com.raytheon.viz.gfe.smarttool.PreviewInfo; import com.raytheon.viz.gfe.smarttool.PreviewInfo;
@ -45,10 +47,23 @@ public class SmartToolRequest extends QueueJobRequest<Object> {
private String varDict; private String varDict;
private SmartToolFinishedListener listener;
private PreviewInfo preview; private PreviewInfo preview;
private Semaphore completedSemaphore;
private Object result;
public SmartToolRequest() {
super();
completedSemaphore = new Semaphore(1);
try {
completedSemaphore.acquire();
} catch (InterruptedException e) {
// don't care
}
}
public Parm getInputParm() { public Parm getInputParm() {
return inputParm; return inputParm;
} }
@ -65,14 +80,6 @@ public class SmartToolRequest extends QueueJobRequest<Object> {
this.varDict = varDict; this.varDict = varDict;
} }
public SmartToolFinishedListener getListener() {
return listener;
}
public void setListener(SmartToolFinishedListener listener) {
this.listener = listener;
}
public PreviewInfo getPreview() { public PreviewInfo getPreview() {
return preview; return preview;
} }
@ -81,4 +88,20 @@ public class SmartToolRequest extends QueueJobRequest<Object> {
this.preview = preview; this.preview = preview;
} }
public void requestComplete(Object result) {
this.result = result;
completedSemaphore.release();
}
public Object getResult() {
try {
completedSemaphore.acquire();
return result;
} catch (InterruptedException e) {
return e;
} finally {
completedSemaphore.release();
}
}
} }

View file

@ -721,6 +721,8 @@ public class TimeSeriesDisplayCanvas extends TimeSeriesGraphCanvas implements
gc.setBackground(this.white); gc.setBackground(this.white);
} }
gc.drawString(NO_DATA_AVAILABLE, tmpX, tmpY); gc.drawString(NO_DATA_AVAILABLE, tmpX, tmpY);
gc.drawString(siteLabel +" fs=" + floodStage, GRAPHBORDER,
GRAPHBORDER - fontHeight * 2);
this.dialog.getParentDialog().enableGraphButton(); this.dialog.getParentDialog().enableGraphButton();
this.dialog.getParentDialog().enableBothButton(); this.dialog.getParentDialog().enableBothButton();
@ -2624,4 +2626,4 @@ public class TimeSeriesDisplayCanvas extends TimeSeriesGraphCanvas implements
public ArrayList<TraceData> getTraceArray() { public ArrayList<TraceData> getTraceArray() {
return traceArray; return traceArray;
} }
} }

View file

@ -96,7 +96,7 @@
<substitute key="colormap" value="Sat/Precip Water/Precip Water - Polar)"/> <substitute key="colormap" value="Sat/Precip Water/Precip Water - Polar)"/>
</contribute> </contribute>
<contribute xsi:type="titleItem" <contribute xsi:type="titleItem"
titleText="------ Blended of AMSU and SSM/I------" id="blendedofAMSUAndSSMIDataLine"/> titleText="------ AMSU and SSM/I + GPS ------" id="blendedofAMSUAndSSMIDataLine"/>
<contribute xsi:type="bundleItem" file="bundles/DefaultSatellite.xml" <contribute xsi:type="bundleItem" file="bundles/DefaultSatellite.xml"
menuText="Blended Total Precip Water" id="blendedTotalPrecipWater"> menuText="Blended Total Precip Water" id="blendedTotalPrecipWater">
<dataURI>/satellite/%/NESDIS/Miscellaneous/Supernational/Sounder_Based_Derived_Precipitable_Water_(PW)</dataURI> <dataURI>/satellite/%/NESDIS/Miscellaneous/Supernational/Sounder_Based_Derived_Precipitable_Water_(PW)</dataURI>

View file

@ -84,6 +84,8 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
* 04/14/2010 4734 mhuang Corrected StdTextProduct import * 04/14/2010 4734 mhuang Corrected StdTextProduct import
* dependency * dependency
* 06/28/2010 4639 cjeanbap Allow user to create a new text product. * 06/28/2010 4639 cjeanbap Allow user to create a new text product.
*
* 01/26/2012 14468 D.Friedman Fix initial BBB field selection.
* </pre> * </pre>
* *
* @author lvenable * @author lvenable
@ -258,32 +260,10 @@ public class AWIPSHeaderBlockDlg extends CaveSWTDialog implements
// Create the message/indicator group combo box. // Create the message/indicator group combo box.
gd = new GridData(70, SWT.DEFAULT); gd = new GridData(70, SWT.DEFAULT);
bbbCboBx = new Combo(wmoIdComp, SWT.DROP_DOWN); bbbCboBx = new Combo(wmoIdComp, SWT.DROP_DOWN|SWT.READ_ONLY);
bbbCboBx.setItems(BBB_LIST); bbbCboBx.setItems(BBB_LIST);
bbbCboBx.select(3); bbbCboBx.select(3);
bbbCboBx.setLayoutData(gd); bbbCboBx.setLayoutData(gd);
bbbCboBx.addVerifyListener(new VerifyListener() {
@Override
public void verifyText(VerifyEvent e) {
if (e.text.length() == 3) {
if (e.start != 0 || e.end != 0) {
e.doit = false;
} else {
e.doit = false;
for (String s : BBB_LIST) {
if (s.equalsIgnoreCase(e.text)) {
e.doit = true;
e.text = s;
break;
}
}
}
} else if (e.text.length() != 0) {
e.doit = false;
}
}
});
bbbCboBx.addFocusListener(new FocusListener() { bbbCboBx.addFocusListener(new FocusListener() {
@ -304,32 +284,11 @@ public class AWIPSHeaderBlockDlg extends CaveSWTDialog implements
// Create the message/indicator version group combo box. // Create the message/indicator version group combo box.
gd = new GridData(70, SWT.DEFAULT); gd = new GridData(70, SWT.DEFAULT);
bbbVerCboBx = new Combo(wmoIdComp, SWT.DROP_DOWN); bbbVerCboBx = new Combo(wmoIdComp, SWT.DROP_DOWN|SWT.READ_ONLY);
bbbVerCboBx.setItems(CHAR_LIST); bbbVerCboBx.setItems(CHAR_LIST);
bbbVerCboBx.select(0); bbbVerCboBx.select(0);
bbbVerCboBx.setLayoutData(gd); bbbVerCboBx.setLayoutData(gd);
bbbVerCboBx.addVerifyListener(new VerifyListener() {
@Override
public void verifyText(VerifyEvent e) {
e.text = e.text.trim().toUpperCase();
if (e.text.length() > 1) {
e.doit = false;
} else if (e.text.length() == 1 && (e.start != 0 || e.end != 0)) {
e.doit = false;
} else if (e.text.length() == 1) {
e.doit = false;
for (String s : CHAR_LIST) {
if (s.equals(e.text)) {
e.doit = true;
break;
}
}
}
}
});
bbbVerCboBx.addFocusListener(new FocusListener() { bbbVerCboBx.addFocusListener(new FocusListener() {
@Override @Override

View file

@ -40,6 +40,7 @@ import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.progress.UIJob;
import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus;
@ -74,7 +75,7 @@ public class TimeDisplay extends ContributionItem {
/** /**
* Job to update the time display * Job to update the time display
*/ */
private static class TimeUpdateJob extends Job { private static class TimeUpdateJob extends UIJob {
/** /**
* @param name * @param name
@ -91,22 +92,16 @@ public class TimeDisplay extends ContributionItem {
* IProgressMonitor) * IProgressMonitor)
*/ */
@Override @Override
protected IStatus run(IProgressMonitor monitor) { public IStatus runInUIThread(IProgressMonitor monitor) {
// if any displays are active // if any displays are active
if (activeList.size() > 0) { if (!activeList.isEmpty()) {
// update the state of all active displays // update the state of all active displays
Display.getDefault().syncExec(new Runnable() { for (TimeDisplay td : activeList) {
td.update();
}
@Override long t = System.currentTimeMillis() % 60000;
public void run() { this.schedule(60000 - t);
for (TimeDisplay td : activeList) {
td.update();
}
}
});
this.schedule(1000);
} }
return Status.OK_STATUS; return Status.OK_STATUS;

View file

@ -31,6 +31,9 @@ import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration;
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Oct 5, 2011 jsanchez Initial creation * Oct 5, 2011 jsanchez Initial creation
* *
* 01/26/2012 14466 D.Friedman Fix parseString processing.
* 01/26/2012 14469 D.Friedman Fix followup bullet processing
*
* </pre> * </pre>
* *
* @author jsanchez * @author jsanchez
@ -145,24 +148,36 @@ public class BulletListManager {
return; return;
} }
String warningText = record.getRawmessage().replaceAll("\n", " ") String warningText = record.getRawmessage().replaceAll("\\s+", " ");
.replaceAll(" ", " ").replaceAll(" ", " ")
.replaceAll(" ", " ");
/* Test 'showString' to determine if the bullet is to be hidden */ /* Test 'showString' to determine if the bullet is to be hidden */
ArrayList<Bullet> displayedBullets = new ArrayList<Bullet>(); ArrayList<Bullet> displayedBullets = null;
for (Bullet b : configuration.getBullets()) { ArrayList<Bullet> displayedDamInfoBullets = null;
if (b != null
&& (b.getShowString() == null || warningText.contains(b for (int pass = 0; pass < 2; ++pass) {
.getShowString()))) { Bullet[] sourceList = pass == 0 ?
displayedBullets.add(b); configuration.getBullets() :
} configuration.getDamInfoBullets();
ArrayList<Bullet> resultList = new ArrayList<Bullet>();
if (sourceList != null) {
for (Bullet b : sourceList) {
if (b != null
&& (b.getShowString() == null ||
selectBulletFromFollowup(b.getShowString(), warningText))) {
resultList.add(b);
}
}
}
if (pass == 0)
displayedBullets = resultList;
else
displayedDamInfoBullets = resultList;
} }
/* Sets up the appropriate bullet groups */ /* Sets up the appropriate bullet groups */
recreateBullets( recreateBullets(
displayedBullets.toArray(new Bullet[displayedBullets.size()]), displayedBullets.toArray(new Bullet[displayedBullets.size()]),
configuration.getDamInfoBullets()); displayedDamInfoBullets.toArray(new DamInfoBullet[displayedDamInfoBullets.size()]));
if (configuration.getLockedGroupsOnFollowup() != null) { if (configuration.getLockedGroupsOnFollowup() != null) {
for (String lockedGroup : configuration.getLockedGroupsOnFollowup() for (String lockedGroup : configuration.getLockedGroupsOnFollowup()
@ -177,13 +192,13 @@ public class BulletListManager {
for (int i = 0; i < bullets.length; i++) { for (int i = 0; i < bullets.length; i++) {
Bullet bullet = bullets[i]; Bullet bullet = bullets[i];
if (selectBulletFromFollowup(bullet.getParseString(), warningText)) { if (selectBulletFromFollowup(bullet.getParseString(), warningText)) {
updateSelectedIndices(i, false); updateSelectedIndices(i, false, true);
} }
if (bullet.getFloodSeverity() != null if (bullet.getFloodSeverity() != null
&& bullet.getFloodSeverity().equals( && bullet.getFloodSeverity().equals(
record.getFloodSeverity())) { record.getFloodSeverity())) {
updateSelectedIndices(i, false); updateSelectedIndices(i, false, true);
} }
} }
} }
@ -206,6 +221,20 @@ public class BulletListManager {
* @param isFollowup * @param isFollowup
*/ */
public void updateSelectedIndices(int selectionIndex, boolean isFollowup) { public void updateSelectedIndices(int selectionIndex, boolean isFollowup) {
updateSelectedIndices(selectionIndex, isFollowup, false);
}
/**
* Updates the list of selected of indices by including or removing indices
* depending on if the bullet is already selected or is a part of a group of
* bullets. If selectUnconditionally is true, sets (instead of toggles)
* bullets.
*
* @param selectionIndex
* @param isFollowup
* @param selectUnconditionally
*/
public void updateSelectedIndices(int selectionIndex, boolean isFollowup, boolean selectUnconditionally) {
if (selectionIndex < 0 || selectionIndex >= bullets.length if (selectionIndex < 0 || selectionIndex >= bullets.length
|| titleGroup.contains(selectionIndex)) { || titleGroup.contains(selectionIndex)) {
return; return;
@ -214,14 +243,20 @@ public class BulletListManager {
Bullet bullet = bullets[selectionIndex]; Bullet bullet = bullets[selectionIndex];
String group = bullet.getBulletGroup(); String group = bullet.getBulletGroup();
if (group == null) { if (group == null) {
if (selectedIndices.contains(selectionIndex)) { if (selectUnconditionally) {
selectedIndices.remove(selectionIndex); if (!selectedIndices.contains(selectionIndex))
} else { selectedIndices.add(selectionIndex);
selectedIndices.add(selectionIndex); } else {
} // toggle
return; if (selectedIndices.contains(selectionIndex)) {
} selectedIndices.remove(selectionIndex);
} else {
selectedIndices.add(selectionIndex);
}
}
return;
}
/* Can't change selection when a part of a locked group on a follow up */ /* Can't change selection when a part of a locked group on a follow up */
if (isFollowup && lockedGroups.contains(group.toLowerCase())) { if (isFollowup && lockedGroups.contains(group.toLowerCase())) {
@ -262,19 +297,30 @@ public class BulletListManager {
} }
List<Integer> groupIndices = bulletGroups.get(group); List<Integer> groupIndices = bulletGroups.get(group);
for (Integer index : groupIndices) { for (Integer index : groupIndices) {
/* /*
* Unselect items in a group except for the latest selection in the * Unselect items in a group except for the latest selection in the
* group * group
*/ */
if (!selectedIndices.contains(selectionIndex) if (selectUnconditionally) {
&& index.equals(selectionIndex)) { if (index.equals(selectionIndex)) {
selectedIndices.add(index); if (!selectedIndices.contains(selectionIndex))
} else { selectedIndices.add(index);
selectedIndices.remove(index); } else {
clearScenarios(index); selectedIndices.remove(index);
} clearScenarios(index);
} }
} else {
// toggles off if selected
if (!selectedIndices.contains(selectionIndex)
&& index.equals(selectionIndex)) {
selectedIndices.add(index);
} else {
selectedIndices.remove(index);
clearScenarios(index);
}
}
}
} }
/** /**
@ -373,7 +419,7 @@ public class BulletListManager {
} }
boolean selectBullet = true; boolean selectBullet = true;
for (String p : parseString.toUpperCase().replaceAll(" ", " ") for (String p : parseString.toUpperCase().replaceAll("\\s+", " ")
.split("\",")) { .split("\",")) {
p = p.replace("\"", ""); p = p.replace("\"", "");
if ((p.startsWith("-") && warningText.contains(p.substring(1))) if ((p.startsWith("-") && warningText.contains(p.substring(1)))

View file

@ -0,0 +1,59 @@
##
# 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.
##
#
# Globally import and sets up instances of the smart tool scripts.
# Designed to be used as a master controller for inspecting and running
# smart tools from Java.
#
#
#
# SOFTWARE HISTORY
#
# Date Ticket# Engineer Description
# ------------ ---------- ----------- --------------------------
# 10/21/08 njensen Initial Creation.
#
#
#
import numpy
import sys
import JUtil
import MasterInterface
class VCModuleInterface(MasterInterface.MasterInterface):
def __init__(self, scriptPath):
MasterInterface.MasterInterface.__init__(self)
self.importModules(scriptPath)
def getMethodArgNames(self, moduleName, className, methodName):
from java.util import ArrayList
args = self.getMethodArgs(moduleName, className, methodName)
argList = ArrayList()
for a in args:
argList.add(a)
return argList
def getMethodArgs(self, moduleName, className, methodName):
return MasterInterface.MasterInterface.getMethodArgs(self, moduleName, className, methodName)[1:]

View file

@ -0,0 +1,182 @@
/**
* 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.Date;
import java.util.List;
import com.raytheon.edex.plugin.grib.dao.GribDao;
import com.raytheon.uf.common.dataplugin.PluginException;
import com.raytheon.uf.common.dataplugin.grib.GribRecord;
import com.raytheon.uf.common.dataplugin.grib.exception.GribException;
import com.raytheon.uf.edex.database.DataAccessLayerException;
import com.raytheon.uf.edex.database.query.DatabaseQuery;
/**
* Grib post processor implementation to generate 6-hr precipitation grids from
* run accumulated total precipitation
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 1/18/2012 porricel Initial Creation
*
* </pre>
*
* @author bphillip
* @version 1
*/
public class CanadianNHPostProcessor extends SixHrPrecipGridProcessor {
@Override
public GribRecord[] process(GribRecord record) throws GribException {
// Post process the data if this is a Total Precipitation grid
if (record.getModelInfo().getParameterAbbreviation().equals("TPrun")) {
return super.process(record);
}
return new GribRecord[] { record };
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
protected List<GribRecord> getPrecipInventory(Date refTime)
throws GribException {
GribDao dao = null;
try {
dao = new GribDao();
} catch (PluginException e) {
throw new GribException("Error instantiating grib dao!", e);
}
DatabaseQuery query = new DatabaseQuery(GribRecord.class);
query.addQueryParam("modelInfo.parameterAbbreviation", "TPrun");
query.addQueryParam("modelInfo.modelName", "Canadian-NH");
query.addQueryParam("dataTime.refTime", refTime);
query.addOrder("dataTime.fcstTime", true);
try {
return (List<GribRecord>) dao.queryByCriteria(query);
} catch (DataAccessLayerException e) {
throw new GribException(
"Error getting Precip inventory for Canadian-NH!", e);
}
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
protected List<Integer> getPrecip6hrInventory(Date refTime)
throws GribException {
GribDao dao = null;
try {
dao = new GribDao();
} catch (PluginException e) {
throw new GribException("Error instantiating grib dao!", e);
}
DatabaseQuery query = new DatabaseQuery(GribRecord.class);
query.addQueryParam("modelInfo.parameterAbbreviation", "TP6hr");
query.addQueryParam("modelInfo.modelName", "Canadian-NH");
query.addQueryParam("dataTime.refTime", refTime);
query.addReturnedField("dataTime.fcstTime");
try {
return (List<Integer>) dao.queryByCriteria(query);
} catch (DataAccessLayerException e) {
throw new GribException(
"Error getting Precip inventory for Canadian-NH!", e);
}
}
/**
* Generates the 6 hour accumulated grid from the run accumulated
* precipitation grids. This function will look in the inventory and
* generate any 6 hr grids that can be generated.
*
* @param record
* The grib record for which to generate the 6 hour accumulated
* precipitation grid
* @return The generated 6-hr precipitation grids
* @throws GribException
*/
protected synchronized GribRecord[] generate6hrPrecipGrids(GribRecord record)
throws GribException {
// The current run accumulated precipitation grid inventory in the
// database
List<GribRecord> precipInventory = getPrecipInventory(record
.getDataTime().getRefTime());
// The current 6-hr precipitation grid inventory in the database
List<Integer> precip6hrInventory = getPrecip6hrInventory(record
.getDataTime().getRefTime());
// Adds the current record to the precip inventory
float[] currentData = (float[]) record.getMessageData();
record.setMessageData(currentData);
precipInventory.add(record);
// Examine each grid in the inventory and generate the 6hr precipitation
// grid if possible
List<GribRecord> generatedRecords = new ArrayList<GribRecord>();
for (int i = 0; i < precipInventory.size(); i++) {
// Check if the 6hr precipitation grid has already been produced
if (!precip6hrInventory.contains(precipInventory.get(i)
.getDataTime().getFcstTime())) {
// If the precipitation grid has not been produced, generate it
List<GribRecord> generated6hrPrecips = generate6hrPrecip(
precipInventory.get(i), precipInventory,
precip6hrInventory);
for (GribRecord newRecord : generated6hrPrecips) {
// Add the generated grid to the current inventory
if (newRecord != null) {
precip6hrInventory.add(newRecord.getDataTime()
.getFcstTime());
generatedRecords.add(newRecord);
}
}
}
}
return generatedRecords.toArray(new GribRecord[] {});
}
/**
* Calculates the new data by subtracting the previous inventory data from
* the current data
*
* @param inventoryData
* The data from the previous precipitation record
* @param newData
* The data from the current precipitation record
*/
protected void calculatePrecipValues(float[] inventoryData, float[] newData) {
for (int i = 0; i < inventoryData.length; i++) {
newData[i] = newData[i] - inventoryData[i];
if (newData[i] < 0) {
newData[i] = 0;
}
}
}
}

View file

@ -0,0 +1,182 @@
/**
* 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.Date;
import java.util.List;
import com.raytheon.edex.plugin.grib.dao.GribDao;
import com.raytheon.uf.common.dataplugin.PluginException;
import com.raytheon.uf.common.dataplugin.grib.GribRecord;
import com.raytheon.uf.common.dataplugin.grib.exception.GribException;
import com.raytheon.uf.edex.database.DataAccessLayerException;
import com.raytheon.uf.edex.database.query.DatabaseQuery;
/**
* Grib post processor implementation to generate 3-hr precipitation grids from
* run accumulated total precipitation
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 1/18/2012 porricel Initial Creation
*
* </pre>
*
* @author bphillip
* @version 1
*/
public class CanadianRegPostProcessor extends ThreeHrPrecipGridProcessor {
@Override
public GribRecord[] process(GribRecord record) throws GribException {
// Post process the data if this is a Total Precipitation grid
if (record.getModelInfo().getParameterAbbreviation().equals("TPrun")) {
return super.process(record);
}
return new GribRecord[] { record };
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
protected List<GribRecord> getPrecipInventory(Date refTime)
throws GribException {
GribDao dao = null;
try {
dao = new GribDao();
} catch (PluginException e) {
throw new GribException("Error instantiating grib dao!", e);
}
DatabaseQuery query = new DatabaseQuery(GribRecord.class);
query.addQueryParam("modelInfo.parameterAbbreviation", "TPrun");
query.addQueryParam("modelInfo.modelName", "Canadian-Reg");
query.addQueryParam("dataTime.refTime", refTime);
query.addOrder("dataTime.fcstTime", true);
try {
return (List<GribRecord>) dao.queryByCriteria(query);
} catch (DataAccessLayerException e) {
throw new GribException(
"Error getting Precip inventory for Canadian-Reg!", e);
}
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
protected List<Integer> getPrecip3hrInventory(Date refTime)
throws GribException {
GribDao dao = null;
try {
dao = new GribDao();
} catch (PluginException e) {
throw new GribException("Error instantiating grib dao!", e);
}
DatabaseQuery query = new DatabaseQuery(GribRecord.class);
query.addQueryParam("modelInfo.parameterAbbreviation", "TP3hr");
query.addQueryParam("modelInfo.modelName", "Canadian-Reg");
query.addQueryParam("dataTime.refTime", refTime);
query.addReturnedField("dataTime.fcstTime");
try {
return (List<Integer>) dao.queryByCriteria(query);
} catch (DataAccessLayerException e) {
throw new GribException(
"Error getting Precip inventory for Canadian-Reg!", e);
}
}
/**
* Generates the 3 hour accumulated grid from the run accumulated
* precipitation grids. This function will look in the inventory and
* generate any 3 hr grids that can be generated.
*
* @param record
* The grib record for which to generate the 3 hour accumulated
* precipitation grid
* @return The generated 3-hr precipitation grids
* @throws GribException
*/
protected synchronized GribRecord[] generate3hrPrecipGrids(GribRecord record)
throws GribException {
// The current run accumulated precipitation grid inventory in the
// database
List<GribRecord> precipInventory = getPrecipInventory(record
.getDataTime().getRefTime());
// The current 3-hr precipitation grid inventory in the database
List<Integer> precip3hrInventory = getPrecip3hrInventory(record
.getDataTime().getRefTime());
// Adds the current record to the precip inventory
float[] currentData = (float[]) record.getMessageData();
record.setMessageData(currentData);
precipInventory.add(record);
// Examine each grid in the inventory and generate the 3hr precipitation
// grid if possible
List<GribRecord> generatedRecords = new ArrayList<GribRecord>();
for (int i = 0; i < precipInventory.size(); i++) {
// Check if the 3hr precipitation grid has already been produced
if (!precip3hrInventory.contains(precipInventory.get(i)
.getDataTime().getFcstTime())) {
// If the precipitation grid has not been produced, generate it
List<GribRecord> generated3hrPrecips = generate3hrPrecip(
precipInventory.get(i), precipInventory,
precip3hrInventory);
for (GribRecord newRecord : generated3hrPrecips) {
// Add the generated grid to the current inventory
if (newRecord != null) {
precip3hrInventory.add(newRecord.getDataTime()
.getFcstTime());
generatedRecords.add(newRecord);
}
}
}
}
return generatedRecords.toArray(new GribRecord[] {});
}
/**
* Calculates the new data by subtracting the previous inventory data from
* the current data
*
* @param inventoryData
* The data from the previous precipitation record
* @param newData
* The data from the current precipitation record
*/
protected void calculatePrecipValues(float[] inventoryData, float[] newData) {
for (int i = 0; i < inventoryData.length; i++) {
newData[i] = newData[i] - inventoryData[i];
if (newData[i] < 0) {
newData[i] = 0;
}
}
}
}

View file

@ -0,0 +1,236 @@
/**
* 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.Calendar;
import java.util.List;
import com.raytheon.edex.plugin.grib.dao.GribDao;
import com.raytheon.edex.plugin.grib.util.GribModelCache;
import com.raytheon.uf.common.dataplugin.PluginException;
import com.raytheon.uf.common.dataplugin.grib.GribModel;
import com.raytheon.uf.common.dataplugin.grib.GribRecord;
import com.raytheon.uf.common.dataplugin.grib.exception.GribException;
import com.raytheon.uf.common.datastorage.records.FloatDataRecord;
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.DataTime;
import com.raytheon.uf.common.time.TimeRange;
import com.raytheon.uf.edex.database.DataAccessLayerException;
/**
* Abstract class to generate 3hr records
*
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 24, 2012 DR 14299 M. Porricelli Initial creation
*
* </pre>
*
* @author porricel
* @version 1.0
*/
public abstract class ThreeHrPrecipGridProcessor implements IDecoderPostProcessor {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(ThreeHrPrecipGridProcessor.class);
/** The number of seconds in 3 hours */
protected static final int SECONDS_IN_3_HRS = 10800;
@Override
public GribRecord[] process(GribRecord record) throws GribException {
// Post process the data if this is a Total Precipitation grid
GribRecord[] newRecords = generate3hrPrecipGrids(record);
GribRecord[] retVal = new GribRecord[newRecords.length + 1];
retVal[0] = record;
for (int i = 1; i < retVal.length; i++) {
retVal[i] = newRecords[i - 1];
}
return retVal;
}
protected abstract GribRecord[] generate3hrPrecipGrids(GribRecord record)
throws GribException;
/**
* Generates the 3hr precipitation grid
*
* @param record
* The current record to clone and modify to produce the new 3hr
* grid
* @param precipInventory
* The current run accumulated grid inventory
* @param precip3hrInventory
* The current 3hr precipitation inventory
* @return The generated 3hr precipitation grid
* @throws GribException
*/
protected List<GribRecord> generate3hrPrecip(GribRecord record,
List<GribRecord> precipInventory, List<Integer> precip3hrInventory)
throws GribException {
List<GribRecord> tp3hrRecords = new ArrayList<GribRecord>();
int currentFcstTime = record.getDataTime().getFcstTime();
// If this is the first grid (the 3 hr grid), the 3hr precip
// accumulation is the same as the 3hr run accumulated grid
if (currentFcstTime == SECONDS_IN_3_HRS) {
tp3hrRecords.add(calculate3hrPrecip(null, record));
}
// If this is not the first grid, generate the new grid using the
// previous grid
else {
for (GribRecord rec : precipInventory) {
if (rec.getDataTime().getFcstTime() == currentFcstTime
- SECONDS_IN_3_HRS) {
tp3hrRecords.add(calculate3hrPrecip(rec, record));
}
}
}
return tp3hrRecords;
}
/**
* Generates the 3hr precipitation grid from the current grid and the
* previous grid
*
* @param inventoryRecord
* The previous grid from the inventory
* @param currentRecord
* The current grid
* @return The generated 3hr precipitation grid
* @throws GribException
*/
protected GribRecord calculate3hrPrecip(GribRecord inventoryRecord,
GribRecord currentRecord) throws GribException {
// Clone the current record and set the ID to 0 so Hibernate will
// recognize it as a new record
GribRecord tp3hrRecord = new GribRecord(currentRecord);
tp3hrRecord.setId(0);
if (currentRecord.getMessageData() == null) {
GribDao dao = null;
try {
dao = new GribDao();
currentRecord.setMessageData(((FloatDataRecord) dao
.getHDF5Data(currentRecord, 0)[0]).getFloatData());
} catch (PluginException e) {
throw new GribException("Error populating grib data!", e);
}
}
// Copy the data to the new record so the data from the original record
// does not get modified
float[] currentData = (float[]) currentRecord.getMessageData();
currentRecord.setMessageData(currentData);
float[] newData = new float[currentData.length];
System.arraycopy(currentData, 0, newData, 0, currentData.length);
tp3hrRecord.setMessageData(newData);
// Assign the new parameter abbreviation and cache it if necessary
tp3hrRecord.getModelInfo().setParameterAbbreviation("TP3hr");
tp3hrRecord.getModelInfo().generateId();
try {
GribModel model = GribModelCache.getInstance().getModel(
tp3hrRecord.getModelInfo());
tp3hrRecord.setModelInfo(model);
} catch (DataAccessLayerException e) {
throw new GribException("Unable to get model info from the cache!",
e);
}
// Change the data time to include the 3-hr time range
modifyDataTime(tp3hrRecord);
// Calculate the new data values
if (inventoryRecord != null) {
if (inventoryRecord.getMessageData() == null) {
GribDao dao = null;
try {
dao = new GribDao();
inventoryRecord
.setMessageData(((FloatDataRecord) dao.getHDF5Data(
inventoryRecord, 0)[0]).getFloatData());
} catch (PluginException e) {
throw new GribException("Error populating grib data!", e);
}
}
calculatePrecipValues((float[]) inventoryRecord.getMessageData(),
(float[]) tp3hrRecord.getMessageData());
}
return tp3hrRecord;
}
/**
* Calculates the new data by subtracting the previous inventory data from
* the current data
*
* @param inventoryData
* The data from the previous precipitation record
* @param newData
* The data from the current precipitation record
*/
protected abstract void calculatePrecipValues(float[] messageData,
float[] messageData2);
/**
* Modifies the DataTime of the provided record to include a 3hr time range
*
* @param record
* The record to modify the datatime for
*/
protected void modifyDataTime(GribRecord record) {
Calendar refTime = record.getDataTime().getRefTimeAsCalendar();
int fcstTime = record.getDataTime().getFcstTime();
// Calculate the start time by subtracting 3 hours from the reference
// time + forecast time
Calendar startTime = (Calendar) refTime.clone();
startTime.add(Calendar.SECOND, fcstTime - SECONDS_IN_3_HRS);
// Calculate the end time by adding the reference time + forecast time
Calendar endTime = (Calendar) refTime.clone();
endTime.add(Calendar.SECOND, fcstTime);
TimeRange validPeriod = new TimeRange(startTime, endTime);
DataTime newDataTime = new DataTime(refTime, fcstTime, validPeriod);
// Reset the datauri since the datauri contains the DataTime
record.setDataTime(newDataTime);
record.setDataURI(null);
try {
record.setPluginName("grib");
record.constructDataURI();
} catch (PluginException e) {
statusHandler.handle(Priority.PROBLEM,
"Error constructing dataURI!", e);
}
}
}

View file

@ -2,26 +2,8 @@
<gribParamInfo xmlns:ns2="group"> <gribParamInfo xmlns:ns2="group">
<valtimeMINUSreftime> <valtimeMINUSreftime>
<fcst>0</fcst> <fcst>0</fcst>
<fcst>21600</fcst>
<fcst>43200</fcst> <fcst>43200</fcst>
<fcst>86400</fcst>
<fcst>129600</fcst>
<fcst>172800</fcst>
<fcst>216000</fcst>
<fcst>259200</fcst>
<fcst>302400</fcst>
<fcst>345600</fcst>
<fcst>388800</fcst>
<fcst>432000</fcst>
<fcst>475200</fcst>
<fcst>518400</fcst>
<fcst>561600</fcst>
<fcst>604800</fcst>
<fcst>648000</fcst>
<fcst>691200</fcst>
<fcst>734400</fcst>
<fcst>777600</fcst>
<fcst>820800</fcst>
<fcst>864000</fcst>
</valtimeMINUSreftime> </valtimeMINUSreftime>
<gribParameterInfo xsi:type="parameterInfo" <gribParameterInfo xsi:type="parameterInfo"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

View file

@ -79,3 +79,7 @@ TPCSurgeProb:com.raytheon.edex.plugin.grib.decoderpostprocessors.TPCSurgeProbPos
#SREF grids #SREF grids
SREF212:com.raytheon.edex.plugin.grib.decoderpostprocessors.SREFProbPostProcessor SREF212:com.raytheon.edex.plugin.grib.decoderpostprocessors.SREFProbPostProcessor
SREF243:com.raytheon.edex.plugin.grib.decoderpostprocessors.SREFProbPostProcessor SREF243:com.raytheon.edex.plugin.grib.decoderpostprocessors.SREFProbPostProcessor
#Canadian GEM grids
Canadian-Reg:com.raytheon.edex.plugin.grib.decoderpostprocessors.CanadianRegPostProcessor
Canadian-NH:com.raytheon.edex.plugin.grib.decoderpostprocessors.CanadianNHPostProcessor

View file

@ -686,6 +686,48 @@
</id> </id>
<versionsToKeep>2</versionsToKeep> <versionsToKeep>2</versionsToKeep>
</rule> </rule>
<rule>
<id>
<pluginName>redbook</pluginName>
<key>wmoTTAAii=PEIY97</key>
</id>
<versionsToKeep>2</versionsToKeep>
</rule>
<rule>
<id>
<pluginName>redbook</pluginName>
<key>wmoTTAAii=PTIY97</key>
</id>
<versionsToKeep>2</versionsToKeep>
</rule>
<rule>
<id>
<pluginName>redbook</pluginName>
<key>wmoTTAAii=PYIY97</key>
</id>
<versionsToKeep>2</versionsToKeep>
</rule>
<rule>
<id>
<pluginName>redbook</pluginName>
<key>wmoTTAAii=PEIY96</key>
</id>
<versionsToKeep>2</versionsToKeep>
</rule>
<rule>
<id>
<pluginName>redbook</pluginName>
<key>wmoTTAAii=PTIY96</key>
</id>
<versionsToKeep>2</versionsToKeep>
</rule>
<rule>
<id>
<pluginName>redbook</pluginName>
<key>wmoTTAAii=PYIY96</key>
</id>
<versionsToKeep>2</versionsToKeep>
</rule>
<rule> <rule>
<id> <id>
<pluginName>redbook</pluginName> <pluginName>redbook</pluginName>

View file

@ -407,6 +407,42 @@
<fcstHR>240</fcstHR> <fcstHR>240</fcstHR>
</value> </value>
</entry> </entry>
<entry>
<key>PEIY96</key>
<value prd="86400" ofs="43200">
<fcstHR>336</fcstHR>
</value>
</entry>
<entry>
<key>PEIY97</key>
<value prd="86400" ofs="43200">
<fcstHR>168</fcstHR>
</value>
</entry>
<entry>
<key>PTIY96</key>
<value prd="86400" ofs="43200">
<fcstHR>336</fcstHR>
</value>
</entry>
<entry>
<key>PTIY97</key>
<value prd="86400" ofs="43200">
<fcstHR>168</fcstHR>
</value>
</entry>
<entry>
<key>PYIY96</key>
<value prd="86400" ofs="43200">
<fcstHR>336</fcstHR>
</value>
</entry>
<entry>
<key>PYIY97</key>
<value prd="86400" ofs="43200">
<fcstHR>168</fcstHR>
</value>
</entry>
<entry> <entry>
<key>PEIK98</key> <key>PEIK98</key>
<value> <value>

View file

@ -93,6 +93,11 @@ public class GfePyIncludeUtil {
public static final String GFE_CONFIG = FileUtil.join("config", GFE); public static final String GFE_CONFIG = FileUtil.join("config", GFE);
public static final String VCMODULES = FileUtil.join(GFE, "vcmodule");
public static final String VCMOD_UTILS = FileUtil
.join(VCMODULES, "utility");
private static final IPathManager PATH_MANAGER = PathManagerFactory private static final IPathManager PATH_MANAGER = PathManagerFactory
.getPathManager(); .getPathManager();
@ -177,6 +182,10 @@ public class GfePyIncludeUtil {
return PATH_MANAGER.getLocalizationFile(ctx, TESTS); return PATH_MANAGER.getLocalizationFile(ctx, TESTS);
} }
public static LocalizationFile getVCModUtilsLF(LocalizationContext ctx) {
return PATH_MANAGER.getLocalizationFile(ctx, VCMOD_UTILS);
}
// Include Path getters // Include Path getters
public static String getCommonPythonIncludePath() { public static String getCommonPythonIncludePath() {
@ -386,4 +395,13 @@ public class GfePyIncludeUtil {
LocalizationType.EDEX_STATIC, siteId), GFE_CONFIG); LocalizationType.EDEX_STATIC, siteId), GFE_CONFIG);
} }
public static String getVCModulesIncludePath() {
return getPath(PATH_MANAGER.getContext(LocalizationType.COMMON_STATIC,
LocalizationLevel.BASE), VCMODULES);
}
public static String getVCModUtilsIncludePath() {
return getPath(PATH_MANAGER.getContext(LocalizationType.COMMON_STATIC,
LocalizationLevel.BASE), VCMOD_UTILS);
}
} }

View file

@ -54,6 +54,7 @@ import com.vividsolutions.jts.geom.Coordinate;
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Aug 11, 2010 mnash Initial creation * Aug 11, 2010 mnash Initial creation
* Dec 28, 2011 11705 gzhang Fix SCAN missing Rows error
* *
* </pre> * </pre>
* *
@ -82,8 +83,9 @@ public class RadarRecordUtil {
.getTheText())) { .getTheText())) {
Map<GraphicBlockValues, String> map = new HashMap<GraphicBlockValues, String>(); Map<GraphicBlockValues, String> map = new HashMap<GraphicBlockValues, String>();
Matcher m = RadarConstants.graphic_block_pattern Matcher m = RadarConstants.graphic_block_pattern
.matcher(((TextSymbolPacket) packets[j]) .matcher(
.getTheText()); getNormalizedGBText( ((TextSymbolPacket) packets[j]).getTheText() )
);
if (m.find()) { if (m.find()) {
String storm_id = m.group(1).trim(); String storm_id = m.group(1).trim();
map.put(GraphicBlockValues.AZIMUTH, m map.put(GraphicBlockValues.AZIMUTH, m
@ -526,5 +528,41 @@ public class RadarRecordUtil {
else else
return Double.parseDouble(s); return Double.parseDouble(s);
} }
/**
* DR#11705: SCAN missing row(s) comparing to radar Comb Att Table.
*
* Error cause: RadarConstants.GRAPHIC_BLOCK as a Regular Expression
* pattern can not match some variations in Graphic Block Texts with
* "<" and ">" having spaces between them and their associated numbers
* ( MXHAILSIZE and TOP ).
*
* Fix: replace all "<" and ">" with space: " "
*
* @param : Graphic Block Text that may contain ">" and/or "<".
* @return: String with ">" and/or "<" replaced by space.
*/
private static String getNormalizedGBText(String text){
if(text == null || text.isEmpty() || ( (! text.contains(">")) && (! text.contains("<")) ) )
return text;
/*
* contains only ">"
*/
if( ! text.contains("<") )
return text.replaceAll(">", " ");
/*
* contains only "<"
*/
if( ! text.contains(">") )
return text.replaceAll("<", " ");
/*
* contains both "<" and ">"
*/
return text.replaceAll(">"," ").replaceAll("<", " ");
}
} }

View file

@ -453,18 +453,20 @@ public class JmsPooledSession {
"Trapped internal exception", trappedExc); "Trapped internal exception", trappedExc);
} }
closePooledConsumersProducers();
// need to close down all wrappers
for (JmsSessionWrapper wrapper : references) {
wrapper.closeInternal();
}
references.clear();
conn.removeSession(this);
// synchronize on the connection to avoid deadlock conditions in // synchronize on the connection to avoid deadlock conditions in
// qpid // qpid
synchronized (conn) { synchronized (conn) {
closePooledConsumersProducers();
// need to close down all wrappers
for (JmsSessionWrapper wrapper : references) {
wrapper.closeInternal();
}
references.clear();
try { try {
sess.close(); sess.close();
} catch (Exception e) { } catch (Exception e) {

View file

@ -109,14 +109,12 @@ public class JmsConnectionWrapper implements Connection {
*/ */
@Override @Override
public void close() throws JMSException { public void close() throws JMSException {
synchronized (this) { if (closeInternal()) {
if (closeInternal()) { // remove this wrapper from the manager
// remove this wrapper from the manager mgr.removeReference(this);
mgr.removeReference(this);
if (exceptionOccurred) { if (exceptionOccurred) {
mgr.close(); mgr.close();
}
} }
} }
} }

View file

@ -132,15 +132,14 @@ public class JmsSessionWrapper implements Session {
*/ */
@Override @Override
public void close() throws JMSException { public void close() throws JMSException {
synchronized (this) { if (closeInternal()) {
if (closeInternal()) { // remove this wrapper from the manager
// remove this wrapper from the manager mgr.removeReference(this);
mgr.removeReference(this);
if (exceptionOccurred) { if (exceptionOccurred) {
mgr.close(); mgr.close();
}
} }
} }
} }