Merge "Issue #1473: Fix Alarm Alert NPE" into development

Former-commit-id: edaf980163ff2f3770cb125b9a837a23ca1b16b2
This commit is contained in:
Richard Peter 2013-01-14 11:55:35 -06:00 committed by Gerrit Code Review
commit 0f705ac355

View file

@ -92,7 +92,7 @@ import com.vividsolutions.jts.geom.GeometryFactory;
*/ */
/** /**
* @author michaelg * @author michaelg
* *
*/ */
public class AlarmAlertFunctions { public class AlarmAlertFunctions {
@ -113,23 +113,23 @@ public class AlarmAlertFunctions {
private static final transient IUFStatusHandler statusHandler = UFStatus private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(AlarmAlertFunctions.class); .getHandler(AlarmAlertFunctions.class);
private static final Pattern UGC_NEW_PATTERN = Pattern private static final Pattern UGC_NEW_PATTERN = Pattern
.compile("^(([A-Z]{3})(\\d{3}))$"); .compile("^(([A-Z]{3})(\\d{3}))$");
private static final Pattern UGC_FOLLOW_PATTERN = Pattern private static final Pattern UGC_FOLLOW_PATTERN = Pattern
.compile("^(\\d{3})$"); .compile("^(\\d{3})$");
private static String DEFAULT_DISTANCE="3000"; private static String DEFAULT_DISTANCE = "3000";
private static final String HYPHEN = Pattern.quote("-"); private static final String HYPHEN = Pattern.quote("-");
public static final Pattern UGC = Pattern public static final Pattern UGC = Pattern
.compile("(^(\\w{2}[CZ]\\d{3}\\S*-\\d{6}-)$|((\\d{3}-)*\\d{6}-)$|((\\d{3}-)+))"); .compile("(^(\\w{2}[CZ]\\d{3}\\S*-\\d{6}-)$|((\\d{3}-)*\\d{6}-)$|((\\d{3}-)+))");
private static final double ONE_DEGREE_MI = 69.09; private static final double ONE_DEGREE_MI = 69.09;
private static final double ONE_DEGREE_KM = 111.20; private static final double ONE_DEGREE_KM = 111.20;
protected void getGIS() { protected void getGIS() {
@ -147,21 +147,19 @@ public class AlarmAlertFunctions {
string.append("AOR"); string.append("AOR");
} }
if (!"".equals(prod.getAorDistance())) { if (!"".equals(prod.getAorDistance())) {
/* /*
* DR15555 - check the text content, * DR15555 - check the text content, if it is not a valid number set
* if it is not a valid number set the * the text to default 3000 mi
* text to default 3000 mi */
*/ Scanner scn = new Scanner(prod.getAorDistance());
Scanner scn = new Scanner(prod.getAorDistance()); while (scn.hasNext()) {
while (scn.hasNext()){ if (!scn.hasNextInt()) {
if (!scn.hasNextInt()){ prod.setAorDistance(DEFAULT_DISTANCE);
prod.setAorDistance(DEFAULT_DISTANCE); break;
break; } else {
} scn.next();
else { }
scn.next(); }
}
}
string.append("AOR+" + prod.getAorDistance() + prod.getAorLabel()); string.append("AOR+" + prod.getAorDistance() + prod.getAorLabel());
} else if (!"".equals(prod.getUgcList())) { } else if (!"".equals(prod.getUgcList())) {
string.append("UGC-" + prod.getUgcList()); string.append("UGC-" + prod.getUgcList());
@ -276,10 +274,10 @@ public class AlarmAlertFunctions {
if (productId != null) { if (productId != null) {
productId = productId.trim().toUpperCase(); productId = productId.trim().toUpperCase();
for (AlarmAlertProduct a : currentAlarms) { for (AlarmAlertProduct a : currentAlarms) {
ProductType pt = a.getProductType(); ProductType pt = a.getProductType();
/* /*
* Alarm_Alert * Alarm_Alert
*/ */
if (AA.equals(pt)) { if (AA.equals(pt)) {
String s = a.getProductId(); String s = a.getProductId();
if (s != null) { if (s != null) {
@ -292,334 +290,339 @@ public class AlarmAlertFunctions {
} }
} }
} }
/* /*
* DR1555 - Proximity_Alarm * DR1555 - Proximity_Alarm
*/ */
else if (PA.equals(pt)) {; else if (PA.equals(pt)) {
String s = a.getProductId(); String s = a.getProductId();
if (s != null) { if (s != null) {
s = s.trim().toUpperCase(); s = s.trim().toUpperCase();
if (s.equals(productId)) { if (s.equals(productId)) {
List<StdTextProduct> productList = getProduct(a List<StdTextProduct> productList = getProduct(a
.getProductId()); .getProductId());
if (productList.size() > 0) { if (productList.size() > 0) {
StdTextProduct stp = productList.get(0); StdTextProduct stp = productList.get(0);
if (stp != null) { if (stp != null) {
Geometry messagePolygon = getMessagePolygon(stp); Geometry messagePolygon = getMessagePolygon(stp);
if (a.isAor()) { if (a.isAor()) {
/* /*
* Check if polygon in the message * Check if polygon in the message is
* is within the AOR * within the AOR
*/ */
if (matchAOR(messagePolygon)) { if (messagePolygon != null
prods.add(a); && matchAOR(messagePolygon)) {
} prods.add(a);
} else if (!"".equals(a.getAorDistance())) { }
/* } else if (!"".equals(a.getAorDistance())) {
* Check if polygon in the message /*
* is within the AOR+distance * Check if polygon in the message is
*/ * within the AOR+distance
if (matchAORExtention(a.getAorDistance(), */
a.getAorLabel(), messagePolygon)) { if (messagePolygon != null
prods.add(a); && matchAORExtention(
} a.getAorDistance(),
} else if (!"".equals(a.getUgcList())) { a.getAorLabel(),
/* messagePolygon)) {
* Check if UGCs in the message prods.add(a);
* match the UGCs in the alarm }
*/ } else if (!"".equals(a.getUgcList())) {
String messageUGCs = getMessageUGCs(stp /*
.getProduct()); * Check if UGCs in the message match
String alarmUGCs = a.getUgcList(); * the UGCs in the alarm
if (matchUGCList(alarmUGCs, messageUGCs)) { */
prods.add(a); String messageUGCs = getMessageUGCs(stp
} .getProduct());
} String alarmUGCs = a.getUgcList();
} if (matchUGCList(alarmUGCs, messageUGCs)) {
} prods.add(a);
}
}
}
}
} }
} }
} }
} }
} }
return prods; return prods;
} }
/** /**
* Return a String containing UGCs specified in the message * Return a String containing UGCs specified in the message
* *
* @param productText * @param productText
* @return * @return
*/ */
private static String getMessageUGCs(String productText) { private static String getMessageUGCs(String productText) {
String ugcLine = ""; String ugcLine = "";
for (String line : productText.replaceAll("\r", "").trim().split("\n")) { for (String line : productText.replaceAll("\r", "").trim().split("\n")) {
Matcher m = UGC.matcher(line); Matcher m = UGC.matcher(line);
if (m.find()) { if (m.find()) {
ugcLine += line; ugcLine += line;
continue; continue;
} else if (ugcLine.length() > 0) { } else if (ugcLine.length() > 0) {
break; break;
} }
} }
return ugcLine; return ugcLine;
} }
/** /**
* Returns true if the polygon intersects the CWA * Returns true if the polygon intersects the CWA
* *
* @param polygon * @param polygon
* @return * @return
*/ */
private static boolean matchAOR(Geometry polygon) { private static boolean matchAOR(Geometry polygon) {
Geometry cwa = null; Geometry cwa = null;
String site = LocalizationManager.getInstance().getCurrentSite(); String site = LocalizationManager.getInstance().getCurrentSite();
try { try {
cwa = readCountyWarningArea(site); cwa = readCountyWarningArea(site);
} catch (SpatialException e) { } catch (SpatialException e) {
e.printStackTrace(); e.printStackTrace();
} }
if (cwa!=null) { if (cwa != null) {
if (polygon.intersects(cwa)) { if (polygon.intersects(cwa)) {
return true; return true;
} }
} }
return false;
}
/**
* Returns true if a UGC specified in the alarmUGCs is present in the
* messageUGCs
*
* @param alarmUGCs
* @param messageUGCs
* @return
*/
private static boolean matchUGCList(String alarmUGCs, String messageUGCs) {
List<String> alarmUGCList = getUGCs(alarmUGCs);
for ( String alarmUGC: alarmUGCList) {
if (messageUGCs.contains(alarmUGC) ) {
return true;
}
}
return false; return false;
} }
/** /**
* Return a List of strings of UGCs * Returns true if a UGC specified in the alarmUGCs is present in the
* * messageUGCs
* @param ugcString *
* @return * @param alarmUGCs
*/ * @param messageUGCs
private static List<String> getUGCs(String ugcString) { * @return
String[] ugcList = ugcString.split(HYPHEN); */
// Process the list of UGC lines into a list of UGCs in full form private static boolean matchUGCList(String alarmUGCs, String messageUGCs) {
// matching edit area names List<String> alarmUGCList = getUGCs(alarmUGCs);
List<String> finalUGCList = new ArrayList<String>(ugcList.length); for (String alarmUGC : alarmUGCList) {
String state = null; if (messageUGCs.contains(alarmUGC)) {
for (String ugc : ugcList) { return true;
Matcher newGroup = UGC_NEW_PATTERN.matcher(ugc); }
if (newGroup.matches()) { }
state = newGroup.group(2); return false;
finalUGCList.add(newGroup.group(1)); }
} else {
Matcher followGroup = UGC_FOLLOW_PATTERN.matcher(ugc);
if (followGroup.matches()) {
finalUGCList.add(state + followGroup.group(1));
}
}
}
return finalUGCList;
}
/**
* Return Geometry representing the site's CWA
*
* @param site
* @return
* @throws SpatialException
*/
private static Geometry readCountyWarningArea(String site)
throws SpatialException {
Map<String, RequestConstraint> map = new HashMap<String, RequestConstraint>();
map.put("cwa", new RequestConstraint(site));
SpatialQueryResult[] result = SpatialQueryFactory.create().query("cwa",
null, null, map, null);
if (result == null || result.length == 0) {
return null;
}
return result[0].geometry;
}
/** /**
* Returns true if the polygon intersects the CWA+distance * Return a List of strings of UGCs
* *
* @param distanceStr * @param ugcString
* @param distanceUnits * @return
* @param polygon */
* @return private static List<String> getUGCs(String ugcString) {
*/ String[] ugcList = ugcString.split(HYPHEN);
private static boolean matchAORExtention(String distanceStr, // Process the list of UGC lines into a list of UGCs in full form
String distanceUnits, Geometry polygon) { // matching edit area names
Geometry cwa = null; List<String> finalUGCList = new ArrayList<String>(ugcList.length);
String site = LocalizationManager.getInstance().getCurrentSite(); String state = null;
try { for (String ugc : ugcList) {
cwa = readCountyWarningArea(site); Matcher newGroup = UGC_NEW_PATTERN.matcher(ugc);
} catch (SpatialException e) { if (newGroup.matches()) {
// TODO Auto-generated catch block state = newGroup.group(2);
e.printStackTrace(); finalUGCList.add(newGroup.group(1));
} } else {
Geometry CWAConvex = cwa.convexHull(); Matcher followGroup = UGC_FOLLOW_PATTERN.matcher(ugc);
if (followGroup.matches()) {
finalUGCList.add(state + followGroup.group(1));
}
}
}
return finalUGCList;
}
double d0 = 0.0d; /**
if ("mi".equalsIgnoreCase(distanceUnits)) { * Return Geometry representing the site's CWA
d0 = ONE_DEGREE_MI; *
} else { * @param site
d0 = ONE_DEGREE_KM; * @return
} * @throws SpatialException
Double distance = Double.parseDouble(distanceStr); */
double centerLat = Math.toRadians(CWAConvex.getCentroid().getY()); private static Geometry readCountyWarningArea(String site)
Double deltaX = distance / (Math.cos(centerLat) * d0); throws SpatialException {
Double deltaY = distance / d0; Map<String, RequestConstraint> map = new HashMap<String, RequestConstraint>();
Geometry expandedCWA = expandCWABy(CWAConvex, deltaX, deltaY); map.put("cwa", new RequestConstraint(site));
SpatialQueryResult[] result = SpatialQueryFactory.create().query("cwa",
null, null, map, null);
if (result == null || result.length == 0) {
return null;
}
return result[0].geometry;
}
if (expandedCWA != null) { /**
if (polygon.intersects(expandedCWA)) { * Returns true if the polygon intersects the CWA+distance
return true; *
} * @param distanceStr
} * @param distanceUnits
return false; * @param polygon
} * @return
*/
private static boolean matchAORExtention(String distanceStr,
String distanceUnits, Geometry polygon) {
Geometry cwa = null;
String site = LocalizationManager.getInstance().getCurrentSite();
try {
cwa = readCountyWarningArea(site);
} catch (SpatialException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Geometry CWAConvex = cwa.convexHull();
/** double d0 = 0.0d;
* Return expanded by deltaX-deltaY geometry if ("mi".equalsIgnoreCase(distanceUnits)) {
* d0 = ONE_DEGREE_MI;
* @param CWAConvex } else {
* @param deltaX d0 = ONE_DEGREE_KM;
* @param deltaY }
* @return Double distance = Double.parseDouble(distanceStr);
*/ double centerLat = Math.toRadians(CWAConvex.getCentroid().getY());
private static Geometry expandCWABy(Geometry CWAConvex, Double deltaX, Double deltaX = distance / (Math.cos(centerLat) * d0);
Double deltaY) { Double deltaY = distance / d0;
Coordinate[] coords = CWAConvex.getCoordinates(); Geometry expandedCWA = expandCWABy(CWAConvex, deltaX, deltaY);
Coordinate[] coordsExpanded = new Coordinate[coords.length];
Double centerLat = CWAConvex.getCentroid().getY();
Double centerLon = CWAConvex.getCentroid().getX();
for (int i = 0; i < coords.length; i++) {
double latE = coords[i].y;
double lonE = coords[i].x;
if (coords[i].x < centerLon) {
lonE = coords[i].x - deltaX;
;
} else if (coords[i].x > centerLon) {
lonE = coords[i].x + deltaX;
} else if (coords[i].x == centerLon) {
lonE = coords[i].x;
}
if (coords[i].y < centerLat) {
latE = coords[i].y - deltaY;
} else if (coords[i].y > centerLat) {
latE = coords[i].y + deltaY;
} else if (coords[i].y == centerLat) {
latE = coords[i].y;
}
coordsExpanded[i] = new Coordinate(lonE, latE);
}
GeometryFactory gf = new GeometryFactory();
return gf.createLinearRing(coordsExpanded).convexHull();
}
/** if (expandedCWA != null) {
* Return the polygon contained in message if (polygon.intersects(expandedCWA)) {
* return true;
* @param stp }
* @return }
*/ return false;
private static Geometry getMessagePolygon(StdTextProduct stp) { }
String body = stp.getProduct();
if (body.contains("LAT...LON")) {
Coordinate[] coords = getLatLonCoords(body);
GeometryFactory gf = new GeometryFactory();
return gf.createLinearRing(coords);
}
return null;
}
/** /**
* Return an array of Coordinate[] contained in the message * Return expanded by deltaX-deltaY geometry
* *
* @param body * @param CWAConvex
* @return * @param deltaX
*/ * @param deltaY
private static Coordinate[] getLatLonCoords(String body) { * @return
String latLon = ""; */
boolean insideLatLon = false; private static Geometry expandCWABy(Geometry CWAConvex, Double deltaX,
ArrayList<Coordinate> coordinates = new ArrayList<Coordinate>(); Double deltaY) {
Pattern latLonPtrn = Pattern Coordinate[] coords = CWAConvex.getCoordinates();
.compile("LAT...LON+(\\s\\d{3,4}\\s\\d{3,5}){1,}"); Coordinate[] coordsExpanded = new Coordinate[coords.length];
Pattern subLatLonPtrn = Pattern.compile("\\s(\\d{3,4})\\s(\\d{3,5})"); Double centerLat = CWAConvex.getCentroid().getY();
String[] separatedLines = body.split("\n"); Double centerLon = CWAConvex.getCentroid().getX();
for (String line : separatedLines) { for (int i = 0; i < coords.length; i++) {
Matcher m = latLonPtrn.matcher(line); double latE = coords[i].y;
if (m.find()) { double lonE = coords[i].x;
latLon = line; if (coords[i].x < centerLon) {
insideLatLon = true; lonE = coords[i].x - deltaX;
continue; ;
} } else if (coords[i].x > centerLon) {
if (insideLatLon) { lonE = coords[i].x + deltaX;
m = subLatLonPtrn.matcher(line); } else if (coords[i].x == centerLon) {
if (!line.startsWith("TIME...") && m.find()) { lonE = coords[i].x;
latLon += " " + line.trim(); }
continue; if (coords[i].y < centerLat) {
} else { latE = coords[i].y - deltaY;
insideLatLon = false; } else if (coords[i].y > centerLat) {
} latE = coords[i].y + deltaY;
} } else if (coords[i].y == centerLat) {
} latE = coords[i].y;
coordinates = processLatlons(latLon); }
Coordinate[] coords = new Coordinate[coordinates.size()]; coordsExpanded[i] = new Coordinate(lonE, latE);
coords = coordinates.toArray(coords); }
return coords; GeometryFactory gf = new GeometryFactory();
} return gf.createLinearRing(coordsExpanded).convexHull();
}
/** /**
* Process the extracted from the message latlon coordinates * Return the polygon contained in message
* @param latLon *
* @return * @param stp
*/ * @return
private static ArrayList<Coordinate> processLatlons(String latLon) { */
ArrayList<Coordinate> coordinates = new ArrayList<Coordinate>(); private static Geometry getMessagePolygon(StdTextProduct stp) {
String currentToken = null; String body = stp.getProduct();
String latlon = "LAT...LON"; if (body.contains("LAT...LON")) {
String latitude = null; Coordinate[] coords = getLatLonCoords(body);
String longitude = null; GeometryFactory gf = new GeometryFactory();
boolean pair = false; return gf.createLinearRing(coords);
Double dlat, dlong; }
StringTokenizer latlonTokens = new StringTokenizer(latLon); return null;
while (latlonTokens.hasMoreTokens()) { }
currentToken = latlonTokens.nextToken();
if (!currentToken.equals(latlon)) {
if (pair) {
longitude = currentToken;
pair = false; /**
* Return an array of Coordinate[] contained in the message
*
* @param body
* @return
*/
private static Coordinate[] getLatLonCoords(String body) {
String latLon = "";
boolean insideLatLon = false;
ArrayList<Coordinate> coordinates = new ArrayList<Coordinate>();
Pattern latLonPtrn = Pattern
.compile("LAT...LON+(\\s\\d{3,4}\\s\\d{3,5}){1,}");
Pattern subLatLonPtrn = Pattern.compile("\\s(\\d{3,4})\\s(\\d{3,5})");
String[] separatedLines = body.split("\n");
for (String line : separatedLines) {
Matcher m = latLonPtrn.matcher(line);
if (m.find()) {
latLon = line;
insideLatLon = true;
continue;
}
if (insideLatLon) {
m = subLatLonPtrn.matcher(line);
if (!line.startsWith("TIME...") && m.find()) {
latLon += " " + line.trim();
continue;
} else {
insideLatLon = false;
}
}
}
coordinates = processLatlons(latLon);
Coordinate[] coords = new Coordinate[coordinates.size()];
coords = coordinates.toArray(coords);
return coords;
}
dlat = (double) (Integer.parseInt(latitude) / 100.0); /**
dlong = (double) ((Integer.parseInt(longitude) / 100.0) * (-1.0)); * Process the extracted from the message latlon coordinates
coordinates.add(new Coordinate(dlong, dlat)); *
} else { * @param latLon
latitude = currentToken; * @return
pair = true; */
} private static ArrayList<Coordinate> processLatlons(String latLon) {
} ArrayList<Coordinate> coordinates = new ArrayList<Coordinate>();
} String currentToken = null;
Double dlong0 = coordinates.get(0).x; String latlon = "LAT...LON";
Double dlat0 = coordinates.get(0).y; String latitude = null;
coordinates.add(new Coordinate(dlong0, dlat0)); String longitude = null;
return coordinates; boolean pair = false;
} Double dlat, dlong;
StringTokenizer latlonTokens = new StringTokenizer(latLon);
while (latlonTokens.hasMoreTokens()) {
currentToken = latlonTokens.nextToken();
if (!currentToken.equals(latlon)) {
if (pair) {
longitude = currentToken;
/** pair = false;
dlat = (double) (Integer.parseInt(latitude) / 100.0);
dlong = (double) ((Integer.parseInt(longitude) / 100.0) * (-1.0));
coordinates.add(new Coordinate(dlong, dlat));
} else {
latitude = currentToken;
pair = true;
}
}
}
Double dlong0 = coordinates.get(0).x;
Double dlat0 = coordinates.get(0).y;
coordinates.add(new Coordinate(dlong0, dlat0));
return coordinates;
}
/**
* initialize the localization for user with the save/load functions * initialize the localization for user with the save/load functions
* *
* @return the initialized localization * @return the initialized localization