diff --git a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureDlg.java b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureDlg.java index dee0cec572..441b9d7e27 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureDlg.java +++ b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureDlg.java @@ -64,7 +64,6 @@ import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.common.time.DataTime; import com.raytheon.uf.common.util.FileUtil; import com.raytheon.uf.viz.core.DescriptorMap; -import com.raytheon.uf.viz.core.IDisplayPane; import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.core.drawables.AbstractDescriptor; import com.raytheon.uf.viz.core.drawables.AbstractRenderableDisplay; @@ -99,6 +98,7 @@ import com.raytheon.viz.ui.editor.AbstractEditor; * Oct 16, 2012 1229 rferrel Changes for non-blocking AlterBundleDlg. * Oct 16, 2012 1229 rferrel Changes to have displayDialog method. * Oct 16, 2012 1229 rferrel Changes for non-blocking ProcedureListDlg. + * Feb 25, 2013 1640 bsteffen Dispose old display in BundleLoader * * * @@ -858,18 +858,6 @@ public class ProcedureDlg extends CaveSWTDialog { editor.setLoopProperties(b.getLoopProperties()); } - /* - * Check if the bundle was used to open the editor. If it was then we do - * not want to clear the display. - */ - if (editor.getDisplayPanes()[0].getDescriptor() != b.getDisplays()[0] - .getDescriptor()) { - for (IDisplayPane pane : editor.getDisplayPanes()) { - pane.getRenderableDisplay().getDescriptor().getResourceList() - .clear(); - } - } - ProcedureLoadJob.getInstance().enqueue(b, editor); // add to history diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/rsc/DataStoreResource.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/rsc/DataStoreResource.java index d71503394f..047afdf509 100644 --- a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/rsc/DataStoreResource.java +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/rsc/DataStoreResource.java @@ -105,6 +105,7 @@ import com.vividsolutions.jts.geom.Point; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Oct 31, 2012 #1326 randerso Initial creation + * Feb 22, 2013 #1641 randerso Moved ID_ATTRIBUTE_NAME to package scope * * * @@ -115,7 +116,7 @@ import com.vividsolutions.jts.geom.Point; public class DataStoreResource extends AbstractVizResource implements IPropertyChangeListener, IResourceDataChanged { - private static final String ID_ATTRIBUTE_NAME = "Feature.ID"; + static final String ID_ATTRIBUTE_NAME = "Feature.ID"; private static final int CLICK_TOLERANCE = 3; diff --git a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/rsc/ReloadJob.java b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/rsc/ReloadJob.java index b2e471b147..f9025cc6c1 100644 --- a/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/rsc/ReloadJob.java +++ b/cave/com.raytheon.uf.viz.gisdatastore/src/com/raytheon/uf/viz/gisdatastore/rsc/ReloadJob.java @@ -44,6 +44,23 @@ import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryCollection; import com.vividsolutions.jts.geom.Point; +/** + * Job to reload data from GIS data stores + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Oct 31, 2012      #1326 randerso     Initial creation
+ * Feb 22, 2013      #1641 randerso     Added checks for using ID as label or shading attribute
+ * 
+ * 
+ * + * @author randerso + * @version 1.0 + */ class ReloadJob extends Job { private static final int QUEUE_LIMIT = 1; @@ -199,11 +216,16 @@ class ReloadJob extends Job { List fields = new ArrayList(); fields.add(req.geomField); - if (req.labelField != null && !fields.contains(req.labelField)) { + if (req.labelField != null + && !fields.contains(req.labelField) + && !req.labelField + .equals(DataStoreResource.ID_ATTRIBUTE_NAME)) { fields.add(req.labelField); } if (req.shadingField != null - && !fields.contains(req.shadingField)) { + && !fields.contains(req.shadingField) + && !req.shadingField + .equals(DataStoreResource.ID_ATTRIBUTE_NAME)) { fields.add(req.shadingField); } @@ -308,6 +330,16 @@ class ReloadJob extends Job { } } + if (DataStoreResource.ID_ATTRIBUTE_NAME + .equals(req.labelField)) { + labelAttr = id; + } + + if (DataStoreResource.ID_ATTRIBUTE_NAME + .equals(req.shadingField)) { + shadingAttr = id; + } + if (labelAttr != null && g != null) { String label; if (labelAttr instanceof BigDecimal) { diff --git a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/stormtrack/AbstractStormTrackResource.java b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/stormtrack/AbstractStormTrackResource.java index cee7e9acbc..361c626a22 100644 --- a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/stormtrack/AbstractStormTrackResource.java +++ b/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/common/stormtrack/AbstractStormTrackResource.java @@ -64,7 +64,7 @@ import com.raytheon.viz.ui.input.EditableManager; * retrieve the requested line style so * that it can be stored in the * StormTrackState. - * + * 02-12-2013 1600 jsanchez Changed the visibility of the method adjustAngle * * * @author mschenke @@ -269,7 +269,7 @@ public abstract class AbstractStormTrackResource extends * @param angle * @return */ - protected double adjustAngle(double angle) { + public static double adjustAngle(double angle) { double newVal = angle % 360; if (newVal > 180) { newVal -= 360; diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/formatterlauncher/ProductEditorComp.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/formatterlauncher/ProductEditorComp.java index 53665be285..aa538326fa 100644 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/formatterlauncher/ProductEditorComp.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/formatterlauncher/ProductEditorComp.java @@ -1,19 +1,19 @@ /** * 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. **/ @@ -120,7 +120,7 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback; /** * Composite containing the product editor controls. - * + * *
  * SOFTWARE HISTORY
  * Date         Ticket#    Engineer    Description
@@ -143,12 +143,13 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
  *                                     Changes for non-blocking FindReplaceDlg.
  *                                     Changes for non-blocking StoreTransmitDlg.
  *                                     Changes for non-blocking WrapLengthDialog.
- * 
+ * 28 Feb 2013 15889       ryu         Removed detachAttributionPhrase and getVTECActionCodes
+ *
  * 
- * + * * @author lvenable * @version 1.0 - * + * */ public class ProductEditorComp extends Composite implements INotificationObserver { @@ -350,7 +351,7 @@ public class ProductEditorComp extends Composite implements /** * Enumeration of product types. - * + * * @author lvenable */ public enum productTypeEnum { @@ -395,7 +396,7 @@ public class ProductEditorComp extends Composite implements /** * Constructor. - * + * * @param parent * Parent composite. */ @@ -1054,7 +1055,7 @@ public class ProductEditorComp extends Composite implements /** * Store or Transmit text product. - * + * * @param action * STORE: show the Store dialog TRANSMITT: shows the Transmit * dialog. AUTOSTORE: implement autoStore @@ -1136,7 +1137,6 @@ public class ProductEditorComp extends Composite implements boolean retVal = true; if (!textComp.isCorMode()) { - detachAttributionPhrase(); retVal = changeTimes(); } @@ -1237,70 +1237,6 @@ public class ProductEditorComp extends Composite implements return vtecList; } - /** - * get the list of VTEC Action Codes for this segment one Action code per - * VTEC line - */ - private List getVTECActionCodes(SegmentData segData, - ProductDataStruct pds) { - - HashMap segMap = segData.getSementMap(); - TextIndexPoints tipVtec = segMap.get("vtec"); - if (tipVtec == null) { - return new ArrayList(); - } - - int lineCount = tipVtec.getEndIndex().x - tipVtec.getStartIndex().x; - ArrayList actioncodes = new ArrayList(lineCount); - for (int i = 0; i < lineCount; i++) { - String vtec = pds.getProductTextArray()[i - + tipVtec.getStartIndex().x]; - // extract the action code - String vline = vtec.split("/", 3)[1]; - String ac = vline.split("\\.")[1]; - actioncodes.add(ac); - } - return actioncodes; - } - - private void detachAttributionPhrase() { - final String attributionPhraseRgx = "THE NATIONAL WEATHER SERVICE IN [A-Z0-9\\p{Punct}\\s]+?\\n\\n"; - Pattern attribPattern = Pattern.compile(attributionPhraseRgx); - StyledTextComp stc = textComp; - ProductDataStruct pds = stc.getProductDataStruct(); - List segs = pds.getSegmentsArray(); - for (SegmentData segData : segs) { - String newSegTxt = null; - String oldSegTxt = segData.getSementMap().get("ugc").getText(); - TextIndexPoints oldSegTip = segData.getSementMap().get("ugc"); - List actioncodes = getVTECActionCodes(segData, pds); - if (actioncodes == null || actioncodes.isEmpty()) { - return; - } - - if (actioncodes.contains("NEW") || actioncodes.contains("EXA") - || actioncodes.contains("EXB")) { - continue; - } else { - // all actions in {"CON","CAN","UPG","EXT","EXP"} - // Not the first issuance, strip the attribution phrase from - // segment text. - Matcher matcher = attribPattern.matcher(oldSegTxt); - while (matcher.find()) { - newSegTxt = matcher.replaceAll(""); - final int segNum = segs.indexOf(segData) + 1; - statusHandler.handle(Priority.INFO, - "Detached attribution phrase from segment data number " - + segNum); - } - } - - if (newSegTxt != null) { - textComp.replaceText(oldSegTip, newSegTxt); - } - } - } - /** * Retrieve the latest active VTEC for our site from server. Filter and keep * only the ones for this pil. @@ -1574,7 +1510,7 @@ public class ProductEditorComp extends Composite implements /** * Decodes the start and end times of VTEC, return null if all zeros. - * + * * @param vt * The VTEC date string in "yyMMdd'T'HHmm'Z'" format * @return Date object that corresponds to the specified VTEC time or null @@ -1905,7 +1841,7 @@ public class ProductEditorComp extends Composite implements /** * Returns a Date from an encoded YYMMDD and hhmm string. Function name is a * misnomer, but kept from porting AWIPS1 equivalent function. - * + * * @param day * The "calendar day" of the time in Java's "yyMMdd" format. * @param time @@ -1929,7 +1865,7 @@ public class ProductEditorComp extends Composite implements /** * Convert time string in DDHHMM format to a Date. - * + * * @param dtgString * time string in DDHHMM format * @return time converted from input string @@ -2087,14 +2023,14 @@ public class ProductEditorComp extends Composite implements * returns the appropriate expiration time. Expiration time is the earliest * of the specified expiration time, 1 hr if a CAN code is detected, or the * ending time of ongoing events (CON, EXT, EXB, NEW). - * + * * @param issTime * issue time * @param expTime * expire time * @param vtecStr * vtec string - * + * * @return expire time */ public Date getExpireTime(Date issTime, Date expTime, String vtecStr) { @@ -2340,7 +2276,7 @@ public class ProductEditorComp extends Composite implements /** * Get the directory. - * + * * @return The directory */ private String getDir() { @@ -2475,7 +2411,7 @@ public class ProductEditorComp extends Composite implements /** * Display the Find or Find & Replace dialog. - * + * * @param findAndReplace * If true show the Find & Replace dialog, false shows the Find * dialog. @@ -2707,7 +2643,7 @@ public class ProductEditorComp extends Composite implements /* * (non-Javadoc) - * + * * @seecom.raytheon.uf.viz.core.notification.INotificationObserver# * notificationArrived * (com.raytheon.uf.viz.core.notification.NotificationMessage[]) @@ -2878,7 +2814,7 @@ public class ProductEditorComp extends Composite implements /** * Word-wrap the text selected by the user. - * + * */ private void doWrapSelection() { StyledText styledText = textComp.getTextEditorST(); @@ -2959,7 +2895,7 @@ public class ProductEditorComp extends Composite implements /* * (non-Javadoc) - * + * * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime. * IProgressMonitor) */ diff --git a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/formatterlauncher/StoreTransmitDlg.java b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/formatterlauncher/StoreTransmitDlg.java index eeafc5f64e..98174d46bc 100755 --- a/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/formatterlauncher/StoreTransmitDlg.java +++ b/cave/com.raytheon.viz.gfe/src/com/raytheon/viz/gfe/dialogs/formatterlauncher/StoreTransmitDlg.java @@ -65,7 +65,6 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog; * 28May2010 2187 cjeanbap Added StdTextProductFactory * functionality. * 09 NOV 2012 1298 rferrel Changes for non-blocking dialog. - * 10Jan2012 15564 mgamazaychikov Set the awipsWanPil based on productText data * * * @author lvenable @@ -388,15 +387,7 @@ public class StoreTransmitDlg extends CaveSWTDialog implements } else { req = new OUPRequest(); OfficialUserProduct oup = new OfficialUserProduct(); - /* - * DR15564 - set the awipsWanPil based on productText data - */ - String[] splitLines = productText.split("\n"); - String[] firstLine = splitLines[0].split(" "); - String[] secondLine = splitLines[1].split(" "); - String cccc = firstLine[1]; - String productNnnidXxxid = secondLine[0]; - String awipsWanPil = cccc + productNnnidXxxid; + String awipsWanPil = productIdTF.getText(); oup.setAwipsWanPil(awipsWanPil); oup.setProductText(productText); diff --git a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/BundleLoader.java b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/BundleLoader.java index c9056f8739..c16806bc6d 100644 --- a/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/BundleLoader.java +++ b/cave/com.raytheon.viz.ui/src/com/raytheon/viz/ui/BundleLoader.java @@ -37,6 +37,7 @@ import com.raytheon.viz.ui.editor.IMultiPaneEditor; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Jan 8, 2013 mschenke Initial creation + * Feb 25, 2013 1640 bsteffen Dispose old display in BundleLoader * * * @@ -296,7 +297,11 @@ public class BundleLoader extends Job { VizApp.runSync(new Runnable() { @Override public void run() { + IRenderableDisplay oldDisplay = loadTo.getRenderableDisplay(); loadTo.setRenderableDisplay(loadFrom); + if (oldDisplay != null && oldDisplay != loadFrom) { + oldDisplay.dispose(); + } } }); } diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/AbstractDbSourceDataAdaptor.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/AbstractDbSourceDataAdaptor.java index a49d0425ed..956c135f18 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/AbstractDbSourceDataAdaptor.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/AbstractDbSourceDataAdaptor.java @@ -27,6 +27,7 @@ import com.raytheon.uf.common.geospatial.SpatialQueryFactory; import com.raytheon.uf.common.geospatial.SpatialQueryResult; import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.maps.rsc.DbMapQueryFactory; +import com.raytheon.viz.awipstools.common.stormtrack.AbstractStormTrackResource; import com.raytheon.viz.core.map.GeoUtil; import com.raytheon.viz.warngen.gis.ClosestPoint; import com.raytheon.viz.warngen.gis.ClosestPointComparator; @@ -47,6 +48,7 @@ import com.vividsolutions.jts.geom.Point; * pre-history * Sep 25, 2012 #15425 Qinglu Lin Added getGid(). * Oct 17, 2012 jsanchez Added pathcast algorithm. + * Feb 12, 2013 1600 jsanchez Used adjustAngle method from AbstractStormTrackResource. * * * @@ -336,9 +338,10 @@ abstract public class AbstractDbSourceDataAdaptor { gc.setStartingGeographicPoint(cp.getPoint().x, cp.getPoint().y); gc.setDestinationGeographicPoint(closestCoord.x, closestCoord.y); cp.setAzimuth(gc.getAzimuth()); - cp.setOppositeAzimuth(ClosestPoint.adjustAngle(cp.getAzimuth() + 180)); + cp.setOppositeAzimuth(AbstractStormTrackResource.adjustAngle(cp + .getAzimuth() + 180)); cp.setRoundedAzimuth(GeoUtil.roundAzimuth(cp.getAzimuth())); - cp.setOppositeRoundedAzimuth(ClosestPoint.adjustAngle(cp + cp.setOppositeRoundedAzimuth(AbstractStormTrackResource.adjustAngle(cp .getRoundedAzimuth() + 180)); cp.setArea(area); cp.setParentArea(parentArea); diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/DbAreaSourceDataAdaptor.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/DbAreaSourceDataAdaptor.java index 9ef6bc3676..6ad33388a6 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/DbAreaSourceDataAdaptor.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/config/DbAreaSourceDataAdaptor.java @@ -29,14 +29,21 @@ import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.prep.PreparedGeometry; /** + * + * + *
  * 
  * SOFTWARE HISTORY
  * 
- * Date Ticket# Engineer Description ------------ ---------- -----------
- * --------------------------
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Sep 25, 2012 #15425     Qinglu Lin   Updated createClosestPoint().
+ * Feb 13, 2012  1605      jsanchez     Calculated the point based on lat,lon values.
  * 
- * @author jsanchez Sep 25, 2012 #15425 Qinglu Lin Updated createClosestPoint().
+ * 
* + * @author jsanchez + * @version 1.0 */ public class DbAreaSourceDataAdaptor extends AbstractDbSourceDataAdaptor { @@ -46,6 +53,10 @@ public class DbAreaSourceDataAdaptor extends AbstractDbSourceDataAdaptor { private static final String cwaField = "cwa"; + private static final String longitude = "lon"; + + private static final String latitude = "lat"; + public DbAreaSourceDataAdaptor(PathcastConfiguration pathcastConfiguration, UnitConverter distanceToMeters, Geometry searchArea, String localizedSite) throws VizException { @@ -69,6 +80,8 @@ public class DbAreaSourceDataAdaptor extends AbstractDbSourceDataAdaptor { ptFields.add(pointField); ptFields.add(useDirectionField); ptFields.add(suppressedDirectionsField); + ptFields.add(longitude); + ptFields.add(latitude); List fields = null; if (sortBy != null && sortBy.length > 0) { @@ -96,7 +109,7 @@ public class DbAreaSourceDataAdaptor extends AbstractDbSourceDataAdaptor { Map attributes = ptRslt.attributes; String name = String.valueOf(attributes.get(pointField)); - Coordinate point = ptRslt.geometry.getCoordinate(); + Coordinate point = getPoint(attributes); int population = getPopulation(ptFields, attributes); int warngenlev = getWangenlev(ptFields, attributes); List partOfArea = getPartOfArea(ptFields, attributes, @@ -264,4 +277,17 @@ public class DbAreaSourceDataAdaptor extends AbstractDbSourceDataAdaptor { return directions; } + + /** + * Returns a Coordinate based on the lat,lon values in the attributes. + * + * @param attributes + * @return + */ + private Coordinate getPoint(Map attributes) { + double lat = Double.valueOf(String.valueOf(attributes.get(latitude))); + double lon = Double.valueOf(String.valueOf(attributes.get(longitude))); + + return new Coordinate(lon, lat); + } } diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/ClosestPoint.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/ClosestPoint.java index e1fd5398ee..e3fcb8ab00 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/ClosestPoint.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/ClosestPoint.java @@ -39,6 +39,7 @@ import com.vividsolutions.jts.geom.Coordinate; * a copy constructor. * Sep 25, 2012 #15425 Qinglu Lin Updated two ClosestPoint() and added getGid(). * Oct 17, 2012 jsanchez Added setter methods. + * Feb 12, 2013 1600 jsanchez Removed adjustAngle method. * * * @@ -247,26 +248,6 @@ public class ClosestPoint implements Comparable { this.gid = gid; } - /** - * Adjusts the angle from -360/360 to be between -180/180 - * - * @param angle - * @return - */ - public static double adjustAngle(double angle) { - double newVal = angle % 360; - if (newVal > 180) { - newVal -= 360; - } else if (newVal < -180) { - newVal += 360; - } - - if (newVal < 0) { - newVal += 360; - } - return newVal; - } - /* * (non-Javadoc) * diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/ClosestPointComparator.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/ClosestPointComparator.java index 7cfe8691fd..9959d97e89 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/ClosestPointComparator.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/ClosestPointComparator.java @@ -39,6 +39,7 @@ import org.apache.commons.lang.ArrayUtils; * Mar 3, 2011 jsanchez Initial creation * Sep 25, 2012 15425 Qinglu Lin Implemented sorting on 'gid' in ascending order. * Oct 17, 2012 jsanchez Refactored the enum sort to be more flexible. + * Feb 14, 2013 1605 jsanchez Updated the distance comparison for more accuracy. * * * @@ -148,8 +149,7 @@ public class ClosestPointComparator implements Comparator { value = cp1.parentArea.compareTo(cp2.parentArea); break; case DISTANCE: - value = new Integer(cp1.roundedDistance) - .compareTo(cp2.roundedDistance); + value = new Double(cp1.distance).compareTo(cp2.distance); break; case GID: value = new Integer(cp1.gid).compareTo(cp2.gid); diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Wx.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Wx.java index fc157905b8..44f62e3ac1 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Wx.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gis/Wx.java @@ -66,6 +66,7 @@ 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.exception.VizException; +import com.raytheon.viz.awipstools.common.stormtrack.AbstractStormTrackResource; import com.raytheon.viz.awipstools.common.stormtrack.StormTrackDisplay; import com.raytheon.viz.awipstools.common.stormtrack.StormTrackState; import com.raytheon.viz.core.map.GeoUtil; @@ -102,6 +103,7 @@ import com.vividsolutions.jts.geom.Point; * which are at different locations in pathcast. * Oct 17, 2012 jsanchez Moved the path cast data collecting to a separate class. * Jan 31, 2013 1557 jsanchez Used allowDuplicates flag to collect points with duplicate names. + * Feb 12, 2013 1600 jsanchez Used adjustAngle method from AbstractStormTrackResource. * * * @@ -845,9 +847,10 @@ public class Wx { .getCoordinate()); gc.setDestinationGeographicPoint(cen.x, cen.y); cp2.azimuth = gc.getAzimuth(); - cp2.oppositeAzimuth = ClosestPoint.adjustAngle(cp2.azimuth + 180); + cp2.oppositeAzimuth = AbstractStormTrackResource + .adjustAngle(cp2.azimuth + 180); cp2.roundedAzimuth = GeoUtil.roundAzimuth(cp2.azimuth); - cp2.oppositeRoundedAzimuth = ClosestPoint + cp2.oppositeRoundedAzimuth = AbstractStormTrackResource .adjustAngle(cp2.roundedAzimuth + 180); return cp2; diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/BulletListManager.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/BulletListManager.java index d6f25e9212..6bc8c5f88a 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/BulletListManager.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/BulletListManager.java @@ -29,10 +29,11 @@ import com.raytheon.uf.common.dataplugin.warning.config.WarngenConfiguration; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * 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 + * Feb 13, 2013 1606 jsanchez Did not set default bullets for CORs. * * * @@ -87,6 +88,19 @@ public class BulletListManager { * @param damInfoBullets */ public void recreateBullets(Bullet[] bullets, DamInfoBullet[] damInfoBullets) { + recreateBullets(bullets, damInfoBullets, null); + } + + /** + * Separates all the bullets in it's corresponding group. Identifies all the + * bullets that should be selected by default unless the action is a COR. + * + * @param bullets + * @param damInfoBullets + * @param action + */ + public void recreateBullets(Bullet[] bullets, + DamInfoBullet[] damInfoBullets, WarningAction action) { loadBullets(bullets, damInfoBullets); clear(); String damName = null; @@ -128,8 +142,10 @@ public class BulletListManager { } } - for (Integer index : defaultIndices) { - updateSelectedIndices(index, false); + if (action != WarningAction.COR) { + for (Integer index : defaultIndices) { + updateSelectedIndices(index, false); + } } } @@ -153,31 +169,32 @@ public class BulletListManager { /* Test 'showString' to determine if the bullet is to be hidden */ ArrayList displayedBullets = null; ArrayList displayedDamInfoBullets = null; - + for (int pass = 0; pass < 2; ++pass) { - Bullet[] sourceList = pass == 0 ? - configuration.getBullets() : - configuration.getDamInfoBullets(); - ArrayList resultList = new ArrayList(); - 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; + Bullet[] sourceList = pass == 0 ? configuration.getBullets() + : configuration.getDamInfoBullets(); + ArrayList resultList = new ArrayList(); + 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 */ - recreateBullets( - displayedBullets.toArray(new Bullet[displayedBullets.size()]), - displayedDamInfoBullets.toArray(new DamInfoBullet[displayedDamInfoBullets.size()])); + recreateBullets(displayedBullets.toArray(new Bullet[displayedBullets + .size()]), + displayedDamInfoBullets + .toArray(new DamInfoBullet[displayedDamInfoBullets + .size()]), action); if (configuration.getLockedGroupsOnFollowup() != null) { for (String lockedGroup : configuration.getLockedGroupsOnFollowup() @@ -221,20 +238,21 @@ public class BulletListManager { * @param isFollowup */ public void updateSelectedIndices(int selectionIndex, boolean isFollowup) { - updateSelectedIndices(selectionIndex, isFollowup, false); + 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. If selectUnconditionally is true, sets (instead of toggles) * bullets. * * @param selectionIndex * @param isFollowup * @param selectUnconditionally */ - public void updateSelectedIndices(int selectionIndex, boolean isFollowup, boolean selectUnconditionally) { + public void updateSelectedIndices(int selectionIndex, boolean isFollowup, + boolean selectUnconditionally) { if (selectionIndex < 0 || selectionIndex >= bullets.length || titleGroup.contains(selectionIndex)) { return; @@ -243,20 +261,20 @@ public class BulletListManager { Bullet bullet = bullets[selectionIndex]; String group = bullet.getBulletGroup(); - if (group == null) { - if (selectUnconditionally) { - if (!selectedIndices.contains(selectionIndex)) - selectedIndices.add(selectionIndex); - } else { - // toggle - if (selectedIndices.contains(selectionIndex)) { - selectedIndices.remove(selectionIndex); - } else { - selectedIndices.add(selectionIndex); - } - } - return; - } + if (group == null) { + if (selectUnconditionally) { + if (!selectedIndices.contains(selectionIndex)) + selectedIndices.add(selectionIndex); + } else { + // toggle + 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 */ if (isFollowup && lockedGroups.contains(group.toLowerCase())) { @@ -297,30 +315,30 @@ public class BulletListManager { } List groupIndices = bulletGroups.get(group); - for (Integer index : groupIndices) { - /* - * Unselect items in a group except for the latest selection in the - * group - */ - if (selectUnconditionally) { - if (index.equals(selectionIndex)) { - if (!selectedIndices.contains(selectionIndex)) - selectedIndices.add(index); - } else { - 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); - } - } - } + for (Integer index : groupIndices) { + /* + * Unselect items in a group except for the latest selection in the + * group + */ + if (selectUnconditionally) { + if (index.equals(selectionIndex)) { + if (!selectedIndices.contains(selectionIndex)) + selectedIndices.add(index); + } else { + 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); + } + } + } } /** diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenLayer.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenLayer.java index c7736358ac..774ec41dc8 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenLayer.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/gui/WarngenLayer.java @@ -190,11 +190,11 @@ public class WarngenLayer extends AbstractStormTrackResource { private class CustomMaps extends Job { - private Set customMaps = new HashSet(); + private final Set customMaps = new HashSet(); private Set mapsToLoad; - private MapManager manager; + private final MapManager manager; public CustomMaps() { super("Loading WarnGen Maps"); diff --git a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/template/TemplateRunner.java b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/template/TemplateRunner.java index 54c9e5d715..8206c68d76 100644 --- a/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/template/TemplateRunner.java +++ b/cave/com.raytheon.viz.warngen/src/com/raytheon/viz/warngen/template/TemplateRunner.java @@ -76,6 +76,7 @@ import com.raytheon.uf.viz.core.localization.LocalizationManager; import com.raytheon.uf.viz.core.requests.ThriftClient; import com.raytheon.viz.awipstools.ToolsDataManager; import com.raytheon.viz.awipstools.common.StormTrackData; +import com.raytheon.viz.awipstools.common.stormtrack.AbstractStormTrackResource; import com.raytheon.viz.awipstools.common.stormtrack.StormTrackState; import com.raytheon.viz.awipstools.common.stormtrack.StormTrackState.DisplayType; import com.raytheon.viz.core.mode.CAVEMode; @@ -133,6 +134,8 @@ import com.vividsolutions.jts.io.WKTReader; * Dec 17, 2012 15571 Qinglu Lin For hydro products, resolved issue caused by calling wkt.read(loc) * while loc is null. * Jan 8, 2013 15664 Qinglu Lin Appended selectedAction to handler.handle()'s argument list. + * Feb 12, 2013 1600 jsanchez Correctly set the StormTrackData's motion direction for a CAN and EXP. + * Feb 15, 2013 1607 jsanchez Added two variables corEventTime and corCreateTime. * * * @@ -506,17 +509,18 @@ public class TemplateRunner { coords[i] = new Point2D.Double(locs[i].x, locs[i].y); } context.put("eventLocation", coords); - double motionDirection = oldWarn.getMotdir(); - while (motionDirection >= 360) { - motionDirection -= 360; - } - context.put("movementDirection", motionDirection); + context.put("movementDirection", oldWarn.getMotdir()); context.put("movementInKnots", oldWarn.getMotspd()); + // StormTrackData motion direction is between -180/180, + // whereas a WarningRecord motion direction is between + // -360/360 + double motionDirection = AbstractStormTrackResource + .adjustAngle(oldWarn.getMotdir() - 180); StormTrackData std = ToolsDataManager.getInstance() .getStormTrackData(); std.setDate(simulatedTime); - std.setMotionDirection(oldWarn.getMotdir()); + std.setMotionDirection(motionDirection); std.setMotionSpeed(oldWarn.getMotspd()); t0 = System.currentTimeMillis(); ToolsDataManager.getInstance().setStormTrackData(std); @@ -580,9 +584,14 @@ public class TemplateRunner { context.put("start", oldWarn.getIssueTime().getTime()); if (oldWarn.getAct().equals("NEW")) { context.put("now", new Date(wwaMNDTime)); + // original warning's 'now' time used in MND header + context.put("corCreateTime", new Date(wwaMNDTime)); } else context.put("now", simulatedTime); context.put("event", oldWarn.getIssueTime().getTime()); + // original warning's 'event' time, which should match the storm + // track + context.put("corEventTime", eventTime); String message = oldWarn.getRawmessage(); if (!stormTrackState.originalTrack) { diff --git a/edexOsgi/com.raytheon.uf.common.monitor/src/com/raytheon/uf/common/monitor/config/SCANRunSiteConfigurationManager.java b/edexOsgi/com.raytheon.uf.common.monitor/src/com/raytheon/uf/common/monitor/config/SCANRunSiteConfigurationManager.java index e7471ed71d..3ba2f8cd4a 100644 --- a/edexOsgi/com.raytheon.uf.common.monitor/src/com/raytheon/uf/common/monitor/config/SCANRunSiteConfigurationManager.java +++ b/edexOsgi/com.raytheon.uf.common.monitor/src/com/raytheon/uf/common/monitor/config/SCANRunSiteConfigurationManager.java @@ -20,6 +20,28 @@ import com.raytheon.uf.common.monitor.xml.SCANSiteRunConfigXML; import com.raytheon.uf.common.monitor.xml.SCANSiteXML; import com.raytheon.uf.common.serialization.SerializationException; import com.raytheon.uf.common.serialization.SerializationUtil; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; + +/** + * ScanRunSiteConfigurationManager + * + * Holds the SCAN configuration + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 02/07/2009   2037       dhladky    Initial Creation.
+ * 02/25/13     1660       D. Hladky Fixed configuration bug in scan.
+ * 
+ * 
+ * + * @author dhladky + * @version 1.0 + */ + public class SCANRunSiteConfigurationManager implements ILocalizationFileObserver { @@ -27,6 +49,9 @@ public class SCANRunSiteConfigurationManager implements /** Path to FFMP Source config. */ private static final String CONFIG_FILE_NAME = "scan" + File.separatorChar + "SCANRunSiteConfig.xml"; + + private static final IUFStatusHandler statusHandler = UFStatus + .getHandler(SCANRunSiteConfigurationManager.class); /** * SCAN Configuration XML object. @@ -49,7 +74,7 @@ public class SCANRunSiteConfigurationManager implements try { readConfigXml(); } catch (Exception e) { - e.printStackTrace(); + statusHandler.handle(Priority.ERROR, "Can not read the SCAN configuration", e); } } @@ -77,21 +102,19 @@ public class SCANRunSiteConfigurationManager implements File file = lf.getFile(); // System.out.println("Reading -- " + file.getAbsolutePath()); if (!file.exists()) { - System.out - .println("WARNING [SCAN] SCANRunSiteConfigurationManager: " + statusHandler.handle(Priority.WARN, "SCANRunSiteConfigurationManager: " + file.getAbsolutePath() + " does not exist."); try { createValidConfig(); } catch (Exception e) { - System.out - .println("FATAL [SCAN] SCANRunSiteConfigurationManager: Couldn't create valid runnable configuration"); + statusHandler.handle(Priority.ERROR,"SCANRunSiteConfigurationManager: Couldn't create valid runnable configuration"); } } SCANSiteRunConfigXML configXmltmp = null; - configXmltmp = (SCANSiteRunConfigXML) SerializationUtil - .jaxbUnmarshalFromXmlFile(file.getAbsolutePath()); + configXmltmp = SerializationUtil + .jaxbUnmarshalFromXmlFile(SCANSiteRunConfigXML.class, file.getAbsolutePath()); configXml = configXmltmp; isPopulated = true; @@ -135,7 +158,8 @@ public class SCANRunSiteConfigurationManager implements lf = newXmlFile; } catch (Exception e) { - e.printStackTrace(); + statusHandler.handle(Priority.WARN, "SCANRunSiteConfigurationManager: " + + newXmlFile.getName() + " couldn't be saved.", e); } } @@ -153,7 +177,8 @@ public class SCANRunSiteConfigurationManager implements } } } catch (SerializationException e) { - e.printStackTrace(); + statusHandler.handle(Priority.WARN, "SCANRunSiteConfigurationManager: " + + message.getFileName() + " couldn't be updated.", e); } } @@ -236,42 +261,28 @@ public class SCANRunSiteConfigurationManager implements */ List localsites = RadarsInUseUtil.getSite(null, RadarsInUseUtil.LOCAL_CONSTANT); - List dialsites = RadarsInUseUtil.getSite(null, - RadarsInUseUtil.DIAL_CONSTANT); - String modelDefault = "RUC130"; configXml = new SCANSiteRunConfigXML(); // run over list of available sites + int i = 0; for (String site : localsites) { - SCANSiteXML siteXML = new SCANSiteXML(); - siteXML.setScanSite(site); - siteXML.setMenuLocation(RadarsInUseUtil.LOCAL_CONSTANT); + if (i < 12) { // no more than 12 radars in scan config + SCANSiteXML siteXML = new SCANSiteXML(); + siteXML.setScanSite(site); + siteXML.setMenuLocation(RadarsInUseUtil.LOCAL_CONSTANT); - for (DATA_TYPE param : DATA_TYPE.values()) { - SCANModelParameterXML paramXML = new SCANModelParameterXML(); - paramXML.setParameterName(param.getType()); - paramXML.setModelName(modelDefault); - siteXML.addModelParameter(paramXML); + for (DATA_TYPE param : DATA_TYPE.values()) { + SCANModelParameterXML paramXML = new SCANModelParameterXML(); + paramXML.setParameterName(param.getType()); + paramXML.setModelName(modelDefault); + siteXML.addModelParameter(paramXML); + } + + configXml.addSite(siteXML); + i++; } - - configXml.addSite(siteXML); - } - - for (String site : dialsites) { - SCANSiteXML siteXML = new SCANSiteXML(); - siteXML.setScanSite(site); - siteXML.setMenuLocation(RadarsInUseUtil.DIAL_CONSTANT); - - for (DATA_TYPE param : DATA_TYPE.values()) { - SCANModelParameterXML paramXML = new SCANModelParameterXML(); - paramXML.setParameterName(param.getType()); - paramXML.setModelName(modelDefault); - siteXML.addModelParameter(paramXML); - } - - configXml.addSite(siteXML); } saveConfigXml(); diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.cwat/src/com/raytheon/uf/edex/plugin/cwat/CWATGenerator.java b/edexOsgi/com.raytheon.uf.edex.plugin.cwat/src/com/raytheon/uf/edex/plugin/cwat/CWATGenerator.java index 285be2fd99..6705caa142 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.cwat/src/com/raytheon/uf/edex/plugin/cwat/CWATGenerator.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.cwat/src/com/raytheon/uf/edex/plugin/cwat/CWATGenerator.java @@ -28,8 +28,11 @@ import com.raytheon.edex.urifilter.URIFilter; import com.raytheon.edex.urifilter.URIGenerateMessage; import com.raytheon.uf.common.dataplugin.cwat.CWATRecord; import com.raytheon.uf.common.dataplugin.cwat.dao.CWATDao; -import com.raytheon.uf.common.dataplugin.radar.util.RadarsInUseUtil; +import com.raytheon.uf.common.monitor.config.SCANRunSiteConfigurationManager; +import com.raytheon.uf.common.monitor.events.MonitorConfigEvent; +import com.raytheon.uf.common.monitor.events.MonitorConfigListener; import com.raytheon.uf.common.monitor.scan.ScanUtils; +import com.raytheon.uf.common.serialization.SerializationException; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; @@ -37,8 +40,26 @@ import com.raytheon.uf.common.time.DataTime; import com.raytheon.uf.edex.cpgsrv.CompositeProductGenerator; import com.raytheon.uf.edex.plugin.cwat.common.CWATConfig; -public class CWATGenerator extends CompositeProductGenerator { - private static final transient IUFStatusHandler statusHandler = UFStatus +/** + * CWATGenerator Product + * + * CWAT files for use in EDEX. + * + *
+ * SOFTWARE HISTORY
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 02/25/13     1660       D. Hladky Fixed configuration bug in scan.
+ * 
+ * 
+ * + * @author dhladky + * @version 1.0 + */ + +public class CWATGenerator extends CompositeProductGenerator implements + MonitorConfigListener { + private static final IUFStatusHandler statusHandler = UFStatus .getHandler(CWATGenerator.class); private static final String genName = "CWAT"; @@ -47,6 +68,9 @@ public class CWATGenerator extends CompositeProductGenerator { /** Set of icaos to filter for */ private Set icaos = null; + + /** run configuration manager **/ + public SCANRunSiteConfigurationManager srcm = null; /** * Public CWAT constructor @@ -61,12 +85,24 @@ public class CWATGenerator extends CompositeProductGenerator { @Override protected void configureFilters() { - statusHandler.handle(Priority.INFO, "Process Filter Config..."); - // read this from localization eventually - icaos = new HashSet(RadarsInUseUtil.getSite(null, - RadarsInUseUtil.LOCAL_CONSTANT)); - icaos.addAll(RadarsInUseUtil.getSite(null, - RadarsInUseUtil.DIAL_CONSTANT)); + statusHandler.handle(Priority.INFO, getGeneratorName() + + " process Filter Config..."); + + try { + getRunConfig().readConfigXml(); + } catch (SerializationException e) { + statusHandler.handle(Priority.ERROR, + "Couldn't read CWAT(scan) configuration!!!", e); + } + boolean configValid = getRunConfig().isPopulated(); + + if (!configValid) { + statusHandler.handle(Priority.WARN, + "Configuration for CWAT(scan) is invalid!!!"); + return; + } + + icaos = new HashSet(getRunConfig().getSiteNames()); } @Override @@ -82,7 +118,7 @@ public class CWATGenerator extends CompositeProductGenerator { } catch (Exception e) { statusHandler.handle(Priority.ERROR, "Couldn't create CWAT Filter.." + icao - + " is not a viable RADAR site."); + + " is not a viable RADAR site.", e); iter.remove(); } } @@ -97,8 +133,7 @@ public class CWATGenerator extends CompositeProductGenerator { cwa_config = new CWATConfig(genMessage, this); } catch (Exception e) { statusHandler.handle(Priority.ERROR, - "CWAT Configuration parameters for run not met..."); - e.printStackTrace(); + "CWAT Configuration parameters for run not met...",e); return; } @@ -149,4 +184,26 @@ public class CWATGenerator extends CompositeProductGenerator { public boolean isRunning() { return getConfigManager().getCWATState(); } + + @Override + public void configChanged(MonitorConfigEvent fce) { + if (fce.getSource() instanceof SCANRunSiteConfigurationManager) { + statusHandler.handle(Priority.INFO, + "Re-configuring CWAT URI filters...Run Site Config change"); + resetFilters(); + } + } + + /** + * run config manager + * + * @return + */ + public SCANRunSiteConfigurationManager getRunConfig() { + if (srcm == null) { + srcm = SCANRunSiteConfigurationManager.getInstance(); + srcm.addListener(this); + } + return srcm; + } } diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/res/spring/ffmp-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/res/spring/ffmp-ingest.xml index 5ac1430bef..e768457d1a 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/res/spring/ffmp-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/res/spring/ffmp-ingest.xml @@ -12,16 +12,16 @@ - - - + + - + --> - diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/FFMPGenerator.java b/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/FFMPGenerator.java index 9b743dc7de..1f7c5eafae 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/FFMPGenerator.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/FFMPGenerator.java @@ -43,9 +43,12 @@ import com.raytheon.edex.msg.DataURINotificationMessage; import com.raytheon.edex.plugin.radar.dao.RadarStationDao; import com.raytheon.edex.urifilter.URIFilter; import com.raytheon.edex.urifilter.URIGenerateMessage; +import com.raytheon.uf.common.dataplugin.PluginException; import com.raytheon.uf.common.dataplugin.ffmp.FFMPAggregateRecord; import com.raytheon.uf.common.dataplugin.ffmp.FFMPBasinData; +import com.raytheon.uf.common.dataplugin.ffmp.FFMPBasinMetaData; import com.raytheon.uf.common.dataplugin.ffmp.FFMPDataContainer; +import com.raytheon.uf.common.dataplugin.ffmp.FFMPGuidanceInterpolation; import com.raytheon.uf.common.dataplugin.ffmp.FFMPRecord; import com.raytheon.uf.common.dataplugin.ffmp.FFMPTemplates; import com.raytheon.uf.common.dataplugin.ffmp.FFMPTemplates.MODE; @@ -70,6 +73,7 @@ import com.raytheon.uf.common.monitor.events.MonitorConfigEvent; import com.raytheon.uf.common.monitor.events.MonitorConfigListener; import com.raytheon.uf.common.monitor.xml.DomainXML; import com.raytheon.uf.common.monitor.xml.FFMPRunXML; +import com.raytheon.uf.common.monitor.xml.FFTIAttributeXML.ATTRIBUTE; import com.raytheon.uf.common.monitor.xml.FFTISourceXML; import com.raytheon.uf.common.monitor.xml.ProductRunXML; import com.raytheon.uf.common.monitor.xml.ProductXML; @@ -96,8 +100,10 @@ import com.raytheon.uf.edex.database.cluster.ClusterTask; import com.raytheon.uf.edex.plugin.ffmp.common.FFMPConfig; import com.raytheon.uf.edex.plugin.ffmp.common.FFMPProcessor; import com.raytheon.uf.edex.plugin.ffmp.common.FFTI; +import com.raytheon.uf.edex.plugin.ffmp.common.FFTIAccum; import com.raytheon.uf.edex.plugin.ffmp.common.FFTIData; import com.raytheon.uf.edex.plugin.ffmp.common.FFTIProcessor; +import com.raytheon.uf.edex.plugin.ffmp.common.FFTIRatioDiff; /** * @@ -111,6 +117,7 @@ import com.raytheon.uf.edex.plugin.ffmp.common.FFTIProcessor; * 02/03/2011 6500 cjeanbap Fixed NullPointerException. * 07/31/2011 578 dhladky FFTI modifications * 01/27/13 1478 D. Hladky Added creation of full cache records to help read write stress on NAS + * 02/25/13 1660 D. Hladky Redesigned data flow for FFTI in order to have only one mosaic piece in memory at a time. * * * @author dhladky @@ -119,19 +126,18 @@ import com.raytheon.uf.edex.plugin.ffmp.common.FFTIProcessor; public class FFMPGenerator extends CompositeProductGenerator implements MonitorConfigListener { + private static final transient IUFStatusHandler statusHandler = UFStatus .getHandler(FFMPGenerator.class); - /** * Public constructor for FFMPGenerator * * @param name * @param compositeProductType */ - public FFMPGenerator(Executor executor, Executor processexecutor) { + public FFMPGenerator(Executor executor) { super(genName, productType, executor); - this.processexecutor = processexecutor; } private static final String genName = "FFMP"; @@ -164,9 +170,6 @@ public class FFMPGenerator extends CompositeProductGenerator implements /** ffti finished processing **/ public boolean fftiDone = true; - /** products **/ - private ConcurrentHashMap products = null; - /** Processes map **/ private ConcurrentHashMap processes = null; @@ -188,9 +191,6 @@ public class FFMPGenerator extends CompositeProductGenerator implements /** checks for initial load **/ public ArrayList loadedData = new ArrayList(); - /** thread the productkeys **/ - public ConcurrentHashMap> productKeys = new ConcurrentHashMap>(); - /** template config manager **/ public FFMPTemplateConfigurationManager tempConfig = null; @@ -206,12 +206,6 @@ public class FFMPGenerator extends CompositeProductGenerator implements "apps_dir") + File.separator + "ffmp" + File.separator; - /** source bins used for finding basin to data correlations **/ - private HashMap sourceBins = new HashMap(); - - /** thread executor **/ - public Executor processexecutor = null; - @Override protected void configureFilters() { @@ -394,8 +388,7 @@ public class FFMPGenerator extends CompositeProductGenerator implements statusHandler.handle(Priority.PROBLEM, "Couldn't create FFMP Filter.." + " primary Domain: " + domain.getCwa() - + " this RUNNER is not a viable FFMP config."); - e.printStackTrace(); + + " this RUNNER is not a viable FFMP config.", e); } } @@ -452,7 +445,6 @@ public class FFMPGenerator extends CompositeProductGenerator implements long time = System.currentTimeMillis(); this.config = new FFMPConfig( (FFMPURIGenerateMessage) genMessage, this); - products = new ConcurrentHashMap(); processes = new ConcurrentHashMap(); // read config updates, make sure we don't miss something getRunConfig().readConfigXml(); @@ -466,7 +458,6 @@ public class FFMPGenerator extends CompositeProductGenerator implements } // start threads - for (String source : processes.keySet()) { this.getExecutor().execute( new ProcessProduct(processes.get(source), this)); @@ -476,72 +467,48 @@ public class FFMPGenerator extends CompositeProductGenerator implements while (processes.size() > 0) { // wait for all threads to finish before returning try { - Thread.sleep(100); - statusHandler.handle(Priority.DEBUG, - "Checking status ..." + processes.size()); - for (String source : processes.keySet()) { + Thread.sleep(50); + if (statusHandler.isPriorityEnabled(Priority.DEBUG)) { statusHandler.handle(Priority.DEBUG, - "Still processing ..." + source); + "Checking status ..." + processes.size()); + for (String source : processes.keySet()) { + statusHandler.handle(Priority.DEBUG, + "Still processing ..." + source); + } } } catch (InterruptedException e) { - e.printStackTrace(); + statusHandler.handle(Priority.ERROR, "Process thread had been interupted!", e); } } - if (products.size() > 0) { + if (fftiSources.size() > 0) { + this.getExecutor().execute(new FFTI(this)); + } - // Do the FFTI evaluation, if we have FFTI sources - if (fftiSources.size() > 0) { - this.getExecutor().execute(new FFTI(this)); - } - - ArrayList records = new ArrayList( - products.size()); - for (String source : products.keySet()) { - for (FFMPRecord rec : products.get(source)) { - records.add(rec); - } - } - - FFMPRecord[] recs = new FFMPRecord[records.size()]; - for (int i = 0; i < records.size(); i++) { - recs[i] = records.get(i); - } - - this.setPluginDataObjects(recs); - this.setPluginDao(new FFMPDao(getCompositeProductType(), - template, fscm, config.getCWA())); - - while (fftiSources.size() > 0) { - try { - Thread.sleep(100); + while (fftiSources.size() > 0) { + try { + Thread.sleep(50); + if (statusHandler.isPriorityEnabled(Priority.DEBUG)) { statusHandler.handle(Priority.DEBUG, "Checking status ..." + fftiDone); - } catch (InterruptedException e) { - statusHandler.handle(Priority.DEBUG, - "Checking status failed!" + e); } + } catch (InterruptedException e) { + statusHandler.handle(Priority.DEBUG, + "Checking status failed!" + e); } - - statusHandler.handle( - Priority.INFO, - config.getCWA() + " finished, duration: " - + (System.currentTimeMillis() - time) - + " ms, wrote " + records.size() + " "); - - } else { - statusHandler.handle(Priority.WARN, config.getCWA() - + " no new products to produce."); } - // dump data we don't need anymore + + statusHandler.handle(Priority.INFO, config.getCWA() + + " finished, duration: " + + (System.currentTimeMillis() - time) + " ms "); + ffmpData.clear(); // suggest garbage collection System.gc(); } catch (Throwable e) { statusHandler.handle(Priority.ERROR, - "Unable to process FFMP Records."); - e.printStackTrace(); + "Unable to process FFMP Records.", e); } } } @@ -587,7 +554,6 @@ public class FFMPGenerator extends CompositeProductGenerator implements private class ProcessProduct implements Runnable { SourceXML ffmpProduct; - FFMPGenerator generator; @Override @@ -603,9 +569,10 @@ public class FFMPGenerator extends CompositeProductGenerator implements "ProcessProduct: Finishing thread " + ffmpProduct.getSourceName()); } catch (Exception e) { - processes.remove(ffmpProduct.getSourceName()); statusHandler.handle(Priority.ERROR, "ProcessProduct: removed " + ffmpProduct.getSourceName(), e); + } finally { + processes.remove(ffmpProduct.getSourceName()); } } @@ -621,9 +588,7 @@ public class FFMPGenerator extends CompositeProductGenerator implements HashMap dataHash = config.getSourceData(ffmpProduct .getSourceName()); - ArrayList ffmpRecords = new ArrayList( - dataHash.size()); - + FFMPRunXML runner = getRunConfig().getRunner(config.getCWA()); // process all of the dataKeys for this source @@ -702,80 +667,55 @@ public class FFMPGenerator extends CompositeProductGenerator implements sites.add(siteKey); } - int i = 0; - if (sites != null) { - // set the latch keys - ArrayList lsites = new ArrayList(); - for (String site : sites) { - lsites.add(site); - } - - productKeys.put(ffmpProduct.getSourceName(), lsites); - } - - for (String productKey : sites) { + // Go over all of the sites, if mosaic source, can be many. + for (String siteKey : sites) { FFMPRecord ffmpRec = new FFMPRecord(); ffmpRec.setSourceName(ffmpProduct.getSourceName()); ffmpRec.setDataKey(dataKey); - ffmpRec.setSiteKey(productKey); + ffmpRec.setSiteKey(siteKey); ffmpRec.setPluginName(getCompositeProductType()); ffmpRec.setWfo(config.getCWA()); FFMPProcessor ffmp = new FFMPProcessor(config, generator, ffmpRec, template); ffmpRec = ffmp.processFFMP(ffmpProduct); ffmpRec.constructDataURI(); - + if (ffmpRec != null) { + + persistRecord(ffmpRec); + processDataContainer(ffmpRec, siteKey); + // Now that we have the data container, + // we can process FFTI for this piece of the mosaic if (ffmp.isFFTI()) { + fftiDone = false; - if (!fftiSources.contains(ffmp.getFFTISource())) { + FFTISourceXML fftiSource = ffmp.getFFTISource(); + + // This only runs once for the site key loop + if (!fftiSources.contains(fftiSource)) { FFTIProcessor ffti = new FFTIProcessor( generator, ffmpRec, ffmp.getFFTISource()); fftiSources.add(ffmp.getFFTISource()); ffti.processFFTI(); } + + // Do the accumulation now, more memory efficient. + // Only one piece in memory at a time + for (String attribute: ffmp.getAttributes()) { + if (attribute.equals(ATTRIBUTE.ACCUM.getAttribute())) { + FFTIAccum accum = getAccumulationForSite(ffmpProduct.getDisplayName(), siteKey, dataKey, fftiSource.getDurationHour(), ffmpProduct.getUnit(siteKey)); + if (statusHandler.isPriorityEnabled(Priority.DEBUG)) { + statusHandler.debug("Accumulating FFTI for source: "+ffmpProduct.getDisplayName()+" site: "+siteKey+" data: "+dataKey+" duration: "+fftiSource.getDurationHour()+ " accumulation: "+accum.getAccumulation()); + } + } + } } - // this is a threaded process!!!!!!!!!!! - // Added this to speed the processing of mosaiced - // sources. - // Before all processing was in line to the source - // thread. - // This caused slowness in the overall processing. - // By allowing the mosaic components to be concurrently - // processed it has drastically sped up overall FFMP - // performance. - processDataContainer(ffmpRec, productKey); - ffmpRecords.add(ffmpRec); - } - i++; - } - - while (productKeys.size() > 0) { - // wait for all threads to finish before returning - try { - Thread.sleep(100); - statusHandler.handle(Priority.DEBUG, - "Checking status ..." + productKeys.size()); - for (String source : productKeys.keySet()) { - statusHandler.handle(Priority.DEBUG, - "Still processing ..." + source); - } - } catch (InterruptedException e) { - statusHandler.handle(Priority.WARN, - "Product Procesing Interrupted! " + e); } } } - - FFMPRecord[] recs = new FFMPRecord[ffmpRecords.size()]; - for (int i = 0; i < ffmpRecords.size(); i++) { - recs[i] = ffmpRecords.get(i); - } - products.put(ffmpProduct.getSourceName(), recs); - processes.remove(ffmpProduct.getSourceName()); } } @@ -885,7 +825,7 @@ public class FFMPGenerator extends CompositeProductGenerator implements // Didn't process a domain, locked by another cluster // member, sleep and try again try { - Thread.sleep(100); + Thread.sleep(50); } catch (InterruptedException e) { statusHandler.handle(Priority.WARN, "Domain processing Interrupted!", e); @@ -1044,15 +984,7 @@ public class FFMPGenerator extends CompositeProductGenerator implements * @return */ public SourceBinList getSourceBinList(String sourceId) { - SourceBinList sbl = null; - if (!sourceBins.containsKey(sourceId)) { - sbl = readSourceBins(sourceId); - sourceBins.put(sourceId, sbl); - } else { - sbl = sourceBins.get(sourceId); - } - - return sbl; + return readSourceBins(sourceId); } /** @@ -1061,7 +993,6 @@ public class FFMPGenerator extends CompositeProductGenerator implements * @param sbl */ public void setSourceBinList(SourceBinList sbl) { - sourceBins.put(sbl.getSourceId(), sbl); writeSourceBins(sbl); } @@ -1228,238 +1159,181 @@ public class FFMPGenerator extends CompositeProductGenerator implements } /** - * Process this data container - * - * @param sourceSiteDataKey - * @param huc - * @param wfo - * @return + * Process the ffmp data container + * @param ffmpRec + * @param productKey */ public void processDataContainer(FFMPRecord ffmpRec, String productKey) { - this.getProcessExecutor().execute( - new ProcessDataContainer(ffmpRec, productKey)); - } + String sourceName = null; + Date backDate = null; + String sourceSiteDataKey = null; + FFMPDataContainer fdc = null; + boolean write = true; - /** - * Inner class to thread writing of BuddyFiles - * - * @author dhladky - * - */ - private class ProcessDataContainer implements Runnable { + try { + // write out the fast loader cache file + long ptime = System.currentTimeMillis(); + SourceXML source = getSourceConfig().getSource( + ffmpRec.getSourceName()); + String dataKey = ffmpRec.getDataKey(); - private FFMPRecord ffmpRec; - - private String productKey; - - public void run() { - try { - processDataContainer(ffmpRec, productKey); - } catch (Exception e) { - statusHandler.handle(Priority.ERROR, - "ProcessDataContainer: removed " + e.getMessage()); + if (source.getSourceType().equals( + SOURCE_TYPE.GUIDANCE.getSourceType())) { + sourceName = source.getDisplayName(); + sourceSiteDataKey = sourceName; + // FFG is so infrequent go back a day + backDate = new Date( + config.getDate().getTime() + - (TimeUtil.MILLIS_PER_HOUR * FFG_SOURCE_CACHE_TIME)); + } else { + sourceName = ffmpRec.getSourceName(); + sourceSiteDataKey = sourceName + "-" + ffmpRec.getSiteKey() + + "-" + dataKey; + backDate = new Date(ffmpRec.getDataTime().getRefTime() + .getTime() + - (TimeUtil.MILLIS_PER_HOUR * SOURCE_CACHE_TIME)); } - } - public ProcessDataContainer(FFMPRecord ffmpRec, String productKey) { - this.ffmpRec = ffmpRec; - this.productKey = productKey; - } + // deal with setting of needed HUCS + ArrayList hucs = template.getTemplateMgr() + .getHucLevels(); - /** - * Process this data container - * - * @param ffmpRec - * @param write - */ - private void processDataContainer(FFMPRecord ffmpRec, String productKey) { + if (source.getSourceType().equals( + SOURCE_TYPE.GAGE.getSourceType()) + || source.getSourceType().equals( + SOURCE_TYPE.GUIDANCE.getSourceType())) { + hucs.clear(); + hucs.add("ALL"); + } else { + hucs.remove("VIRTUAL"); + } - String sourceName = null; - Date backDate = null; - String sourceSiteDataKey = null; - FFMPDataContainer fdc = null; - boolean write = true; + // pull from disk if there + fdc = getFFMPDataContainer(sourceSiteDataKey, hucs, backDate); - try { - // write out the fast loader cache file + // brand new or initial load up + if (fdc == null || !loadedData.contains(sourceSiteDataKey)) { - long ptime = System.currentTimeMillis(); - SourceXML source = getSourceConfig().getSource( - ffmpRec.getSourceName()); - String dataKey = ffmpRec.getDataKey(); + long time = System.currentTimeMillis(); + fdc = new FFMPDataContainer(sourceSiteDataKey, hucs); + fdc = FFTIProcessor.populateDataContainer(fdc, template, + hucs, backDate, ffmpRec.getDataTime().getRefTime(), + ffmpRec.getWfo(), source, ffmpRec.getSiteKey()); - if (source.getSourceType().equals( + if (!loadedData.contains(sourceSiteDataKey)) { + loadedData.add(sourceSiteDataKey); + } + + long time2 = System.currentTimeMillis(); + statusHandler.handle(Priority.DEBUG, + "Populated new source: in " + (time2 - time) + + " ms: source: " + sourceSiteDataKey); + + } else { + + long time = System.currentTimeMillis(); + // guidance sources are treated as a mosaic and are handled + // differently. They are force read at startup. + // This is the main line sequence a source will take when + // updated. + if (!source.getSourceType().equals( SOURCE_TYPE.GUIDANCE.getSourceType())) { - sourceName = source.getDisplayName(); - sourceSiteDataKey = sourceName; - // FFG is so infrequent go back a day - backDate = new Date( - config.getDate().getTime() - - (TimeUtil.MILLIS_PER_HOUR * FFG_SOURCE_CACHE_TIME)); - } else { - sourceName = ffmpRec.getSourceName(); - sourceSiteDataKey = sourceName + "-" + ffmpRec.getSiteKey() - + "-" + dataKey; - backDate = new Date(ffmpRec.getDataTime().getRefTime() - .getTime() - - (TimeUtil.MILLIS_PER_HOUR * SOURCE_CACHE_TIME)); - } - // deal with setting of needed HUCS - ArrayList hucs = template.getTemplateMgr() - .getHucLevels(); + Date newDate = fdc.getNewest(); + Date oldDate = fdc.getOldest(); - if (source.getSourceType().equals( - SOURCE_TYPE.GAGE.getSourceType()) - || source.getSourceType().equals( - SOURCE_TYPE.GUIDANCE.getSourceType())) { - hucs.clear(); - hucs.add("ALL"); - } else { - hucs.remove("VIRTUAL"); - } + if (newDate != null && oldDate != null) { + if ((ffmpRec.getDataTime().getRefTime().getTime() - newDate + .getTime()) >= (source + .getExpirationMinutes(ffmpRec.getSiteKey()) * TimeUtil.MILLIS_PER_MINUTE)) { + // force a re-query back to the newest time in + // existing source container, this will fill in + // gaps + // if + // they exist. + fdc = FFTIProcessor.populateDataContainer(fdc, + template, null, newDate, ffmpRec + .getDataTime().getRefTime(), + ffmpRec.getWfo(), source, ffmpRec + .getSiteKey()); - // pull from disk if there - fdc = getFFMPDataContainer(sourceSiteDataKey, hucs, backDate); - - // brand new or initial load up - if (fdc == null || !loadedData.contains(sourceSiteDataKey)) { - - long time = System.currentTimeMillis(); - fdc = new FFMPDataContainer(sourceSiteDataKey, hucs); - fdc = FFTIProcessor.populateDataContainer(fdc, template, - hucs, backDate, ffmpRec.getDataTime().getRefTime(), - ffmpRec.getWfo(), source, ffmpRec.getSiteKey()); - - if (!loadedData.contains(sourceSiteDataKey)) { - loadedData.add(sourceSiteDataKey); + } else if (oldDate + .after(new Date( + backDate.getTime() + - (source + .getExpirationMinutes(ffmpRec + .getSiteKey()) * TimeUtil.MILLIS_PER_MINUTE)))) { + // force a re-query back to barrierTime for + // existing source container, this happens if + // the + // ingest was turned off for some period of + // time. + fdc = FFTIProcessor.populateDataContainer(fdc, + template, null, backDate, oldDate, + ffmpRec.getWfo(), source, + ffmpRec.getSiteKey()); + } } long time2 = System.currentTimeMillis(); statusHandler.handle(Priority.DEBUG, - "Populated new source: in " + (time2 - time) + "Checked Source files: in " + (time2 - time) + " ms: source: " + sourceSiteDataKey); + } + } + // add current record data + for (String huc : hucs) { + fdc.addFFMPEntry(ffmpRec.getDataTime().getRefTime(), + source, ffmpRec.getBasinData(huc), huc, + ffmpRec.getSiteKey()); + } + // set the name + fdc.setFilePath("" + sharePath + ffmpRec.getWfo() + "/" + + sourceSiteDataKey); + // cache it temporarily for FFTI use + if (source.getSourceType().equals( + SOURCE_TYPE.GUIDANCE.getSourceType())) { + // only write last one + write = false; + + if (!ffmpData.containsKey(sourceSiteDataKey)) { + ffmpData.put(sourceSiteDataKey, fdc); } else { + ffmpData.replace(sourceSiteDataKey, fdc); + } + } - long time = System.currentTimeMillis(); - // guidance sources are treated as a mosaic and are handled - // differently. They are force read at startup. - // This is the main line sequence a source will take when - // updated. - if (!source.getSourceType().equals( - SOURCE_TYPE.GUIDANCE.getSourceType())) { + statusHandler.handle( + Priority.INFO, + "Processed FFMPDataContainer: in " + + (System.currentTimeMillis() - ptime) + + " ms: source: " + sourceSiteDataKey); + } catch (Exception e) { + statusHandler.handle(Priority.ERROR, + "Failed Processing FFMPDataContainer" + e.getMessage()); - Date newDate = fdc.getNewest(); - Date oldDate = fdc.getOldest(); - - if (newDate != null && oldDate != null) { - if ((ffmpRec.getDataTime().getRefTime().getTime() - newDate - .getTime()) >= (source - .getExpirationMinutes(ffmpRec.getSiteKey()) * TimeUtil.MILLIS_PER_MINUTE)) { - // force a re-query back to the newest time in - // existing source container, this will fill in - // gaps - // if - // they exist. - fdc = FFTIProcessor.populateDataContainer(fdc, - template, null, newDate, ffmpRec - .getDataTime().getRefTime(), - ffmpRec.getWfo(), source, ffmpRec - .getSiteKey()); - - } else if (oldDate - .after(new Date( - backDate.getTime() - - (source - .getExpirationMinutes(ffmpRec - .getSiteKey()) * TimeUtil.MILLIS_PER_MINUTE)))) { - // force a re-query back to barrierTime for - // existing source container, this happens if - // the - // ingest was turned off for some period of - // time. - fdc = FFTIProcessor.populateDataContainer(fdc, - template, null, backDate, oldDate, - ffmpRec.getWfo(), source, - ffmpRec.getSiteKey()); - } - } - - long time2 = System.currentTimeMillis(); - statusHandler.handle(Priority.DEBUG, - "Checked Source files: in " + (time2 - time) - + " ms: source: " + sourceSiteDataKey); - } + } finally { + // purge it up + if (fdc != null) { + // this is defensive for if errors get thrown + if (backDate == null) { + backDate = new Date((System.currentTimeMillis()) + - (TimeUtil.MILLIS_PER_HOUR * SOURCE_CACHE_TIME)); } - // add current record data - for (String huc : hucs) { - fdc.addFFMPEntry(ffmpRec.getDataTime().getRefTime(), - source, ffmpRec.getBasinData(huc), huc, - ffmpRec.getSiteKey()); - } - // set the name - fdc.setFilePath("" + sharePath + ffmpRec.getWfo() + "/" - + sourceSiteDataKey); - // cache it temporarily for FFTI use - if (source.getSourceType().equals( - SOURCE_TYPE.GUIDANCE.getSourceType())) { - // only write last one - write = false; + fdc.purge(backDate); - if (!ffmpData.containsKey(sourceSiteDataKey)) { - ffmpData.put(sourceSiteDataKey, fdc); - } else { - ffmpData.replace(sourceSiteDataKey, fdc); - } - } - - statusHandler.handle( - Priority.INFO, - "Processed FFMPDataContainer: in " - + (System.currentTimeMillis() - ptime) - + " ms: source: " + sourceSiteDataKey); - } catch (Exception e) { - statusHandler.handle(Priority.ERROR, - "Failed Processing FFMPDataContainer" + e.getMessage()); - - } finally { - // moved writing here to remain safe from possible race - // condition between processing threads - if (productKeys != null) { - if (productKeys.containsKey(ffmpRec.getSourceName())) { - productKeys.get(ffmpRec.getSourceName()).remove( - productKey); - // System.out.println("Removed productKey: "+productKey); - if (productKeys.get(ffmpRec.getSourceName()).size() == 0) { - // System.out.println("Removed source: "+ffmpRec.getSourceName()+" now writing"); - productKeys.remove(ffmpRec.getSourceName()); - // last one, allow write - write = true; - } - } - } - // purge it up - if (fdc != null) { - // this is defensive for if errors get thrown - if (backDate == null) { - backDate = new Date((System.currentTimeMillis()) - - (TimeUtil.MILLIS_PER_HOUR * SOURCE_CACHE_TIME)); - } - - fdc.purge(backDate); - - if (write) { - // write it out - writeCacheFiles(fdc); - } + if (write) { + // write it out + writeCacheFiles(fdc); } } } } + /** * load existing container * @@ -1744,7 +1618,6 @@ public class FFMPGenerator extends CompositeProductGenerator implements } else { if (file.exists() && file.canRead() && file.canWrite() && (file.lastModified() > backDate.getTime())) { - // System.out.println("File update and exists..."+sourceSiteDataKey); return true; } } @@ -1791,10 +1664,6 @@ public class FFMPGenerator extends CompositeProductGenerator implements ffgCheck = false; resetFilters(); - if (sourceBins != null) { - sourceBins.clear(); - } - loadedData.clear(); if (ffmpData != null) { @@ -1953,18 +1822,285 @@ public class FFMPGenerator extends CompositeProductGenerator implements public ConcurrentHashMap getFFTIDataContainer() { return fftiData; } - + /** - * the executor runner + * Get value for an individual piece of the puzzle * + * @param fftiSourceKey + * @param fftiSiteKey + * @param fftiDataKey + * @param duration + * @param unit * @return */ - public Executor getProcessExecutor() { - return processexecutor; - } + public FFTIAccum getAccumulationForSite(String fftiSourceKey, + String fftiSiteKey, String fftiDataKey, double duration, String unit) { - public void setProcessExecutor(Executor processexecutor) { - this.processexecutor = processexecutor; + SourceXML ffmpSource = getSourceConfig() + .getSourceByDisplayName(fftiSourceKey); + FFTIAccum accumulator = null; + String siteDataKey = ffmpSource.getDisplayName() + "-" + fftiSiteKey + + "-" + fftiDataKey; + + if (isFFTI(siteDataKey)) { + accumulator = (FFTIAccum) getFFTIData(siteDataKey); + } else { + accumulator = new FFTIAccum(); + } + + // This will only happen at initial load, update, and duration changes. + if (accumulator.isReset() || accumulator.getDuration() != duration) { + + accumulator.setDuration(duration); + accumulator.setUnit(unit); + + if (ffmpSource.isMosaic()) { + accumulator.setName(ffmpSource.getDisplayName()); + } else { + accumulator.setName(fftiSiteKey + "-" + fftiSourceKey); + } + + long cur = config.getDate().getTime(); + long timeBack = (long) (duration * TimeUtil.MILLIS_PER_HOUR); + Date backDate = new Date(cur - timeBack); + long expirationTime = ffmpSource.getExpirationMinutes(fftiSiteKey) * TimeUtil.MILLIS_PER_MINUTE; + + FFMPDataContainer fdc = null; + + ArrayList hucs = new ArrayList(); + hucs.add("ALL"); + + fdc = getFFMPDataContainer(siteDataKey, hucs, backDate); + + if (fdc != null) { + + FFMPBasinData fbd = fdc.getBasinData("ALL"); + + // go over the list of CWAs gathering the pfaf list + ArrayList pfafs = new ArrayList(); + ArrayList cwaList = config.fdm.getCwaList(); + + Double gap = FFTI.getGap(fdc, ffmpSource, config.getDate(), duration, fftiSiteKey); + + if (!Double.isNaN(gap)) { + for (Long key : fbd.getBasins().keySet()) { + for (String cwa : cwaList) { + + boolean primary = false; + if (cwa.equals(config.getCWA())) { + primary = true; + } + + FFMPBasinMetaData fmdb = template.getBasin( + fftiSiteKey, key); + + if (fmdb == null) { + continue; + } + + // Gets buffer zones adjacent to CWA + if ((cwa.equals(fmdb.getCwa())) + || (primary && fmdb.isPrimaryCwa())) { + if (!pfafs.contains(key)) { + pfafs.add(key); + } + } + } + } + + double amount = fdc.getMaxValue(pfafs, backDate, + config.getDate(), expirationTime, + ffmpSource.isRate()); + + // max value for monitored area + accumulator.setAccumulation(amount); + accumulator.setGap(gap); + } + } + + ffmpData.remove(siteDataKey); + accumulator.setReset(false); + writeFFTIData(siteDataKey, accumulator); + } + + return accumulator; + } + + /** + * Gets the ratio and difference values for this site + * + * @param qSourceKey + * @param qSiteKey + * @param ffgType + * @param duration + * @param unit + * @return + */ + public FFTIRatioDiff getRatioAndDiffForSite(String qSourceKey, + String qSiteKey, String ffgType, double duration, String unit) { + + FFTIRatioDiff values = null; + SourceXML ffmpQSource = fscm.getSourceByDisplayName(qSourceKey); + + if (ffmpQSource == null) { + ffmpQSource = fscm.getSource(qSourceKey); + } + + String siteDataKey = ffgType + "-" + ffmpQSource.getSourceName() + "-" + + qSiteKey; + + if (isFFTI(siteDataKey)) { + values = (FFTIRatioDiff) getFFTIData(siteDataKey); + if (values.getGuids() == null || values.getQpes() == null) { + values.setReset(true); + } + } else { + values = new FFTIRatioDiff(); + } + + // This will only happen at initial load, update, and duration changes. + if (values.isReset() || values.getDuration() != duration) { + + values.setDuration(duration); + values.setUnit(unit); + + long cur = config.getDate().getTime(); + long timeBack = (long) (duration * TimeUtil.MILLIS_PER_HOUR); + Date backDate = new Date(cur - timeBack); + long expirationTime = ffmpQSource.getExpirationMinutes(qSiteKey) * TimeUtil.MILLIS_PER_MINUTE; + + // make sure we have data + Date ffgBackDate = new Date(config.getDate().getTime() + - (TimeUtil.MILLIS_PER_HOUR * FFMPGenerator.FFG_SOURCE_CACHE_TIME)); + + String primarySource = fscm.getPrimarySource(ffmpQSource); + ProductXML product = fscm.getProduct(primarySource); + ArrayList hucs = new ArrayList(); + hucs.add("ALL"); + + FFMPDataContainer guidContainer = getFFMPDataContainer( + ffgType, hucs, ffgBackDate); + + long guidSourceExpiration = 0l; + + if (guidContainer == null) { + guidContainer = new FFMPDataContainer(ffgType, hucs); + } + + for (SourceXML iguidSource : product + .getGuidanceSourcesByType(ffgType)) { + + if (guidSourceExpiration == 0l) { + guidSourceExpiration = iguidSource + .getExpirationMinutes(qSiteKey) * TimeUtil.MILLIS_PER_MINUTE; + break; + } + } + + // if still nothing, punt! + if (guidContainer.size() == 0) { + + statusHandler.handle(Priority.PROBLEM, + "FFTI: No guidance sources available for " + qSiteKey + + " " + qSourceKey + " " + " comparison."); + return values; + } + + String qpeSiteSourceDataKey = ffmpQSource.getSourceName() + "-" + qSiteKey + "-"+ qSiteKey; + FFMPDataContainer qpeContainer = getFFMPDataContainer(qpeSiteSourceDataKey, hucs, backDate); + + if (qpeContainer != null) { + // go over the list of CWAs gathering the pfaf list + ArrayList pfafs = new ArrayList(); + ArrayList cwaList = config.fdm.getCwaList(); + FFMPBasinData fbd = qpeContainer.getBasinData("ALL"); + + for (Long key : fbd.getBasins().keySet()) { + for (String cwa : cwaList) { + + boolean primary = false; + if (cwa.equals(config.getCWA())) { + primary = true; + } + + FFMPBasinMetaData fmdb = template.getBasin(qSiteKey, + key); + + if (fmdb == null) { + continue; + } + + // Gets buffer zones adjacent to CWA + if ((cwa.equals(fmdb.getCwa())) + || (primary && fmdb.isPrimaryCwa())) { + if (!pfafs.contains(key)) { + pfafs.add(key); + } + } + } + } + + Double gap = FFTI.getGap(qpeContainer, ffmpQSource, config.getDate(), duration, + qSiteKey); + + if (!Double.isNaN(gap)) { + + ArrayList qpes = qpeContainer.getBasinData("ALL") + .getAccumValues(pfafs, backDate, config.getDate(), + expirationTime, false); + + FFMPGuidanceInterpolation interpolator = new FFMPGuidanceInterpolation( + fscm, product, frcm.getRunner( + config.getCWA()).getProduct(qSiteKey), + primarySource, ffgType, qSiteKey); + interpolator.setInterpolationSources(duration); + + ArrayList guids = guidContainer.getBasinData("ALL") + .getGuidanceValues(pfafs, interpolator, + guidSourceExpiration); + + values.setQpes(qpes); + values.setGuids(guids); + values.setGap(gap); + } + } else { + return values; + } + + // replace or insert it + ffmpData.remove(qpeSiteSourceDataKey); + values.setReset(false); + writeFFTIData(siteDataKey, values); + } + + return values; + } + + /** + * Persist the record that has finished processing. + * This is different than other DAT tools. + * Other tools wait until all are finished processing + * before persisting. FFMP persists as it goes in order + * to lessen the data surge being sent to pypies. + * + * @param record + * @return + */ + private synchronized void persistRecord(FFMPRecord record) { + + // persist out this record + try { + setPluginDataObjects(new FFMPRecord[]{record}); + setPluginDao(new FFMPDao(getCompositeProductType(), + template, fscm, config.getCWA())); + persistRecords(); + fireTopicUpdate(); + // clear out pdos that are written + pdos = null; + } catch (PluginException e) { + statusHandler.handle(Priority.PROBLEM, "Couldn't persist the record.", e); + } + } } \ No newline at end of file diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/common/FFMPProcessor.java b/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/common/FFMPProcessor.java index 47467bdad6..72f7853309 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/common/FFMPProcessor.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/common/FFMPProcessor.java @@ -25,6 +25,7 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -93,6 +94,7 @@ import com.vividsolutions.jts.geom.Polygon; * * 07/14/09 2152 D. Hladky Initial release * 10/25/12 DR 15514 G. Zhang Fix ConcurrentModificationException + * 02/25/13 1660 D. Hladky FFTI design change to help mosaic processing. * * * @author dhladky @@ -163,6 +165,8 @@ public class FFMPProcessor { private static final String sourceBinTaskName = "FFMP Source bin"; private boolean isFFTI = false; + + private List fftiAttribute = new ArrayList(); private FFTISourceXML fftiSource = null; @@ -1734,16 +1738,16 @@ public class FFMPProcessor { SOURCE_TYPE.QPE.getSourceType())) { fftiSource = setting.getQpeSource(); isFFTI = true; - break; + fftiAttribute.add(setting.getAttribute().getAttributeName()); } else if (source.getSourceType().equals( SOURCE_TYPE.QPF.getSourceType())) { fftiSource = setting.getQpfSource(); isFFTI = true; - break; + fftiAttribute.add(setting.getAttribute().getAttributeName()); } else { fftiSource = setting.getGuidSource(); isFFTI = true; - break; + fftiAttribute.add(setting.getAttribute().getAttributeName()); } } @@ -1756,7 +1760,7 @@ public class FFMPProcessor { .getDisplayName())) { fftiSource = setting.getQpeSource(); isFFTI = true; - break; + fftiAttribute.add(setting.getAttribute().getAttributeName()); } } } @@ -1771,7 +1775,7 @@ public class FFMPProcessor { fftiSource = setting.getQpfSource(); isFFTI = true; - break; + fftiAttribute.add(setting.getAttribute().getAttributeName()); } } } @@ -1797,6 +1801,14 @@ public class FFMPProcessor { public FFTISourceXML getFFTISource() { return fftiSource; } + + /** + * Returns the FFTI attributes for this source + * @return + */ + public List getAttributes() { + return fftiAttribute; + } /** * composite source ID key diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/common/FFTI.java b/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/common/FFTI.java index dafc0fbcc0..1e0b5f6e4a 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/common/FFTI.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.ffmp/src/com/raytheon/uf/edex/plugin/ffmp/common/FFTI.java @@ -24,12 +24,8 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; -import com.raytheon.uf.common.dataplugin.ffmp.FFMPBasinData; -import com.raytheon.uf.common.dataplugin.ffmp.FFMPBasinMetaData; import com.raytheon.uf.common.dataplugin.ffmp.FFMPDataContainer; import com.raytheon.uf.common.dataplugin.ffmp.FFMPGap; -import com.raytheon.uf.common.dataplugin.ffmp.FFMPGuidanceInterpolation; -import com.raytheon.uf.common.dataplugin.ffmp.FFMPTemplates; import com.raytheon.uf.common.dataplugin.ffmp.FFMPUtils; import com.raytheon.uf.common.monitor.config.FFMPSourceConfigurationManager; import com.raytheon.uf.common.monitor.config.FFMPSourceConfigurationManager.SOURCE_TYPE; @@ -57,6 +53,7 @@ import com.raytheon.uf.edex.plugin.ffmp.FFMPGenerator; * ------------ ---------- ----------- -------------------------- * Apr 01, 2011 dhladky Initial creation * July 13, 2012 dhladky Revamped to help memory + * 02/25/13 1660 D. Hladky Moved FFTI processing to help with mosaic memory usage * * * @@ -78,8 +75,6 @@ public class FFTI implements Runnable { private FFMPGenerator ffmpgen = null; - private FFMPTemplates templates = null; - private DecimalFormat formatter = null; private Priority messagePriority = Priority.INFO; @@ -92,8 +87,6 @@ public class FFTI implements Runnable { this.ffmpgen = ffmpgen; this.config = ffmpgen.config; this.fdm = ffmpgen.config.fdm; - this.templates = ffmpgen.template; - this.formatter = new DecimalFormat(); formatter.setMaximumFractionDigits(2); formatter.setMinimumIntegerDigits(1); @@ -113,9 +106,6 @@ public class FFTI implements Runnable { alertMessage.append(createAlertMessages()); monitorHandler.handle(messagePriority, alertMessage.toString()); } - // Debug - // statusHandler.handle(Priority.INFO, alertMessage.toString()); - } private boolean processSettings() { @@ -244,7 +234,7 @@ public class FFTI implements Runnable { for (int j = 0; j < sites.size(); j++) { - FFTIAccum faccum = getAccumulationForSite(displayName, + FFTIAccum faccum = ffmpgen.getAccumulationForSite(displayName, sites.get(j), dataKey, duration, source.getUnit()); @@ -287,7 +277,7 @@ public class FFTI implements Runnable { source = ffmpgen.getSourceConfig().getSourceByDisplayName( fftiSourceKey); - accum = getAccumulationForSite(fftiSourceKey, fftiSiteKey, + accum = ffmpgen.getAccumulationForSite(fftiSourceKey, fftiSiteKey, fftiSiteKey, duration, source.getUnit()); if (accum != null) { @@ -336,7 +326,7 @@ public class FFTI implements Runnable { for (String site : sites) { - FFTIRatioDiff values = getRatioAndDiffForSite( + FFTIRatioDiff values = ffmpgen.getRatioAndDiffForSite( qSourceXML.getSourceName(), site, guidDisplayNames.get(0), duration, unit); @@ -398,7 +388,7 @@ public class FFTI implements Runnable { qSourceXML = ffmpgen.fscm.getSourceByDisplayName(qSourceKey); unit = qSourceXML.getUnit(); - FFTIRatioDiff values = getRatioAndDiffForSite( + FFTIRatioDiff values = ffmpgen.getRatioAndDiffForSite( qSourceXML.getSourceName(), qSiteKey, guidDisplayNames.get(0), duration, unit); @@ -790,259 +780,6 @@ public class FFTI implements Runnable { return sites; } - /** - * Get value for an individual piece of the puzzle - * - * @param fftiSourceKey - * @param fftiSiteKey - * @param duration - * @return - */ - private FFTIAccum getAccumulationForSite(String fftiSourceKey, - String fftiSiteKey, String fftiDataKey, double duration, String unit) { - - SourceXML ffmpSource = ffmpgen.getSourceConfig() - .getSourceByDisplayName(fftiSourceKey); - FFTIAccum accumulator = null; - String siteDataKey = ffmpSource.getDisplayName() + "-" + fftiSiteKey - + "-" + fftiDataKey; - - if (ffmpgen.isFFTI(siteDataKey)) { - accumulator = (FFTIAccum) ffmpgen.getFFTIData(siteDataKey); - } else { - accumulator = new FFTIAccum(); - } - - // This will only happen at initial load, update, and duration changes. - if (accumulator.isReset() || accumulator.getDuration() != duration) { - - accumulator.setDuration(duration); - accumulator.setUnit(unit); - - if (ffmpSource.isMosaic()) { - accumulator.setName(ffmpSource.getDisplayName()); - } else { - accumulator.setName(fftiSiteKey + "-" + fftiSourceKey); - } - - long cur = config.getDate().getTime(); - long timeBack = (long) (duration * TimeUtil.MILLIS_PER_HOUR); - Date backDate = new Date(cur - timeBack); - long expirationTime = ffmpSource.getExpirationMinutes(fftiSiteKey) * TimeUtil.MILLIS_PER_MINUTE; - - FFMPDataContainer fdc = null; - - ArrayList hucs = new ArrayList(); - hucs.add("ALL"); - - fdc = ffmpgen.getFFMPDataContainer(siteDataKey, hucs, backDate); - - if (fdc != null) { - - FFMPBasinData fbd = fdc.getBasinData("ALL"); - - // go over the list of CWAs gathering the pfaf list - ArrayList pfafs = new ArrayList(); - ArrayList cwaList = fdm.getCwaList(); - - Double gap = getGap(fdc, ffmpSource, duration, fftiSiteKey); - - if (gap != Double.NaN) { - for (Long key : fbd.getBasins().keySet()) { - for (String cwa : cwaList) { - - boolean primary = false; - if (cwa.equals(config.getCWA())) { - primary = true; - } - - FFMPBasinMetaData fmdb = templates.getBasin( - fftiSiteKey, key); - - if (fmdb == null) { - continue; - } - - // Gets buffer zones adjacent to CWA - if ((cwa.equals(fmdb.getCwa())) - || (primary && fmdb.isPrimaryCwa())) { - if (!pfafs.contains(key)) { - pfafs.add(key); - } - } - } - } - - double amount = fdc.getMaxValue(pfafs, backDate, - config.getDate(), expirationTime, - ffmpSource.isRate()); - - // max value for monitored area - accumulator.setAccumulation(amount); - accumulator.setGap(gap); - } - } - - // replace or insert it, memory management - if (ffmpgen.ffmpData.containsKey(siteDataKey)) { - ffmpgen.ffmpData.remove(siteDataKey); - } - accumulator.setReset(false); - ffmpgen.writeFFTIData(siteDataKey, accumulator); - } - - return accumulator; - } - - /** - * Gets the ratio and difference values for this site - * @param qSourceKey - * @param qSiteKey - * @param ffgType - * @param duration - * @param unit - * @return - */ - private FFTIRatioDiff getRatioAndDiffForSite(String qSourceKey, - String qSiteKey, String ffgType, double duration, String unit) { - - FFTIRatioDiff values = null; - SourceXML ffmpQSource = ffmpgen.fscm.getSourceByDisplayName(qSourceKey); - - if (ffmpQSource == null) { - ffmpQSource = ffmpgen.fscm.getSource(qSourceKey); - } - - String siteDataKey = ffgType + "-" + ffmpQSource.getSourceName() + "-" - + qSiteKey; - - if (ffmpgen.isFFTI(siteDataKey)) { - values = (FFTIRatioDiff) ffmpgen.getFFTIData(siteDataKey); - if (values.getGuids() == null || values.getQpes() == null) { - values.setReset(true); - } - } else { - values = new FFTIRatioDiff(); - } - - // This will only happen at initial load, update, and duration changes. - if (values.isReset() || values.getDuration() != duration) { - - values.setDuration(duration); - values.setUnit(unit); - - long cur = config.getDate().getTime(); - long timeBack = (long) (duration * TimeUtil.MILLIS_PER_HOUR); - Date backDate = new Date(cur - timeBack); - long expirationTime = ffmpQSource.getExpirationMinutes(qSiteKey) * TimeUtil.MILLIS_PER_MINUTE; - - // make sure we have data - Date ffgBackDate = new Date(config.getDate().getTime() - - (TimeUtil.MILLIS_PER_HOUR * FFMPGenerator.FFG_SOURCE_CACHE_TIME)); - - String primarySource = ffmpgen.fscm.getPrimarySource(ffmpQSource); - ProductXML product = ffmpgen.fscm.getProduct(primarySource); - ArrayList hucs = new ArrayList(); - hucs.add("ALL"); - - FFMPDataContainer guidContainer = ffmpgen.getFFMPDataContainer( - ffgType, hucs, ffgBackDate); - - long guidSourceExpiration = 0l; - - if (guidContainer == null) { - guidContainer = new FFMPDataContainer(ffgType, hucs); - } - - for (SourceXML iguidSource : product - .getGuidanceSourcesByType(ffgType)) { - - if (guidSourceExpiration == 0l) { - guidSourceExpiration = iguidSource - .getExpirationMinutes(qSiteKey) * TimeUtil.MILLIS_PER_MINUTE; - break; - } - } - - // if still nothing, punt! - if (guidContainer.size() == 0) { - - statusHandler.handle(Priority.PROBLEM, - "FFTI: No guidance sources available for " + qSiteKey - + " " + qSourceKey + " " + " comparison."); - return values; - } - - FFMPDataContainer qpeContainer = ffmpgen.getFFMPDataContainer( - ffmpQSource.getSourceName() + "-" + qSiteKey + "-" - + qSiteKey, hucs, backDate); - - if (qpeContainer != null) { - // go over the list of CWAs gathering the pfaf list - ArrayList pfafs = new ArrayList(); - ArrayList cwaList = fdm.getCwaList(); - FFMPBasinData fbd = qpeContainer.getBasinData("ALL"); - - for (Long key : fbd.getBasins().keySet()) { - for (String cwa : cwaList) { - - boolean primary = false; - if (cwa.equals(config.getCWA())) { - primary = true; - } - - FFMPBasinMetaData fmdb = templates.getBasin(qSiteKey, - key); - - if (fmdb == null) { - continue; - } - - // Gets buffer zones adjacent to CWA - if ((cwa.equals(fmdb.getCwa())) - || (primary && fmdb.isPrimaryCwa())) { - if (!pfafs.contains(key)) { - pfafs.add(key); - } - } - } - } - - Double gap = getGap(qpeContainer, ffmpQSource, duration, - qSiteKey); - - if (gap != Double.NaN) { - - ArrayList qpes = qpeContainer.getBasinData("ALL") - .getAccumValues(pfafs, backDate, config.getDate(), - expirationTime, false); - - FFMPGuidanceInterpolation interpolator = new FFMPGuidanceInterpolation( - ffmpgen.fscm, product, ffmpgen.frcm.getRunner( - config.getCWA()).getProduct(qSiteKey), - primarySource, ffgType, qSiteKey); - interpolator.setInterpolationSources(duration); - - ArrayList guids = guidContainer.getBasinData("ALL") - .getGuidanceValues(pfafs, interpolator, - guidSourceExpiration); - - values.setQpes(qpes); - values.setGuids(guids); - values.setGap(gap); - } - } else { - return values; - } - - // replace or insert it - values.setReset(false); - ffmpgen.writeFFTIData(siteDataKey, values); - } - - return values; - } - /** * gets the gap * @@ -1051,12 +788,11 @@ public class FFTI implements Runnable { * @param duration * @return */ - private Double getGap(FFMPDataContainer qpeContainer, - SourceXML ffmpQSource, double duration, String qSiteKey) { + public static Double getGap(FFMPDataContainer qpeContainer, + SourceXML ffmpQSource, Date curdate, double duration, String qSiteKey) { - long cur = config.getDate().getTime(); long timeBack = (long) (duration * TimeUtil.MILLIS_PER_HOUR); - Date backDate = new Date(cur - timeBack); + Date backDate = new Date(curdate.getTime() - timeBack); long expirationTime = ffmpQSource.getExpirationMinutes(qSiteKey); Double gapVal = 0.0; @@ -1065,7 +801,7 @@ public class FFTI implements Runnable { gapVal = 0.0; List gaps = FFMPGap.getGaps( qpeContainer.getOrderedTimes(backDate), expirationTime, - backDate, config.getDate()); + backDate, curdate); for (FFMPGap gap : gaps) { gapVal += gap.getGap(); } diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.preciprate/src/com/raytheon/uf/edex/plugin/preciprate/PrecipRateGenerator.java b/edexOsgi/com.raytheon.uf.edex.plugin.preciprate/src/com/raytheon/uf/edex/plugin/preciprate/PrecipRateGenerator.java index f5335af5c7..2457c47d68 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.preciprate/src/com/raytheon/uf/edex/plugin/preciprate/PrecipRateGenerator.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.preciprate/src/com/raytheon/uf/edex/plugin/preciprate/PrecipRateGenerator.java @@ -29,7 +29,10 @@ import com.raytheon.edex.urifilter.URIGenerateMessage; import com.raytheon.uf.common.dataplugin.preciprate.PrecipRateRecord; import com.raytheon.uf.common.dataplugin.preciprate.dao.PrecipRateDao; import com.raytheon.uf.common.dataplugin.radar.util.RadarConstants.DHRValues; -import com.raytheon.uf.common.dataplugin.radar.util.RadarsInUseUtil; +import com.raytheon.uf.common.monitor.config.SCANRunSiteConfigurationManager; +import com.raytheon.uf.common.monitor.events.MonitorConfigEvent; +import com.raytheon.uf.common.monitor.events.MonitorConfigListener; +import com.raytheon.uf.common.serialization.SerializationException; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; @@ -47,6 +50,7 @@ import com.raytheon.uf.edex.plugin.preciprate.common.PrecipRateConfig; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 01/25/10 3796 D. Hladky Initial release + * 02/25/13 1660 D. Hladky Fixed SCAN configuration bug. * * * @@ -54,13 +58,18 @@ import com.raytheon.uf.edex.plugin.preciprate.common.PrecipRateConfig; * @version 1 */ -public class PrecipRateGenerator extends CompositeProductGenerator { - private static final transient IUFStatusHandler statusHandler = UFStatus +public class PrecipRateGenerator extends CompositeProductGenerator implements +MonitorConfigListener{ + + private static final IUFStatusHandler statusHandler = UFStatus .getHandler(PrecipRateGenerator.class); private static final String genName = "PrecipRate"; private static final String productType = "preciprate"; + + /** run configuration manager **/ + public SCANRunSiteConfigurationManager srcm = null; /** Set of icaos to filter for */ private Set icaos = null; @@ -77,11 +86,24 @@ public class PrecipRateGenerator extends CompositeProductGenerator { @Override protected void configureFilters() { - logger.debug(getGeneratorName() + " process Filter Config..."); - icaos = new HashSet(RadarsInUseUtil.getSite(null, - RadarsInUseUtil.LOCAL_CONSTANT)); - icaos.addAll(RadarsInUseUtil.getSite(null, - RadarsInUseUtil.DIAL_CONSTANT)); + statusHandler.handle(Priority.INFO, getGeneratorName() + + " process Filter Config..."); + + try { + getRunConfig().readConfigXml(); + } catch (SerializationException e) { + statusHandler.handle(Priority.ERROR, + "Couldn't read PrecipRate(scan) configuration!!!", e); + } + boolean configValid = getRunConfig().isPopulated(); + + if (!configValid) { + statusHandler.handle(Priority.WARN, + "Configuration for PrecipRate(scan) is invalid!!!"); + return; + } + + icaos = new HashSet(getRunConfig().getSiteNames()); } @Override @@ -96,7 +118,7 @@ public class PrecipRateGenerator extends CompositeProductGenerator { } catch (Exception e) { statusHandler.handle(Priority.PROBLEM, "Couldn't create PrecipRate URIFilter.." + icao - + " is not a know RADAR site."); + + " is not a know RADAR site.", e); iter.remove(); } } @@ -168,4 +190,26 @@ public class PrecipRateGenerator extends CompositeProductGenerator { return getConfigManager().getPrecipRateState(); } + @Override + public void configChanged(MonitorConfigEvent fce) { + if (fce.getSource() instanceof SCANRunSiteConfigurationManager) { + statusHandler.handle(Priority.INFO, + "Re-configuring PrecipRate URI filters...Run Site Config change"); + resetFilters(); + } + } + + /** + * run config manager + * + * @return + */ + public SCANRunSiteConfigurationManager getRunConfig() { + if (srcm == null) { + srcm = SCANRunSiteConfigurationManager.getInstance(); + srcm.addListener(this); + } + return srcm; + } + } diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.qpf/src/com/raytheon/uf/edex/plugin/qpf/QPFGenerator.java b/edexOsgi/com.raytheon.uf.edex.plugin.qpf/src/com/raytheon/uf/edex/plugin/qpf/QPFGenerator.java index db365841e5..750eecde04 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.qpf/src/com/raytheon/uf/edex/plugin/qpf/QPFGenerator.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.qpf/src/com/raytheon/uf/edex/plugin/qpf/QPFGenerator.java @@ -29,8 +29,11 @@ import com.raytheon.edex.urifilter.URIGenerateMessage; import com.raytheon.uf.common.dataplugin.qpf.QPFRecord; import com.raytheon.uf.common.dataplugin.qpf.QPFRecord.DATA_TYPE; import com.raytheon.uf.common.dataplugin.qpf.dao.QPFDao; -import com.raytheon.uf.common.dataplugin.radar.util.RadarsInUseUtil; +import com.raytheon.uf.common.monitor.config.SCANRunSiteConfigurationManager; +import com.raytheon.uf.common.monitor.events.MonitorConfigEvent; +import com.raytheon.uf.common.monitor.events.MonitorConfigListener; import com.raytheon.uf.common.monitor.scan.ScanUtils; +import com.raytheon.uf.common.serialization.SerializationException; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; @@ -49,6 +52,7 @@ import com.raytheon.uf.edex.plugin.qpf.common.QPFConfig; * 02/07/2009 1981 dhladky Initial Creation. * 04/27/2012 #562 dgilling Accept getter and setter * renames in QPFRecord. + * 02/25/13 1660 D. Hladky Fixed configuration bug in scan. * * * @@ -56,7 +60,8 @@ import com.raytheon.uf.edex.plugin.qpf.common.QPFConfig; * @version 1.0 */ -public class QPFGenerator extends CompositeProductGenerator { +public class QPFGenerator extends CompositeProductGenerator implements + MonitorConfigListener { private static final transient IUFStatusHandler statusHandler = UFStatus .getHandler(QPFGenerator.class); @@ -65,6 +70,9 @@ public class QPFGenerator extends CompositeProductGenerator { private static final String productType = "qpf"; + /** run configuration manager **/ + public SCANRunSiteConfigurationManager srcm = null; + /** Set of icaos to filter for */ private Set icaos = null; @@ -92,7 +100,7 @@ public class QPFGenerator extends CompositeProductGenerator { } catch (Exception e) { statusHandler.handle(Priority.PROBLEM, "Couldn't create QPF URIFilter.." + icao - + " is not a know RADAR site."); + + " is not a know RADAR site.", e); iter.remove(); } } @@ -102,11 +110,24 @@ public class QPFGenerator extends CompositeProductGenerator { @Override protected void configureFilters() { - logger.info(getGeneratorName() + " process Filter Config..."); - icaos = new HashSet(RadarsInUseUtil.getSite(null, - RadarsInUseUtil.LOCAL_CONSTANT)); - icaos.addAll(RadarsInUseUtil.getSite(null, - RadarsInUseUtil.DIAL_CONSTANT)); + statusHandler.handle(Priority.INFO, getGeneratorName() + + " process Filter Config..."); + + try { + getRunConfig().readConfigXml(); + } catch (SerializationException e) { + statusHandler.handle(Priority.ERROR, + "Couldn't read qpf(scan) configuration!!!", e); + } + boolean configValid = getRunConfig().isPopulated(); + + if (!configValid) { + statusHandler.handle(Priority.WARN, + "Configuration for qpf(scan) is invalid!!!"); + return; + } + + icaos = new HashSet(getRunConfig().getSiteNames()); } @Override @@ -168,4 +189,26 @@ public class QPFGenerator extends CompositeProductGenerator { return getConfigManager().getQPFState(); } + /** + * run config manager + * + * @return + */ + public SCANRunSiteConfigurationManager getRunConfig() { + if (srcm == null) { + srcm = SCANRunSiteConfigurationManager.getInstance(); + srcm.addListener(this); + } + return srcm; + } + + @Override + public void configChanged(MonitorConfigEvent fce) { + if (fce.getSource() instanceof SCANRunSiteConfigurationManager) { + statusHandler.handle(Priority.INFO, + "Re-configuring QPF URI filters...Run Site Config change"); + resetFilters(); + } + } + } diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.scan/src/com/raytheon/uf/edex/plugin/scan/ScanGenerator.java b/edexOsgi/com.raytheon.uf.edex.plugin.scan/src/com/raytheon/uf/edex/plugin/scan/ScanGenerator.java index a7aba994f3..88915ba558 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.scan/src/com/raytheon/uf/edex/plugin/scan/ScanGenerator.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.scan/src/com/raytheon/uf/edex/plugin/scan/ScanGenerator.java @@ -47,9 +47,26 @@ import com.raytheon.uf.edex.cpgsrv.CompositeProductGenerator; import com.raytheon.uf.edex.dat.utils.DatMenuUtil; import com.raytheon.uf.edex.dat.utils.ScanDataCache; +/** + * Generator implementation for SCAN + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#     Engineer    Description
+ * ------------ ----------  ----------- --------------------------
+ * 02/25/13     1660        D. Hladky   Fixed SCAN configuration bug.
+ * 
+ * 
+ * + * @author dhladky + * @version 1 + */ + public class ScanGenerator extends CompositeProductGenerator implements MonitorConfigListener { - private static final transient IUFStatusHandler statusHandler = UFStatus + private static final IUFStatusHandler statusHandler = UFStatus .getHandler(ScanGenerator.class); private static final String genName = "SCAN"; @@ -79,21 +96,22 @@ public class ScanGenerator extends CompositeProductGenerator implements @Override protected void configureFilters() { - statusHandler.handle(Priority.DEBUG, getGeneratorName() + statusHandler.handle(Priority.INFO, getGeneratorName() + " process Filter Config..."); try { getRunConfig().readConfigXml(); } catch (SerializationException e) { - e.printStackTrace(); + statusHandler.handle(Priority.ERROR, "Couldn't read scan configuration!!!", e); } boolean configValid = getRunConfig().isPopulated(); if (!configValid) { + statusHandler.handle(Priority.WARN, + "Configuration for SCAN is invalid!!!"); return; } - logger.debug(getGeneratorName() + " process Filter Config..."); icaos = new HashSet(getRunConfig().getSiteNames()); } @@ -110,7 +128,7 @@ public class ScanGenerator extends CompositeProductGenerator implements } catch (Exception e) { statusHandler.handle(Priority.PROBLEM, "Couldn't create SCAN URIFilter.." + icao - + " is not a known RADAR site."); + + " is not a known RADAR site.", e); iter.remove(); } } diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.vil/src/com/raytheon/uf/edex/plugin/vil/VILGenerator.java b/edexOsgi/com.raytheon.uf.edex.plugin.vil/src/com/raytheon/uf/edex/plugin/vil/VILGenerator.java index 0f42816e1b..43ba2ad369 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.vil/src/com/raytheon/uf/edex/plugin/vil/VILGenerator.java +++ b/edexOsgi/com.raytheon.uf.edex.plugin.vil/src/com/raytheon/uf/edex/plugin/vil/VILGenerator.java @@ -26,11 +26,14 @@ import java.util.Set; import com.raytheon.edex.urifilter.URIFilter; import com.raytheon.edex.urifilter.URIGenerateMessage; -import com.raytheon.uf.common.dataplugin.radar.util.RadarsInUseUtil; import com.raytheon.uf.common.dataplugin.vil.VILRecord; import com.raytheon.uf.common.dataplugin.vil.VILRecord.DATA_TYPE; import com.raytheon.uf.common.dataplugin.vil.dao.VILDao; +import com.raytheon.uf.common.monitor.config.SCANRunSiteConfigurationManager; +import com.raytheon.uf.common.monitor.events.MonitorConfigEvent; +import com.raytheon.uf.common.monitor.events.MonitorConfigListener; import com.raytheon.uf.common.monitor.scan.ScanUtils; +import com.raytheon.uf.common.serialization.SerializationException; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; @@ -47,6 +50,7 @@ import com.raytheon.uf.edex.plugin.vil.common.VILConfig; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * 02/07/2009 2037 dhladky Initial Creation. + * 02/25/13 1660 D. Hladky Fixed SCAN configuration bug. * * * @@ -54,8 +58,9 @@ import com.raytheon.uf.edex.plugin.vil.common.VILConfig; * @version 1.0 */ -public class VILGenerator extends CompositeProductGenerator { - private static final transient IUFStatusHandler statusHandler = UFStatus +public class VILGenerator extends CompositeProductGenerator implements + MonitorConfigListener { + private static final IUFStatusHandler statusHandler = UFStatus .getHandler(VILGenerator.class); private static final String genName = "VIL"; @@ -64,6 +69,9 @@ public class VILGenerator extends CompositeProductGenerator { /** Set of icaos to filter for */ private Set icaos = null; + + /** run configuration manager **/ + public SCANRunSiteConfigurationManager srcm = null; /** * Public constructor for VILGenerator @@ -88,7 +96,7 @@ public class VILGenerator extends CompositeProductGenerator { } catch (Exception e) { statusHandler.handle(Priority.PROBLEM, "Couldn't create VIL URIFilter.." + icao - + " is not a know RADAR site."); + + " is not a know RADAR site.", e); iter.remove(); } } @@ -98,11 +106,24 @@ public class VILGenerator extends CompositeProductGenerator { @Override protected void configureFilters() { - statusHandler.handle(Priority.DEBUG, "Process Filter Config..."); - icaos = new HashSet(RadarsInUseUtil.getSite(null, - RadarsInUseUtil.LOCAL_CONSTANT)); - icaos.addAll(RadarsInUseUtil.getSite(null, - RadarsInUseUtil.DIAL_CONSTANT)); + statusHandler.handle(Priority.INFO, getGeneratorName() + + " process Filter Config..."); + + try { + getRunConfig().readConfigXml(); + } catch (SerializationException e) { + statusHandler.handle(Priority.ERROR, + "Couldn't read VIL(scan) configuration!!!", e); + } + boolean configValid = getRunConfig().isPopulated(); + + if (!configValid) { + statusHandler.handle(Priority.WARN, + "Configuration for vil(scan) is invalid!!!"); + return; + } + + icaos = new HashSet(getRunConfig().getSiteNames()); } @Override @@ -161,4 +182,26 @@ public class VILGenerator extends CompositeProductGenerator { return getConfigManager().getVILState(); } + @Override + public void configChanged(MonitorConfigEvent fce) { + if (fce.getSource() instanceof SCANRunSiteConfigurationManager) { + statusHandler.handle(Priority.INFO, + "Re-configuring VIL URI filters...Run Site Config change"); + resetFilters(); + } + } + + /** + * run config manager + * + * @return + */ + public SCANRunSiteConfigurationManager getRunConfig() { + if (srcm == null) { + srcm = SCANRunSiteConfigurationManager.getInstance(); + srcm.addListener(this); + } + return srcm; + } + }