Issue #1126 Refactored locking and wrapping
Change-Id: I8053e8a8562eba9224a032c482f1cbca5af01df0 Former-commit-id:e133dfe810
[formerlyfb849c43fc
] [formerlye133dfe810
[formerlyfb849c43fc
] [formerly95a5acdd3b
[formerly 064271bce1ba6c69eb4f218cb5a408163f1d05b2]]] Former-commit-id:95a5acdd3b
Former-commit-id:0e905ace7e
[formerly284cfb90f0
] Former-commit-id:48794c841f
This commit is contained in:
parent
74cb9e8817
commit
6d4a0d23e0
13 changed files with 1478 additions and 990 deletions
|
@ -93,11 +93,12 @@ import com.raytheon.viz.warngen.gui.BackupData;
|
||||||
import com.raytheon.viz.warngen.gui.FollowupData;
|
import com.raytheon.viz.warngen.gui.FollowupData;
|
||||||
import com.raytheon.viz.warngen.gui.WarngenLayer;
|
import com.raytheon.viz.warngen.gui.WarngenLayer;
|
||||||
import com.raytheon.viz.warngen.gui.WarngenUIState;
|
import com.raytheon.viz.warngen.gui.WarngenUIState;
|
||||||
|
import com.raytheon.viz.warngen.text.WarningTextHandler;
|
||||||
|
import com.raytheon.viz.warngen.text.WarningTextHandlerFactory;
|
||||||
import com.raytheon.viz.warngen.util.CurrentWarnings;
|
import com.raytheon.viz.warngen.util.CurrentWarnings;
|
||||||
import com.raytheon.viz.warngen.util.FipsUtil;
|
import com.raytheon.viz.warngen.util.FipsUtil;
|
||||||
import com.raytheon.viz.warngen.util.FollowUpUtil;
|
import com.raytheon.viz.warngen.util.FollowUpUtil;
|
||||||
import com.raytheon.viz.warngen.util.WarnGenMathTool;
|
import com.raytheon.viz.warngen.util.WarnGenMathTool;
|
||||||
import com.raytheon.viz.warngen.util.WarningTextHandler;
|
|
||||||
import com.raytheon.viz.warngen.util.WatchUtil;
|
import com.raytheon.viz.warngen.util.WatchUtil;
|
||||||
import com.raytheon.viz.warngen.util.WeatherAdvisoryWatch;
|
import com.raytheon.viz.warngen.util.WeatherAdvisoryWatch;
|
||||||
import com.raytheon.viz.warnings.DateUtil;
|
import com.raytheon.viz.warnings.DateUtil;
|
||||||
|
@ -126,7 +127,8 @@ import com.vividsolutions.jts.io.WKTReader;
|
||||||
* from appearing in 2nd and 3rd bullets when not necessary.
|
* from appearing in 2nd and 3rd bullets when not necessary.
|
||||||
* Aug 13, 2012 14493 Qinglu Lin Handled MND time, event time, and TML time specially for COR to NEW.
|
* Aug 13, 2012 14493 Qinglu Lin Handled MND time, event time, and TML time specially for COR to NEW.
|
||||||
* Aug 29, 2011 15351 jsanchez Set the timezone for TML time.
|
* Aug 29, 2011 15351 jsanchez Set the timezone for TML time.
|
||||||
* Sep 10, 2012 15295 snaples Added property setting for runtime log to createScript.
|
* Sep 10, 2012 15295 snaples Added property setting for runtime log to createScript.
|
||||||
|
* Sep 18, 2012 15332 jsanchez Used a new warning text handler.
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author njensen
|
* @author njensen
|
||||||
|
@ -760,16 +762,19 @@ public class TemplateRunner {
|
||||||
System.out.println("velocity time: "
|
System.out.println("velocity time: "
|
||||||
+ (System.currentTimeMillis() - tz0));
|
+ (System.currentTimeMillis() - tz0));
|
||||||
|
|
||||||
return WarningTextHandler.handle(script.toString().toUpperCase(),
|
String text = script.toString();
|
||||||
areas, cancelareas, selectedAction,
|
WarningTextHandler handler = WarningTextHandlerFactory.getHandler(
|
||||||
WarningAction.valueOf((String) context.get("action")),
|
selectedAction, text, config.getAutoLockText());
|
||||||
config.getAutoLockText());
|
String handledText = handler.handle(text, areas, cancelareas);
|
||||||
|
|
||||||
|
return handledText;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static VelocityEngine ENGINE = new VelocityEngine();
|
private static VelocityEngine ENGINE = new VelocityEngine();
|
||||||
|
|
||||||
private static synchronized String createScript(String vmFile,
|
private static synchronized String createScript(String vmFile,
|
||||||
VelocityContext context, String site, String logDir) throws EdexException {
|
VelocityContext context, String site, String logDir)
|
||||||
|
throws EdexException {
|
||||||
StringWriter sw = new StringWriter();
|
StringWriter sw = new StringWriter();
|
||||||
try {
|
try {
|
||||||
Properties p = new Properties();
|
Properties p = new Properties();
|
||||||
|
@ -780,8 +785,7 @@ public class TemplateRunner {
|
||||||
p.setProperty(
|
p.setProperty(
|
||||||
"velocimacro.permissions.allow.inline.to.replace.global",
|
"velocimacro.permissions.allow.inline.to.replace.global",
|
||||||
"true");
|
"true");
|
||||||
p.setProperty("runtime.log",
|
p.setProperty("runtime.log", FileUtil.join(logDir, "velocity.log"));
|
||||||
FileUtil.join(logDir, "velocity.log"));
|
|
||||||
ENGINE.init(p);
|
ENGINE.init(p);
|
||||||
context.put("scriptLibrary", "VM_global_library.vm");
|
context.put("scriptLibrary", "VM_global_library.vm");
|
||||||
Template template = ENGINE.getTemplate(vmFile,
|
Template template = ENGINE.getTemplate(vmFile,
|
||||||
|
|
|
@ -0,0 +1,357 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.viz.warngen.text;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
|
import com.raytheon.viz.texteditor.util.VtecObject;
|
||||||
|
import com.raytheon.viz.texteditor.util.VtecUtil;
|
||||||
|
import com.raytheon.viz.warngen.gis.AffectedAreas;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract class that locks certain text patterns in the warning text.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Sep 24, 2012 15322 jsanchez Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author jsanchez
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
abstract public class AbstractLockingBehavior implements ICommonPatterns {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sorts in reverse order the areas based on the length of the name.
|
||||||
|
*
|
||||||
|
* @author jsanchez
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private class AreaLockingComparator implements Comparator<AffectedAreas> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(AffectedAreas o1, AffectedAreas o2) {
|
||||||
|
Integer i1 = new Integer(o1.getName().length());
|
||||||
|
Integer i2 = new Integer(o2.getName().length());
|
||||||
|
return i2.compareTo(i1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<AffectedAreas> affectedAreas;
|
||||||
|
|
||||||
|
protected String text;
|
||||||
|
|
||||||
|
protected static final String REPLACEMENT = LOCK_START + "$0" + LOCK_END;
|
||||||
|
|
||||||
|
protected String warningType = "(FLOOD ADVISORY)|(FLOOD WARNING)|(FLOOD STATEMENT)"
|
||||||
|
+ "|(SEVERE WEATHER STATEMENT)|(EXTREME WIND WARNING)|(FIRE WARNING)"
|
||||||
|
+ "|(FLASH FLOOD WARNING)|(FLASH FLOOD STATEMENT)|(SEVERE THUNDERSTORM WARNING)"
|
||||||
|
+ "|(TORNADO WARNING)|(MARINE WEATHER STATEMENT)|(SHORT TERM FORECAST)"
|
||||||
|
+ "|(SPECIAL WEATHER STATEMENT)|(SPECIAL MARINE WARNING)";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks the particular strings in the texts based on common patterns and
|
||||||
|
* the affected areas.
|
||||||
|
*
|
||||||
|
* @param text
|
||||||
|
* @param affectedAreas
|
||||||
|
* @param canceledAreas
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String lock(String text, AffectedAreas[] affectedAreas,
|
||||||
|
AffectedAreas[] canceledAreas) {
|
||||||
|
this.text = text;
|
||||||
|
intialize(affectedAreas, canceledAreas);
|
||||||
|
ugc();
|
||||||
|
htec();
|
||||||
|
vtec();
|
||||||
|
areaNames();
|
||||||
|
mnd();
|
||||||
|
date();
|
||||||
|
body();
|
||||||
|
callToActions();
|
||||||
|
latLon();
|
||||||
|
tml();
|
||||||
|
testMessages();
|
||||||
|
clean();
|
||||||
|
|
||||||
|
return this.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls the sub classes implementation of the body method.
|
||||||
|
*/
|
||||||
|
abstract protected void body();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the affect areas into the appropriate lists.
|
||||||
|
*
|
||||||
|
* @param affectedAreas
|
||||||
|
* @param canceledAreas
|
||||||
|
*/
|
||||||
|
private void intialize(AffectedAreas[] affectedAreas,
|
||||||
|
AffectedAreas[] canceledAreas) {
|
||||||
|
AreaLockingComparator comparator = new AreaLockingComparator();
|
||||||
|
|
||||||
|
if (affectedAreas != null) {
|
||||||
|
this.affectedAreas = new ArrayList<AffectedAreas>(
|
||||||
|
Arrays.asList(affectedAreas));
|
||||||
|
} else {
|
||||||
|
this.affectedAreas = new ArrayList<AffectedAreas>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (canceledAreas != null) {
|
||||||
|
this.affectedAreas.addAll(Arrays.asList(canceledAreas));
|
||||||
|
}
|
||||||
|
Collections.sort(this.affectedAreas, comparator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks the UGC line or FIPS line.
|
||||||
|
*/
|
||||||
|
private void ugc() {
|
||||||
|
Pattern ugcPtrn = Pattern.compile(ugc + newline, Pattern.MULTILINE);
|
||||||
|
find(ugcPtrn.matcher(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks the HTEC line.
|
||||||
|
*/
|
||||||
|
private void htec() {
|
||||||
|
// LOCK_END can be added at the start of the line if a previous line has
|
||||||
|
// been locked.
|
||||||
|
String htec = "^(("
|
||||||
|
+ LOCK_END
|
||||||
|
+ "){0,1}/[A-Za-z0-9]{5}.[0-3NU].\\w{2}.\\d{6}T\\d{4}Z.\\d{6}T\\d{4}Z.\\d{6}T\\d{4}Z.\\w{2}/"
|
||||||
|
+ newline + ")";
|
||||||
|
Pattern htecPtrn = Pattern.compile(htec, Pattern.MULTILINE);
|
||||||
|
find(htecPtrn.matcher(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks the VTEC line.
|
||||||
|
*/
|
||||||
|
private void vtec() {
|
||||||
|
// LOCK_END can be added at the start of the line if a previous line has
|
||||||
|
// been locked.
|
||||||
|
String vtec = "^(("
|
||||||
|
+ LOCK_END
|
||||||
|
+ "){0,1}/[OTEX]\\.([A-Z]{3})\\.[A-Za-z0-9]{4}\\.[A-Z]{2}\\.[WAYSFON]\\.\\d{4}\\.\\d{6}T\\d{4}Z-\\d{6}T\\d{4}Z/"
|
||||||
|
+ newline + ")";
|
||||||
|
Pattern vtecPtrn = Pattern.compile(vtec, Pattern.MULTILINE);
|
||||||
|
find(vtecPtrn.matcher(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks the list of area names.
|
||||||
|
*/
|
||||||
|
private void areaNames() {
|
||||||
|
find(listOfAreaNamePtrn.matcher(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to replace the found patterns.
|
||||||
|
*
|
||||||
|
* @param m
|
||||||
|
*/
|
||||||
|
protected void find(Matcher m) {
|
||||||
|
if (m.find()) {
|
||||||
|
String group = m.group();
|
||||||
|
// If line already starts with a LOCK_END, the LOCK_END is removed
|
||||||
|
// and the line just adds to the LOCK_END at the end.
|
||||||
|
if (group.startsWith(LOCK_END)) {
|
||||||
|
this.text = text.replace(group,
|
||||||
|
group.substring(LOCK_END.length()) + LOCK_END);
|
||||||
|
} else {
|
||||||
|
this.text = m.replaceAll(LOCK_START + "$0" + LOCK_END);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method locks the entire MND Header block.
|
||||||
|
*/
|
||||||
|
private void mnd() {
|
||||||
|
int start = -1;
|
||||||
|
int end = -1;
|
||||||
|
|
||||||
|
StringBuffer mnd = new StringBuffer(
|
||||||
|
"(BULLETIN - IMMEDIATE BROADCAST REQUESTED)|(BULLETIN - EAS ACTIVATION REQUESTED)|"
|
||||||
|
+ warningType);
|
||||||
|
|
||||||
|
Pattern startMND = Pattern.compile(mnd.toString());
|
||||||
|
Matcher m = startMND.matcher(text);
|
||||||
|
if (m.find()) {
|
||||||
|
start = m.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
m = datePtrn.matcher(text);
|
||||||
|
if (m.find()) {
|
||||||
|
end = m.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start != -1 && end != -1 && start < end) {
|
||||||
|
String substring = text.substring(start, end);
|
||||||
|
// There should be only one instance of an MND Header block
|
||||||
|
this.text = text.replace(substring, LOCK_START + substring
|
||||||
|
+ LOCK_END);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks the date.
|
||||||
|
*/
|
||||||
|
private void date() {
|
||||||
|
find(datePtrn.matcher(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks the TIME...MOT...LINE (Can be multiple lines).
|
||||||
|
*/
|
||||||
|
private void tml() {
|
||||||
|
// LOCK_END can be added at the start of the line if a previous line has
|
||||||
|
// been locked.
|
||||||
|
String tml = "^(("
|
||||||
|
+ LOCK_END
|
||||||
|
+ "){0,1}(TIME\\.\\.\\.MOT\\.\\.\\.LOC \\d{3,4}Z \\d{3}DEG \\d{1,3}KT(( \\d{3,4} \\d{3,5}){1,})(\\s*\\d{3,5} )*)\\s*"
|
||||||
|
+ newline + ")";
|
||||||
|
Pattern tmlPtrn = Pattern.compile(tml, Pattern.MULTILINE);
|
||||||
|
find(tmlPtrn.matcher(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks the coordinates of the polygon.
|
||||||
|
*/
|
||||||
|
private void latLon() {
|
||||||
|
// LOCK_END should not be found at the beginning of the LAT...LON since
|
||||||
|
// the previous line should be blank.
|
||||||
|
String latLon = "^((LAT\\.\\.\\.LON( \\d{3,4} \\d{3,5})+)" + newline
|
||||||
|
+ ")(((\\s{5}( \\d{3,4} \\d{3,5})+)" + newline + ")+)?";
|
||||||
|
Pattern latLonPtrn = Pattern.compile(latLon, Pattern.MULTILINE);
|
||||||
|
find(latLonPtrn.matcher(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks the Call To Action header and the segment tags.
|
||||||
|
*/
|
||||||
|
private void callToActions() {
|
||||||
|
// LOCK_END should not be found at the beginning since the previous line
|
||||||
|
// should be blank.
|
||||||
|
String precautionaryPtrn = "^(PRECAUTIONARY/PREPAREDNESS ACTIONS\\.\\.\\."
|
||||||
|
+ newline + ")";
|
||||||
|
String ctaEndPtrn = "^(&&" + newline + ")";
|
||||||
|
String segmentPtrn = "^(\\$\\$" + newline + ")";
|
||||||
|
Pattern cta = Pattern.compile("(" + precautionaryPtrn + ")" + "|("
|
||||||
|
+ ctaEndPtrn + ")" + "|(" + segmentPtrn + ")",
|
||||||
|
Pattern.MULTILINE);
|
||||||
|
find(cta.matcher(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks the test messages.
|
||||||
|
*/
|
||||||
|
private void testMessages() {
|
||||||
|
String test1 = "THIS IS A TEST MESSAGE\\. DO NOT TAKE ACTION BASED ON THIS MESSAGE\\."
|
||||||
|
+ newline;
|
||||||
|
String test2 = "THIS IS A TEST MESSAGE\\.";
|
||||||
|
String test3 = "\\.\\.\\.THIS MESSAGE IS FOR TEST PURPOSES ONLY\\.\\.\\."
|
||||||
|
+ newline;
|
||||||
|
Pattern testPtrn = Pattern.compile("(" + test1 + ")|" + "(" + test2
|
||||||
|
+ ")|" + "(" + test3 + ")");
|
||||||
|
find(testPtrn.matcher(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clean() {
|
||||||
|
// where a lock close and lock open are only separated by whitespace
|
||||||
|
// remove the close and open to join the two locked areas
|
||||||
|
text = text.replaceAll("</L>([\\s\\n\\r]*)<L>", "$1");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this is a Marine Weather Statement and not a Standalone
|
||||||
|
* MWS. Standalone MWS do not have VTECs.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected boolean isMarineProduct() {
|
||||||
|
VtecObject vtecObj = VtecUtil.parseMessage(text);
|
||||||
|
boolean marineProduct = vtecObj != null
|
||||||
|
&& vtecObj.getPhenomena() != null
|
||||||
|
&& vtecObj.getPhenomena().equals("MA");
|
||||||
|
return marineProduct;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if the LOCK_START count matches the LOCK_END count.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean validate(String modified) {
|
||||||
|
int startCount = StringUtils.countMatches(modified, LOCK_START);
|
||||||
|
int endCount = StringUtils.countMatches(modified, LOCK_END);
|
||||||
|
|
||||||
|
return startCount == endCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if the name has been locked already by the template to avoid
|
||||||
|
* stacked lock tags.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected boolean hasBeenLocked(String line, String name) {
|
||||||
|
int index = line.indexOf(name);
|
||||||
|
if (index != -1) {
|
||||||
|
int startBefore = line.lastIndexOf(LOCK_START, index);
|
||||||
|
int endBefore = line.lastIndexOf(LOCK_END, index);
|
||||||
|
int startAfter = line.indexOf(LOCK_START, index);
|
||||||
|
int endAfter = line.indexOf(LOCK_END, index);
|
||||||
|
|
||||||
|
if (startBefore != -1 && endAfter != -1 && startBefore < endAfter) {
|
||||||
|
if (startAfter != -1 && startAfter < endAfter
|
||||||
|
&& startAfter > startBefore) {
|
||||||
|
return false;
|
||||||
|
} else if (endBefore != -1 && endBefore > startBefore
|
||||||
|
&& endBefore < endAfter) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.viz.warngen.text;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifies the warning text by adding 'CORRECTED' in the MND header.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Sep 24, 2012 15322 jsanchez Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author jsanchez
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class CorModifyTextBehavior implements IModifyTextBehavior {
|
||||||
|
|
||||||
|
private static final String[] types = new String[] { "WARNING", "WATCH",
|
||||||
|
"STATEMENT", "ADVISORY" };
|
||||||
|
|
||||||
|
private static final String correctedText = "...CORRECTED";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String modify(String text) {
|
||||||
|
int index = text.indexOf("NATIONAL WEATHER SERVICE");
|
||||||
|
|
||||||
|
int typeIdx = -1, i = 0;
|
||||||
|
if (index > 0) {
|
||||||
|
for (i = 0; i < types.length; i++) {
|
||||||
|
if (text.lastIndexOf(types[i], index) != -1) {
|
||||||
|
typeIdx = text.lastIndexOf(types[i], index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index > 0 && typeIdx > 0 && !text.contains(correctedText)) {
|
||||||
|
text = text.substring(0, typeIdx + types[i].length())
|
||||||
|
+ correctedText
|
||||||
|
+ text.substring(typeIdx + types[i].length());
|
||||||
|
}
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,199 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.viz.warngen.text;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import com.raytheon.viz.warngen.gis.AffectedAreas;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks text patterns for follow up warnings.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Sep 24, 2012 15322 jsanchez Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author jsanchez
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class FollowUpLockingBehavior extends AbstractLockingBehavior {
|
||||||
|
/**
|
||||||
|
* Locks the appropriate text of the body of an initial warning.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void body() {
|
||||||
|
headlines();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks the cancel and the follow up headlines.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private void headlines() {
|
||||||
|
// LOCK_END should not be found at the beginning since the previous line
|
||||||
|
// should be blank.
|
||||||
|
Pattern headlinePtrn = Pattern
|
||||||
|
.compile(
|
||||||
|
"^\\.\\.\\.(A|THE) (.*) (WARNING|ADVISORY) .*(REMAINS|EXPIRE|CANCELLED).*(\\.\\.\\.)$",
|
||||||
|
Pattern.MULTILINE);
|
||||||
|
Matcher m = headlinePtrn.matcher(text);
|
||||||
|
|
||||||
|
while (m.find()) {
|
||||||
|
String originalHeadline = m.group();
|
||||||
|
String headline = headline(originalHeadline);
|
||||||
|
headline = remainsInEffect(headline);
|
||||||
|
headline = expired(headline);
|
||||||
|
headline = canceled(headline);
|
||||||
|
this.text = text.replace(originalHeadline, headline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks the expired text.
|
||||||
|
*/
|
||||||
|
private String expired(String followupHeadline) {
|
||||||
|
// Based on the templates, the expired text is for the affected areas
|
||||||
|
// not the canceled areas.
|
||||||
|
String expire = "(HAS BEEN ALLOWED TO EXPIRE)|(WILL BE ALLOWED TO EXPIRE)|(WILL EXPIRE)|(HAS EXPIRED)|EXPIRED";
|
||||||
|
String time = "AT \\d{3,4} (AM|PM) \\w{3,4}";
|
||||||
|
return followupHeadline.replaceAll(expire, REPLACEMENT).replaceAll(
|
||||||
|
time, REPLACEMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks remains in effect text.
|
||||||
|
*
|
||||||
|
* @param followupHeadline
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String remainsInEffect(String followupHeadline) {
|
||||||
|
return followupHeadline.replaceFirst(
|
||||||
|
"REMAINS IN EFFECT UNTIL \\d{3,4} (AM|PM) \\w{3,4}", LOCK_START
|
||||||
|
+ "$0" + LOCK_END);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks the canceled text.
|
||||||
|
*
|
||||||
|
* @param canceledHeadline
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String canceled(String canceledHeadline) {
|
||||||
|
return canceledHeadline.replaceAll("(IS|(HAS BEEN)) CANCELLED",
|
||||||
|
REPLACEMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to lock area names and notations in the headline.
|
||||||
|
*
|
||||||
|
* @param headline
|
||||||
|
* @param areas
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String headline(String headline) {
|
||||||
|
Set<String> notations = new HashSet<String>();
|
||||||
|
Set<String> names = new HashSet<String>();
|
||||||
|
|
||||||
|
for (AffectedAreas affectedArea : affectedAreas) {
|
||||||
|
if (affectedArea.getAreaNotation() != null
|
||||||
|
&& affectedArea.getAreaNotation().trim().length() != 0) {
|
||||||
|
notations.add(affectedArea.getAreaNotation().toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (affectedArea.getAreasNotation() != null
|
||||||
|
&& affectedArea.getAreasNotation().trim().length() != 0) {
|
||||||
|
notations.add(affectedArea.getAreasNotation().toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (affectedArea.getName() != null
|
||||||
|
&& affectedArea.getName().trim().length() != 0) {
|
||||||
|
names.add(affectedArea.getName().toUpperCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marine products follow different locking rules
|
||||||
|
if (!isMarineProduct()) {
|
||||||
|
headline = keywords(headline);
|
||||||
|
Iterator<String> iterator1 = notations.iterator();
|
||||||
|
while (iterator1.hasNext()) {
|
||||||
|
String notation = iterator1.next();
|
||||||
|
if (!hasBeenLocked(headline, notation)) {
|
||||||
|
headline = headline.replace(notation, LOCK_START + notation
|
||||||
|
+ LOCK_END);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<String> iterator2 = names.iterator();
|
||||||
|
while (iterator2.hasNext()) {
|
||||||
|
String name = iterator2.next();
|
||||||
|
if (!hasBeenLocked(headline, name)) {
|
||||||
|
headline = headline.replace(name, LOCK_START + name
|
||||||
|
+ LOCK_END);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// The full headline of a marine product should be locked.
|
||||||
|
headline = LOCK_START + headline + LOCK_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
return headline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common key words to be locked in a headline.
|
||||||
|
*
|
||||||
|
* @param headline
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String keywords(String headline) {
|
||||||
|
// Locking the start of a head line (...)
|
||||||
|
headline = headline.replaceFirst("^\\.\\.\\.", LOCK_START + "$0"
|
||||||
|
+ LOCK_END);
|
||||||
|
// Locking the end of a head line (...)
|
||||||
|
if (headline.endsWith("...")) {
|
||||||
|
headline = headline.substring(0, headline.length() - 3)
|
||||||
|
+ LOCK_START + "..." + LOCK_END;
|
||||||
|
}
|
||||||
|
// Locks warning type (i.e. SEVERE THUNDERSTORM)
|
||||||
|
headline = headline.replaceAll("(A|THE) (" + warningType + ")",
|
||||||
|
LOCK_START + "$0" + LOCK_END);
|
||||||
|
|
||||||
|
// Locks the 'FOR' in the headline
|
||||||
|
headline = headline.replaceFirst(" FOR ", " " + LOCK_START + "FOR"
|
||||||
|
+ LOCK_END + " ");
|
||||||
|
|
||||||
|
// Locks the 'AND' in the headline
|
||||||
|
headline = headline.replaceFirst(" AND ", " " + LOCK_START + "AND"
|
||||||
|
+ LOCK_END + " ");
|
||||||
|
|
||||||
|
return headline;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.viz.warngen.text;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common patterns.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Sep 24, 2012 15322 jsanchez Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author jsanchez
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public interface ICommonPatterns {
|
||||||
|
|
||||||
|
/** Start tag for locking */
|
||||||
|
public static final String LOCK_START = "<L>";
|
||||||
|
|
||||||
|
/** End tag for locking */
|
||||||
|
public static final String LOCK_END = "</L>";
|
||||||
|
|
||||||
|
public static final String newline = "\\n";
|
||||||
|
|
||||||
|
// LOCK_END should not be found at the beginning since the previous line
|
||||||
|
// should be blank.
|
||||||
|
public static final String ugc = "(^(\\w{2}[CZ]\\d{3}\\S*-\\d{6}-)$|((\\d{3}-)*\\d{6}-)$|((\\d{3}-)+))";
|
||||||
|
|
||||||
|
// LOCK_END can be added at the start of the line if a previous line has
|
||||||
|
// been locked.
|
||||||
|
public static Pattern listOfAreaNamePtrn = Pattern.compile("^((" + LOCK_END
|
||||||
|
+ "){0,1}(((\\w+\\s{1})+\\w{2}-)*((\\w+\\s{1})+\\w{2}-))" + newline
|
||||||
|
+ ")", Pattern.MULTILINE);
|
||||||
|
|
||||||
|
// LOCK_END should not be found at the beginning of a first bullet since the
|
||||||
|
// previous line should be blank.
|
||||||
|
public static final String firstBullet = "^(\\* (.*) (WARNING|ADVISORY)( FOR(.*)|\\.\\.\\.)"
|
||||||
|
+ newline + ")";
|
||||||
|
|
||||||
|
// LOCK_END can be added at the start of the line if a previous line has
|
||||||
|
// been locked.
|
||||||
|
public static Pattern datePtrn = Pattern
|
||||||
|
.compile(
|
||||||
|
"^(("
|
||||||
|
+ LOCK_END
|
||||||
|
+ "){0,1}\\d{3,4} (AM|PM) (\\w{3,4}) \\w{3} (\\w{3})\\s+(\\d{1,2}) (\\d{4})"
|
||||||
|
+ newline + ")", Pattern.MULTILINE);
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.viz.warngen.text;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifies the warning text based on a warning action.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Sep 24, 2012 15332 jsanchez Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author jsanchez
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public interface IModifyTextBehavior {
|
||||||
|
public String modify(String text);
|
||||||
|
}
|
|
@ -0,0 +1,219 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.viz.warngen.text;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.dataplugin.warning.util.FileUtil;
|
||||||
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
|
import com.raytheon.viz.warngen.gis.AffectedAreas;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks text patterns on initial or new warning.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Sep 24, 2012 15322 jsanchez Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author jsanchez
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class InitialLockingBehavior extends AbstractLockingBehavior {
|
||||||
|
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||||
|
.getHandler(InitialLockingBehavior.class);
|
||||||
|
|
||||||
|
private static Pattern immediateCausePtrn = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks the appropriate text of the body of an initial warning.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void body() {
|
||||||
|
header();
|
||||||
|
firstBullet();
|
||||||
|
secondBullet();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to determine the index of each bullet.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Integer[] bulletIndices() {
|
||||||
|
List<Integer> bulletIndices = new ArrayList<Integer>();
|
||||||
|
|
||||||
|
int index = text.indexOf("* ");
|
||||||
|
while (index >= 0) {
|
||||||
|
bulletIndices.add(index);
|
||||||
|
index = text.indexOf("* ", index + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bulletIndices.toArray(new Integer[bulletIndices.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks the header before the first bullet.
|
||||||
|
*/
|
||||||
|
private void header() {
|
||||||
|
// LOCK_END should not be found at the beginning since the previous line
|
||||||
|
// should be blank.
|
||||||
|
String h = "^((THE NATIONAL WEATHER SERVICE IN .{1,} HAS ISSUED A)"
|
||||||
|
+ newline + ")$";
|
||||||
|
Pattern header = Pattern.compile(h, Pattern.MULTILINE);
|
||||||
|
find(header.matcher(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks the affected area names in the first bullet, the immediate cause.
|
||||||
|
*
|
||||||
|
* @param start
|
||||||
|
* @param end
|
||||||
|
*/
|
||||||
|
private void firstBullet() {
|
||||||
|
Integer[] bulletIndices = bulletIndices();
|
||||||
|
|
||||||
|
// Short term forecasts don't follow normal bullets?
|
||||||
|
if (bulletIndices.length < 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int start = bulletIndices[0];
|
||||||
|
int end = bulletIndices[1];
|
||||||
|
|
||||||
|
if (immediateCausePtrn == null) {
|
||||||
|
immediateCausePtrn = getImmediateCausesPtrn();
|
||||||
|
}
|
||||||
|
|
||||||
|
String firstBulletText = text.substring(start, end);
|
||||||
|
|
||||||
|
// According to the original WarningTextHandler, marine zone names
|
||||||
|
// should not be locked. For some reason, this differs from followups as
|
||||||
|
// stated in DR 15110. Need verification from NWS. This is a variance?
|
||||||
|
if (!isMarineProduct()) {
|
||||||
|
Matcher m = null;
|
||||||
|
for (String line : firstBulletText.split("\\n")) {
|
||||||
|
|
||||||
|
if (immediateCausePtrn != null) {
|
||||||
|
// immediate cause
|
||||||
|
m = immediateCausePtrn.matcher(line);
|
||||||
|
if (m.find()) {
|
||||||
|
String i = line.replace(line, LOCK_START + line
|
||||||
|
+ LOCK_END);
|
||||||
|
firstBulletText = firstBulletText.replace(line, i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (AffectedAreas affectedArea : affectedAreas) {
|
||||||
|
String name = affectedArea.getName();
|
||||||
|
String areaNotation = affectedArea.getAreaNotation();
|
||||||
|
String parentRegion = affectedArea.getParentRegion();
|
||||||
|
if (name != null && name.trim().length() != 0
|
||||||
|
&& line.contains(name.toUpperCase())) {
|
||||||
|
name = name.toUpperCase();
|
||||||
|
String t = line;
|
||||||
|
if (!hasBeenLocked(line, name)) {
|
||||||
|
t = t.replace(name, LOCK_START + name + LOCK_END);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (areaNotation != null
|
||||||
|
&& areaNotation.trim().length() != 0) {
|
||||||
|
areaNotation = areaNotation.toUpperCase();
|
||||||
|
if (!hasBeenLocked(line, areaNotation.toUpperCase())) {
|
||||||
|
t = t.replace(areaNotation, LOCK_START
|
||||||
|
+ areaNotation + LOCK_END);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parentRegion != null
|
||||||
|
&& parentRegion.trim().length() != 0) {
|
||||||
|
parentRegion = parentRegion.toUpperCase();
|
||||||
|
if (!hasBeenLocked(line, parentRegion)) {
|
||||||
|
t = t.replace(parentRegion, LOCK_START
|
||||||
|
+ parentRegion + LOCK_END);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validate(t)) {
|
||||||
|
firstBulletText = firstBulletText.replace(line, t);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
firstBulletText = firstBulletText.replaceAll(firstBullet, LOCK_START
|
||||||
|
+ "$0" + LOCK_END);
|
||||||
|
|
||||||
|
this.text = text.replace(text.substring(start, end), firstBulletText);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locks the second bullet.
|
||||||
|
*/
|
||||||
|
private void secondBullet() {
|
||||||
|
// LOCK_END should not be found at the beginning since the previous line
|
||||||
|
// should be blank.
|
||||||
|
String secondBullet = "^(\\* UNTIL \\d{3,4} (AM|PM) \\w{3,4}" + newline
|
||||||
|
+ ")";
|
||||||
|
Pattern secondBulletPtrn = Pattern.compile(secondBullet,
|
||||||
|
Pattern.MULTILINE);
|
||||||
|
find(secondBulletPtrn.matcher(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the immediateCausePtrn with the info in immediateCause.text.
|
||||||
|
*/
|
||||||
|
private static Pattern getImmediateCausesPtrn() {
|
||||||
|
String filename = "immediateCause.txt";
|
||||||
|
StringBuffer pattern = new StringBuffer();
|
||||||
|
|
||||||
|
try {
|
||||||
|
String immediateCause = FileUtil.open(filename, "base");
|
||||||
|
pattern.append("(.*)(A DAM BREAK");
|
||||||
|
for (String ic : immediateCause.split("\n")) {
|
||||||
|
String[] parts = ic.split("\\\\");
|
||||||
|
pattern.append("| " + parts[1].trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
pattern.append(")(.*)");
|
||||||
|
return Pattern.compile(pattern.toString());
|
||||||
|
} catch (Exception e) {
|
||||||
|
statusHandler
|
||||||
|
.handle(Priority.ERROR,
|
||||||
|
"Unable to process immediateCause.txt in the base directory",
|
||||||
|
e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.viz.warngen.text;
|
||||||
|
|
||||||
|
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.texteditor.util.VtecUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the VTEC with a new ETN.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Sep 24, 2012 15322 jsanchez Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author jsanchez
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class NewModifyTextBehavior implements IModifyTextBehavior {
|
||||||
|
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||||
|
.getHandler(NewModifyTextBehavior.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String modify(String text) {
|
||||||
|
try {
|
||||||
|
text = VtecUtil.getVtec(text);
|
||||||
|
} catch (VizException e) {
|
||||||
|
statusHandler
|
||||||
|
.handle(Priority.SIGNIFICANT,
|
||||||
|
"WarnGen cannot update the ETN. Please verify the VTEC is valid.",
|
||||||
|
e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,137 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.viz.warngen.text;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import com.raytheon.viz.warngen.gis.AffectedAreas;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the raw text message by applying locked text patterns, wrapping, etc.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Sep 24, 2012 15322 jsanchez Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author jsanchez
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class WarningTextHandler {
|
||||||
|
|
||||||
|
private AbstractLockingBehavior lockingBehavior;
|
||||||
|
|
||||||
|
private IModifyTextBehavior modifyTextBehavior;
|
||||||
|
|
||||||
|
public String handle(String text, AffectedAreas[] affectedAreas,
|
||||||
|
AffectedAreas[] canceledAreas) {
|
||||||
|
long t0 = System.currentTimeMillis();
|
||||||
|
|
||||||
|
text = text.toUpperCase();
|
||||||
|
|
||||||
|
if (modifyTextBehavior != null) {
|
||||||
|
text = modifyTextBehavior.modify(text);
|
||||||
|
System.out.println("Modified text...");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lockingBehavior != null) {
|
||||||
|
text = lockingBehavior.lock(text, affectedAreas, canceledAreas);
|
||||||
|
System.out.println("Locked text...");
|
||||||
|
}
|
||||||
|
|
||||||
|
text = WrapUtil.wrap(text);
|
||||||
|
System.out.println("Wrapped text...");
|
||||||
|
|
||||||
|
text = clean(text);
|
||||||
|
|
||||||
|
System.out.println("Time to handle the text: "
|
||||||
|
+ (System.currentTimeMillis() - t0));
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets locking behavior
|
||||||
|
*
|
||||||
|
* @param lockingbehavior
|
||||||
|
*/
|
||||||
|
public void setLockingBehavior(AbstractLockingBehavior lockingBehavior) {
|
||||||
|
this.lockingBehavior = lockingBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the modify text behavior.
|
||||||
|
*
|
||||||
|
* @param modifyTextBehavior
|
||||||
|
*/
|
||||||
|
public void setModifyTextBehavior(IModifyTextBehavior modifyTextBehavior) {
|
||||||
|
this.modifyTextBehavior = modifyTextBehavior;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String clean(String text) {
|
||||||
|
text = removeExtraLines(text);
|
||||||
|
text = removeLockedBlankLines(text);
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes blank extra lines.
|
||||||
|
*
|
||||||
|
* @param text
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String removeExtraLines(String text) {
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
String[] seperatedLines = text.replaceAll("\r", "").trim().split("\n");
|
||||||
|
boolean blankLine = false;
|
||||||
|
for (String line : seperatedLines) {
|
||||||
|
if (line.replace(AbstractLockingBehavior.LOCK_START, "")
|
||||||
|
.replace(AbstractLockingBehavior.LOCK_END, "").trim()
|
||||||
|
.length() > 0) {
|
||||||
|
sb.append(line + "\n");
|
||||||
|
blankLine = false;
|
||||||
|
} else if (blankLine == false) {
|
||||||
|
sb.append(line + "\n");
|
||||||
|
blankLine = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the locked blank lines.
|
||||||
|
*
|
||||||
|
* @param text
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String removeLockedBlankLines(String text) {
|
||||||
|
Pattern lockedBlankLinesPattern = Pattern.compile("<L>(\\s*+)</L>",
|
||||||
|
Pattern.MULTILINE);
|
||||||
|
Matcher matchLockedBlankLines = lockedBlankLinesPattern.matcher(text);
|
||||||
|
return matchLockedBlankLines.replaceAll("$1");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.viz.warngen.text;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.dataplugin.warning.WarningRecord.WarningAction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a WarningTextHandler with the appropriate behaviors based on the type
|
||||||
|
* of warning is created.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Sep 24, 2012 15322 jsanchez Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author jsanchez
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class WarningTextHandlerFactory {
|
||||||
|
|
||||||
|
public static WarningTextHandler getHandler(WarningAction action,
|
||||||
|
String text, boolean autoLock) {
|
||||||
|
WarningTextHandler handler = new WarningTextHandler();
|
||||||
|
|
||||||
|
if (action == WarningAction.NEW) {
|
||||||
|
handler.setModifyTextBehavior(new NewModifyTextBehavior());
|
||||||
|
} else if (action == WarningAction.COR) {
|
||||||
|
handler.setModifyTextBehavior(new CorModifyTextBehavior());
|
||||||
|
} else {
|
||||||
|
System.out.println("The text will not be updated based on action.");
|
||||||
|
handler.setModifyTextBehavior(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!autoLock) {
|
||||||
|
System.out.println("Config has autoLock set to 'false'");
|
||||||
|
handler.setLockingBehavior(null);
|
||||||
|
} else if (isInitialWarning(action, text)) {
|
||||||
|
handler.setLockingBehavior(new InitialLockingBehavior());
|
||||||
|
} else {
|
||||||
|
handler.setLockingBehavior(new FollowUpLockingBehavior());
|
||||||
|
}
|
||||||
|
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isInitialWarning(WarningAction action, String text) {
|
||||||
|
if (action == WarningAction.NEW || action == WarningAction.EXT) {
|
||||||
|
return true;
|
||||||
|
} else if (action == WarningAction.COR) {
|
||||||
|
// TODO Need a better solution not to include the text in the
|
||||||
|
// factory.
|
||||||
|
Pattern firstBulletPtrn = Pattern
|
||||||
|
.compile(InitialLockingBehavior.firstBullet);
|
||||||
|
Matcher m = firstBulletPtrn.matcher(text);
|
||||||
|
return m.find();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,179 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.viz.warngen.text;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps lines in the warning text that exceed the max width.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Sep 24, 2012 15322 jsanchez Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author jsanchez
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class WrapUtil implements ICommonPatterns {
|
||||||
|
|
||||||
|
/** Maximum width of a warning */
|
||||||
|
private static final int MAX_WIDTH = 69;
|
||||||
|
|
||||||
|
private static final String INDENT = " ";
|
||||||
|
|
||||||
|
private static final String BULLET_START = "* ";
|
||||||
|
|
||||||
|
private static final Pattern wrapUgcPtrn = Pattern.compile("(\\S{1,"
|
||||||
|
+ (MAX_WIDTH - 1) + "}-)");
|
||||||
|
|
||||||
|
private static final Pattern wrapListOfNamesPtrn = Pattern.compile("(.{1,"
|
||||||
|
+ (MAX_WIDTH - 4) + "} \\w{2}-)");
|
||||||
|
|
||||||
|
// Locations in 4th bullet or locations paragraph of followup
|
||||||
|
// ex: ellipsis, spaces, period
|
||||||
|
private static final Pattern wrapDefaultPtrn = Pattern
|
||||||
|
.compile("(\\w{1,}\\.\\.\\.)|(AND \\w+\\.\\.\\.)|(\\w+\\.\\.\\.\\s{1,2})|"
|
||||||
|
+ "("
|
||||||
|
+ LOCK_START
|
||||||
|
+ "\\w+"
|
||||||
|
+ LOCK_END
|
||||||
|
+ "\\.\\.\\.)|\\S+\\.\\.\\."
|
||||||
|
+ LOCK_END
|
||||||
|
+ "|\\S+\\.\\.\\.|"
|
||||||
|
+ "(\\s*\\S+\\s+)|(.+\\.)|(\\S+$)");
|
||||||
|
|
||||||
|
// ugc pattern
|
||||||
|
private static final Pattern ugcPtrn = Pattern.compile(ugc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps the text independent of being locked before or after.
|
||||||
|
*
|
||||||
|
* @param text
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String wrap(String text) {
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
|
||||||
|
boolean inBullet = false;
|
||||||
|
String addLine = "";
|
||||||
|
String[] lines = text.split("\n");
|
||||||
|
for (int i = 0; i < lines.length; i++) {
|
||||||
|
String line = lines[i];
|
||||||
|
String unlocked = line.replaceAll(LOCK_START + "|" + LOCK_END, "");
|
||||||
|
|
||||||
|
if (unlocked.trim().length() == 0) { // BLANK LINE
|
||||||
|
inBullet = false;
|
||||||
|
addLine = line;
|
||||||
|
} else if (unlocked.length() <= MAX_WIDTH) { // LESS THAN MAX
|
||||||
|
// Add indenting if the template didn't account for it yet.
|
||||||
|
if (inBullet && !unlocked.startsWith(INDENT)) {
|
||||||
|
sb.append(INDENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlocked.startsWith(BULLET_START)) {
|
||||||
|
inBullet = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
addLine = line;
|
||||||
|
} else { // NEEDS TO BE WRAPPED
|
||||||
|
addLine = wrapLongLines(line, inBullet);
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append(addLine);
|
||||||
|
if (i != lines.length - 1) {
|
||||||
|
sb.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps lines longer than the MAX WIDTH
|
||||||
|
*
|
||||||
|
* @param line
|
||||||
|
* @param inBullet
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static String wrapLongLines(String line, boolean inBullet) {
|
||||||
|
StringBuffer sb = new StringBuffer(line.length());
|
||||||
|
String unlockedLine = line.replaceAll(LOCK_START + "|" + LOCK_END, "");
|
||||||
|
|
||||||
|
if (unlockedLine.startsWith(BULLET_START)) {
|
||||||
|
inBullet = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pattern p = getPattern(line);
|
||||||
|
Matcher m = p.matcher(line.trim());
|
||||||
|
String tmp = inBullet && !unlockedLine.startsWith(BULLET_START) ? INDENT
|
||||||
|
: "";
|
||||||
|
|
||||||
|
while (m.find()) {
|
||||||
|
String group = m.group();
|
||||||
|
String unlocked = group.replaceAll(LOCK_START + "|" + LOCK_END, "");
|
||||||
|
|
||||||
|
int len = tmp.replaceAll(LOCK_START + "|" + LOCK_END, "").length();
|
||||||
|
if (len + unlocked.length() > MAX_WIDTH && tmp.trim().length() > 0) {
|
||||||
|
sb.append(tmp + "\n");
|
||||||
|
tmp = inBullet ? INDENT : "";
|
||||||
|
tmp += group;
|
||||||
|
} else {
|
||||||
|
tmp += group;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmp.trim().length() > 0) {
|
||||||
|
sb.append(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to return matcher object for wrapping text.
|
||||||
|
*
|
||||||
|
* @param line
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static Pattern getPattern(String line) {
|
||||||
|
|
||||||
|
Matcher m = ugcPtrn.matcher(line);
|
||||||
|
// UGC line or FIPS line
|
||||||
|
if (m.find()) {
|
||||||
|
return wrapUgcPtrn;
|
||||||
|
}
|
||||||
|
|
||||||
|
m = listOfAreaNamePtrn.matcher(line);
|
||||||
|
// List of area names.
|
||||||
|
if (m.find() && !line.startsWith(BULLET_START)) {
|
||||||
|
return wrapListOfNamesPtrn;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wrapDefaultPtrn;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,22 +1,3 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.viz.warngen.util;
|
package com.raytheon.viz.warngen.util;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -34,6 +15,7 @@ import com.raytheon.uf.common.time.TimeRange;
|
||||||
import com.raytheon.viz.warngen.gis.AffectedAreas;
|
import com.raytheon.viz.warngen.gis.AffectedAreas;
|
||||||
import com.raytheon.viz.warngen.gis.GisUtil;
|
import com.raytheon.viz.warngen.gis.GisUtil;
|
||||||
import com.raytheon.viz.warngen.gis.GisUtil.Direction;
|
import com.raytheon.viz.warngen.gis.GisUtil.Direction;
|
||||||
|
import com.raytheon.viz.warngen.text.ICommonPatterns;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This utility will provide methods for determining what followup products are
|
* This utility will provide methods for determining what followup products are
|
||||||
|
@ -64,8 +46,9 @@ public class FollowUpUtil {
|
||||||
* This method checks whether a particular followup should be available
|
* This method checks whether a particular followup should be available
|
||||||
* given a Warning Record, a vtec Action, and a template configuration
|
* given a Warning Record, a vtec Action, and a template configuration
|
||||||
*/
|
*/
|
||||||
public static boolean checkApplicable(String site, WarngenConfiguration config,
|
public static boolean checkApplicable(String site,
|
||||||
AbstractWarningRecord record, WarningAction action) {
|
WarngenConfiguration config, AbstractWarningRecord record,
|
||||||
|
WarningAction action) {
|
||||||
|
|
||||||
// Current Time
|
// Current Time
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
|
@ -91,14 +74,16 @@ public class FollowUpUtil {
|
||||||
rval = true;
|
rval = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (action == WarningAction.COR && checkCorApplicable(site, config, record)) {
|
if (action == WarningAction.COR
|
||||||
|
&& checkCorApplicable(site, config, record)) {
|
||||||
rval = true;
|
rval = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean checkCorApplicable(String site, WarngenConfiguration config, AbstractWarningRecord warnRec) {
|
private static boolean checkCorApplicable(String site,
|
||||||
|
WarngenConfiguration config, AbstractWarningRecord warnRec) {
|
||||||
boolean allowsCONProduct = false;
|
boolean allowsCONProduct = false;
|
||||||
boolean allowsCORProduct = false;
|
boolean allowsCORProduct = false;
|
||||||
for (String s : config.getFollowUps()) {
|
for (String s : config.getFollowUps()) {
|
||||||
|
@ -113,29 +98,31 @@ public class FollowUpUtil {
|
||||||
if (allowsCORProduct == false) {
|
if (allowsCORProduct == false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentWarnings cw = CurrentWarnings.getInstance(site);
|
CurrentWarnings cw = CurrentWarnings.getInstance(site);
|
||||||
List<AbstractWarningRecord> correctableWarnings = cw.getCorrectableWarnings(warnRec);
|
List<AbstractWarningRecord> correctableWarnings = cw
|
||||||
|
.getCorrectableWarnings(warnRec);
|
||||||
|
|
||||||
boolean wasContinued = false;
|
boolean wasContinued = false;
|
||||||
for (AbstractWarningRecord w : correctableWarnings) {
|
for (AbstractWarningRecord w : correctableWarnings) {
|
||||||
if (WarningAction.valueOf(w.getAct()) == WarningAction.CON) {
|
if (WarningAction.valueOf(w.getAct()) == WarningAction.CON) {
|
||||||
wasContinued = true;
|
wasContinued = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adding a COR option for continuation follow ups
|
// Adding a COR option for continuation follow ups
|
||||||
if (correctableWarnings.isEmpty() == false && ((allowsCONProduct && wasContinued)
|
if (correctableWarnings.isEmpty() == false
|
||||||
|| (allowsCONProduct == false && wasContinued == false))) {
|
&& ((allowsCONProduct && wasContinued) || (allowsCONProduct == false && wasContinued == false))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the raw message of the record but removes
|
* Returns the raw message of the record but removes the first wmoid and the
|
||||||
* the first wmoid and the pil (the first two lines of the warning)
|
* pil (the first two lines of the warning)
|
||||||
|
*
|
||||||
* @param record
|
* @param record
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@ -169,47 +156,49 @@ public class FollowUpUtil {
|
||||||
|
|
||||||
return originalMessage;
|
return originalMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of the canceled areas from the original text
|
* Returns a list of the canceled areas from the original text
|
||||||
|
*
|
||||||
* @param originalText
|
* @param originalText
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static ArrayList<AffectedAreas> canceledAreasFromText(String originalText) {
|
public static ArrayList<AffectedAreas> canceledAreasFromText(
|
||||||
|
String originalText) {
|
||||||
boolean ugcdone = false;
|
boolean ugcdone = false;
|
||||||
boolean namedone = false;
|
boolean namedone = false;
|
||||||
boolean insideHeadline = false;
|
boolean insideHeadline = false;
|
||||||
String ugcLine = "";
|
String ugcLine = "";
|
||||||
String namesLine = "";
|
String namesLine = "";
|
||||||
String headline = "";
|
String headline = "";
|
||||||
|
Pattern ugcPtrn = Pattern.compile(ICommonPatterns.ugc);
|
||||||
for (String line : originalText.trim().split("\n")) {
|
for (String line : originalText.trim().split("\n")) {
|
||||||
if (line.contains("TEST") || line.trim().length() == 0) {
|
if (line.contains("TEST") || line.trim().length() == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
Matcher m = ugcPtrn.matcher(line);
|
||||||
Matcher m = WarningTextHandler.ugcPtrn.matcher(line);
|
|
||||||
if (!ugcdone && m.find()) {
|
if (!ugcdone && m.find()) {
|
||||||
ugcLine += m.group();
|
ugcLine += m.group();
|
||||||
continue;
|
continue;
|
||||||
} else if (ugcLine.length() > 0) {
|
} else if (ugcLine.length() > 0) {
|
||||||
ugcdone = true;
|
ugcdone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
m = WarningTextHandler.listOfAreaNamePtrn.matcher(line);
|
m = ICommonPatterns.listOfAreaNamePtrn.matcher(line);
|
||||||
if (!namedone && m.find()) {
|
if (!namedone && m.find()) {
|
||||||
namesLine += m.group();
|
namesLine += m.group();
|
||||||
continue;
|
continue;
|
||||||
} else if (namesLine.length() > 0) {
|
} else if (namesLine.length() > 0) {
|
||||||
namedone = true;
|
namedone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line.startsWith("...")) {
|
if (line.startsWith("...")) {
|
||||||
headline += line.substring(3);
|
headline += line.substring(3);
|
||||||
insideHeadline = true;
|
insideHeadline = true;
|
||||||
} else if (insideHeadline) {
|
} else if (insideHeadline) {
|
||||||
|
|
||||||
if (line.trim().endsWith("...")) {
|
if (line.trim().endsWith("...")) {
|
||||||
headline += line.substring(0,line.length() - 3);
|
headline += line.substring(0, line.length() - 3);
|
||||||
insideHeadline = false;
|
insideHeadline = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -219,9 +208,9 @@ public class FollowUpUtil {
|
||||||
String[] ugcs = ugcLine.split("-");
|
String[] ugcs = ugcLine.split("-");
|
||||||
String[] names = namesLine.split("-");
|
String[] names = namesLine.split("-");
|
||||||
String[] areas = headline.split("\\.\\.\\.");
|
String[] areas = headline.split("\\.\\.\\.");
|
||||||
|
|
||||||
ArrayList<AffectedAreas> al = new ArrayList<AffectedAreas>();
|
ArrayList<AffectedAreas> al = new ArrayList<AffectedAreas>();
|
||||||
|
|
||||||
String stateAbbreviation = null;
|
String stateAbbreviation = null;
|
||||||
String areaNotation = null;
|
String areaNotation = null;
|
||||||
String areasNotation = null;
|
String areasNotation = null;
|
||||||
|
@ -232,7 +221,7 @@ public class FollowUpUtil {
|
||||||
AffectedAreas affectedArea = new AffectedAreas();
|
AffectedAreas affectedArea = new AffectedAreas();
|
||||||
String ugc = ugcs[i].trim();
|
String ugc = ugcs[i].trim();
|
||||||
if (ugc.length() == 6) {
|
if (ugc.length() == 6) {
|
||||||
stateAbbreviation = ugc.substring(0,2);
|
stateAbbreviation = ugc.substring(0, 2);
|
||||||
if (ugc.charAt(2) == 'Z') {
|
if (ugc.charAt(2) == 'Z') {
|
||||||
areaNotation = "ZONE";
|
areaNotation = "ZONE";
|
||||||
areasNotation = "ZONES";
|
areasNotation = "ZONES";
|
||||||
|
@ -241,17 +230,18 @@ public class FollowUpUtil {
|
||||||
areasNotation = "COUNTIES";
|
areasNotation = "COUNTIES";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fips = ugc.substring(ugc.length() - 3);
|
fips = ugc.substring(ugc.length() - 3);
|
||||||
|
|
||||||
if (i < names.length) {
|
if (i < names.length) {
|
||||||
name = names[i].substring(0, names[i].length()-3);
|
name = names[i].substring(0, names[i].length() - 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
for (String area : areas) {
|
for (String area : areas) {
|
||||||
if (area.contains(name)) {
|
if (area.contains(name)) {
|
||||||
EnumSet<Direction> set = EnumSet.noneOf(Direction.class);
|
EnumSet<Direction> set = EnumSet
|
||||||
|
.noneOf(Direction.class);
|
||||||
for (Direction direction : Direction.values()) {
|
for (Direction direction : Direction.values()) {
|
||||||
if (area.contains(direction.name())) {
|
if (area.contains(direction.name())) {
|
||||||
set.add(direction);
|
set.add(direction);
|
||||||
|
@ -262,7 +252,7 @@ public class FollowUpUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
affectedArea.setFips(fips);
|
affectedArea.setFips(fips);
|
||||||
affectedArea.setStateabbr(stateAbbreviation);
|
affectedArea.setStateabbr(stateAbbreviation);
|
||||||
affectedArea.setAreaNotation(areaNotation);
|
affectedArea.setAreaNotation(areaNotation);
|
||||||
|
@ -274,11 +264,12 @@ public class FollowUpUtil {
|
||||||
|
|
||||||
return al;
|
return al;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getUgcLineCanFromText(String originalText) {
|
public static String getUgcLineCanFromText(String originalText) {
|
||||||
String ugcLine = "";
|
String ugcLine = "";
|
||||||
for (String line : originalText.trim().split("\n")) {
|
Pattern ugcPtrn = Pattern.compile(ICommonPatterns.ugc);
|
||||||
Matcher m = WarningTextHandler.ugcPtrn.matcher(line);
|
for (String line : originalText.trim().split("\n")) {
|
||||||
|
Matcher m = ugcPtrn.matcher(line);
|
||||||
if (m.find()) {
|
if (m.find()) {
|
||||||
ugcLine += line;
|
ugcLine += line;
|
||||||
continue;
|
continue;
|
||||||
|
@ -286,7 +277,7 @@ public class FollowUpUtil {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ugcLine;
|
return ugcLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,926 +0,0 @@
|
||||||
/**
|
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
||||||
*
|
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
||||||
* This software product contains export-restricted data whose
|
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
|
||||||
* an export license or other authorization.
|
|
||||||
*
|
|
||||||
* Contractor Name: Raytheon Company
|
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
|
||||||
* Mail Stop B8
|
|
||||||
* Omaha, NE 68106
|
|
||||||
* 402.291.0100
|
|
||||||
*
|
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
||||||
* further licensing information.
|
|
||||||
**/
|
|
||||||
package com.raytheon.viz.warngen.util;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import com.raytheon.uf.common.dataplugin.warning.WarningRecord.WarningAction;
|
|
||||||
import com.raytheon.uf.common.dataplugin.warning.util.FileUtil;
|
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
|
||||||
import com.raytheon.viz.texteditor.TextWarningConstants;
|
|
||||||
import com.raytheon.viz.texteditor.util.VtecObject;
|
|
||||||
import com.raytheon.viz.texteditor.util.VtecUtil;
|
|
||||||
import com.raytheon.viz.warngen.gis.AffectedAreas;
|
|
||||||
import com.raytheon.viz.warngen.gis.AffectedAreasComparator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds lock tags and wraps the text
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Dec 2, 2010 jsanchez Initial creation
|
|
||||||
* Aug 29, 2011 10719 rferrel applyLocks no longer allows removal of
|
|
||||||
* required blank lines.
|
|
||||||
* May 10, 2012 14681 Qinglu Lin Updated regex string for Pattern listOfAreaNamePtrn, etc.
|
|
||||||
* May 30, 2012 14749 Qinglu Lin Handled CAN in a CANCON specifically.
|
|
||||||
* Jun 6, 2012 14749 Qinglu Lin Added code to lock "...THE" in "...THE CITY OF", etc.
|
|
||||||
* (David's concise approach was used. A quicker but
|
|
||||||
* lengthy code snippet is available) and to resolve issue with
|
|
||||||
* empty areaNotation and areasNotation which occurs when,
|
|
||||||
* for example, District of Columbia is followed by a county.
|
|
||||||
* Jun 19, 2012 15110 Qinglu Lin Fixed issues in CAN of CANCON: a) ST in any words changed to "ST." and
|
|
||||||
* locked if county name has ST., e.g., ST. JOSEPH;
|
|
||||||
* b)Locking beyond the first paragraph for areal flood warning followup;
|
|
||||||
* c)Locking does not work for areal flood advisory followup;
|
|
||||||
* d)NullointException/locking does not work for special marine warning
|
|
||||||
* and locking beyond first paragragh.
|
|
||||||
* Jul 17, 2012 14989 Qinglu Lin Removed locks, <L> and </L>, for county names in pathcast line.
|
|
||||||
* Sep 11, 2012 15372 Qinglu Lin Adjusted code so that <L> and </L> in the line of "MAINLY RURAL AREAS"
|
|
||||||
* were removed as well.
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author jsanchez
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class WarningTextHandler {
|
|
||||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
|
||||||
.getHandler(WarningTextHandler.class);
|
|
||||||
|
|
||||||
/** Maximum width of a warning */
|
|
||||||
private static final int MAX_WIDTH = 69;
|
|
||||||
|
|
||||||
private static final String LOCK_START = TextWarningConstants.BEGIN_ELEMENT_TAG;
|
|
||||||
|
|
||||||
private static final String LOCK_END = TextWarningConstants.END_ELEMENT_TAG;
|
|
||||||
|
|
||||||
private static final String TEST_MSG1 = "...THIS MESSAGE IS FOR TEST PURPOSES ONLY...";
|
|
||||||
|
|
||||||
private static final String TEST_MSG2 = "THIS IS A TEST MESSAGE.";
|
|
||||||
|
|
||||||
private static final String TEST_MSG3 = "THIS IS A TEST MESSAGE. DO NOT TAKE ACTION BASED ON THIS MESSAGE.";
|
|
||||||
|
|
||||||
/** Pattern for wrapping a long line */
|
|
||||||
private static final Pattern wrapRE = Pattern
|
|
||||||
.compile("(\\S\\S&&([^\\.][^\\.][^\\.]){" + (MAX_WIDTH - 3)
|
|
||||||
+ ",}|.{1," + (MAX_WIDTH - 3) + "})(" + LOCK_START + "|"
|
|
||||||
+ LOCK_END + "|-|\\s+|(\\.\\.\\.)|$)");
|
|
||||||
|
|
||||||
/** Strictly wraps only after hyphens */
|
|
||||||
private static final Pattern hyphenWrapRE = Pattern.compile("(.{1,"
|
|
||||||
+ (MAX_WIDTH - 1) + "}-)");
|
|
||||||
|
|
||||||
private static final Pattern datePtrn = Pattern
|
|
||||||
.compile("(\\d{1,2})(\\d{2})\\s(AM|PM)\\s(\\w{3,4})\\s\\w{3}\\s(\\w{3})\\s{1,}(\\d{1,2})\\s(\\d{4})");
|
|
||||||
|
|
||||||
/** The UGC line (ex. NEC003-008-010-110325) */
|
|
||||||
public static final Pattern ugcPtrn = Pattern
|
|
||||||
.compile("((\\w{2}[CZ](\\d{3}-){1,}){1,})|(\\d{3}-){1,}");
|
|
||||||
|
|
||||||
/** The VTEC line (ex. /O.NEW.KOAX.TO.W.0001.110715T1722Z-110715T1730Z) */
|
|
||||||
private static final Pattern vtecPtrn = Pattern
|
|
||||||
.compile("/[OTEX]\\.([A-Z]{3})\\.[A-Za-z0-9]{4}\\.[A-Z]{2}\\.[WAYSFON]\\.\\d{4}\\.\\d{6}T\\d{4}Z-\\d{6}T\\d{4}Z/");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The HTEC line (ex.
|
|
||||||
* /00000.0.${ic}.000000T0000Z.000000T0000Z.000000T0000Z.OO/)
|
|
||||||
*/
|
|
||||||
private static final Pattern htecPtrn = Pattern
|
|
||||||
.compile("/[A-Za-z0-9]{5}.[0-3NU].\\w{2}.\\d{6}T\\d{4}Z.\\d{6}T\\d{4}Z.\\d{6}T\\d{4}Z.\\w{2}/");
|
|
||||||
|
|
||||||
/** ex. * TORNADO WARNING FOR... */
|
|
||||||
private static final Pattern firstBulletPtrn = Pattern
|
|
||||||
.compile("\\*\\s(.*)\\s(WARNING|ADVISORY)(\\sFOR(.*)|\\.\\.\\.)");
|
|
||||||
|
|
||||||
private static final Pattern cancelPtrn = Pattern
|
|
||||||
.compile("(|(.*))(IS CANCELLED\\.\\.\\.)");
|
|
||||||
|
|
||||||
private static final Pattern cancelOnlyPtrn = Pattern
|
|
||||||
.compile("(CANCELLED<\\/L>\\.\\.\\.)");
|
|
||||||
|
|
||||||
private static final Pattern expirePtrn = Pattern
|
|
||||||
.compile("(|(.*))((EXPIRED|WILL EXPIRE)\\sAT\\s\\d{3,4}\\s(AM|PM)\\s\\w{3}...)");
|
|
||||||
|
|
||||||
private static final Pattern headlinePtrn = Pattern
|
|
||||||
.compile("(\\.\\.\\.((A|THE)\\s(.*)\\s(WARNING|ADVISORY))\\s(FOR|(REMAINS IN EFFECT (|(UNTIL\\s\\d{3,4}\\s(AM|PM)\\s\\w{3})))))(|(.*))");
|
|
||||||
|
|
||||||
private static final Pattern canVtecPtrn = Pattern.compile("(\\.CAN\\.)");
|
|
||||||
|
|
||||||
private static final Pattern smwCanPtrn = Pattern.compile("(\\.MA\\.W\\.)");
|
|
||||||
|
|
||||||
private static final Pattern afaCanPtrn = Pattern.compile("(\\.FA\\.Y\\.)");
|
|
||||||
|
|
||||||
private static final Pattern smwHeadlinePtrn = Pattern
|
|
||||||
.compile("(THE AFFECTED AREAS WERE)");
|
|
||||||
|
|
||||||
private static Pattern immediateCausePtrn = null;
|
|
||||||
|
|
||||||
/** ex. SARPY NE-DOUGLAS NE-WASHINGTON NE- */
|
|
||||||
public static final Pattern listOfAreaNamePtrn = Pattern
|
|
||||||
.compile("(((\\w{1,}\\s{1}){1,}\\w{2}-){0,}((\\w{1,}\\s{1}){1,}\\w{2}-))");
|
|
||||||
|
|
||||||
private static final Pattern secondBulletPtrn = Pattern.compile("\\*(|\\s"
|
|
||||||
+ TEST_MSG2 + ")\\sUNTIL\\s\\d{3,4}\\s(AM|PM)\\s\\w{3,4}");
|
|
||||||
|
|
||||||
private static final Pattern testMessagePtrn = Pattern.compile("(|.*)("
|
|
||||||
+ TEST_MSG2 + ")(.*)");
|
|
||||||
|
|
||||||
private static final Pattern latLonPtrn = Pattern
|
|
||||||
.compile("^LAT...LON+(\\s\\d{3,4}\\s\\d{3,5}){1,}");
|
|
||||||
|
|
||||||
private static final Pattern subLatLonPtrn = Pattern
|
|
||||||
.compile("^((?!TIME...MOT... LOC))\\s{1,}\\d{3,4}\\s\\d{3,5}(|(\\s\\d{3,4}\\s\\d{3,5}){1,})");
|
|
||||||
|
|
||||||
private static final Pattern tmlPtrn = Pattern
|
|
||||||
.compile("TIME...MOT...LOC \\d{3,4}Z\\s\\d{3}DEG\\s\\d{1,3}KT((\\s\\d{3,4}\\s\\d{3,5}){1,})");
|
|
||||||
|
|
||||||
private static final Pattern subTMLPtrn = Pattern
|
|
||||||
.compile("(\\d{3,5}\\s){1,}");
|
|
||||||
|
|
||||||
private static final Pattern lockedBlankLinesPattern = Pattern.compile(
|
|
||||||
"<L>(\\s*+)</L>", Pattern.MULTILINE);
|
|
||||||
|
|
||||||
private static final String LOCK_REPLACEMENT_TEXT = LOCK_START + "$0"
|
|
||||||
+ LOCK_END;
|
|
||||||
|
|
||||||
private static final Pattern extraTokensPattern = Pattern
|
|
||||||
.compile("\\b(?:THE|IS|CANCELLED)\\b");
|
|
||||||
|
|
||||||
static {
|
|
||||||
String pattern = "";
|
|
||||||
|
|
||||||
// Load immediateCausePtrn with immediateCause.txt
|
|
||||||
try {
|
|
||||||
String immediateCause = FileUtil.open("immediateCause.txt", "base");
|
|
||||||
pattern = "(.*)(A DAM BREAK";
|
|
||||||
for (String ic : immediateCause.split("\n")) {
|
|
||||||
String[] parts = ic.split("\\\\");
|
|
||||||
pattern += "| " + parts[1].trim();
|
|
||||||
}
|
|
||||||
pattern += ")(.*)";
|
|
||||||
immediateCausePtrn = Pattern.compile(pattern);
|
|
||||||
} catch (Exception e) {
|
|
||||||
statusHandler
|
|
||||||
.handle(Priority.ERROR,
|
|
||||||
"Unable to process immediateCause.txt in the base directory",
|
|
||||||
e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String handle(String originalMessage, AffectedAreas[] areas,
|
|
||||||
AffectedAreas[] canceledAreas, WarningAction action,
|
|
||||||
WarningAction action2, boolean autoLock) {
|
|
||||||
long t0 = System.currentTimeMillis();
|
|
||||||
if (action == WarningAction.NEW) {
|
|
||||||
try {
|
|
||||||
originalMessage = VtecUtil.getVtec(originalMessage);
|
|
||||||
} catch (Exception e) {
|
|
||||||
statusHandler
|
|
||||||
.handle(Priority.SIGNIFICANT,
|
|
||||||
"WarnGen cannot update the ETN. Please verify the VTEC is valid.",
|
|
||||||
e);
|
|
||||||
}
|
|
||||||
} else if (action == WarningAction.COR) {
|
|
||||||
originalMessage = addCorrectedText(originalMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
originalMessage = wrap(originalMessage);
|
|
||||||
|
|
||||||
if (autoLock) {
|
|
||||||
boolean initialWarning = (action == WarningAction.NEW || action == WarningAction.EXT);
|
|
||||||
|
|
||||||
if (action == WarningAction.COR) {
|
|
||||||
Matcher m = firstBulletPtrn.matcher(originalMessage);
|
|
||||||
initialWarning = m.find();
|
|
||||||
}
|
|
||||||
List<AffectedAreas> areasArr = areas != null ? Arrays.asList(areas)
|
|
||||||
: null;
|
|
||||||
List<AffectedAreas> canceledAreasArr = canceledAreas != null ? Arrays
|
|
||||||
.asList(canceledAreas) : null;
|
|
||||||
originalMessage = applyLocks(originalMessage, areasArr,
|
|
||||||
canceledAreasArr, initialWarning, action2);
|
|
||||||
}
|
|
||||||
|
|
||||||
originalMessage = removeExtraLines(originalMessage);
|
|
||||||
|
|
||||||
// remove locked blank lines
|
|
||||||
Matcher matchLockedBlankLines = lockedBlankLinesPattern
|
|
||||||
.matcher(originalMessage);
|
|
||||||
originalMessage = matchLockedBlankLines.replaceAll("$1");
|
|
||||||
|
|
||||||
System.out.println("Time to handle the text: "
|
|
||||||
+ (System.currentTimeMillis() - t0));
|
|
||||||
return originalMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String addCorrectedText(String originalMessage) {
|
|
||||||
int index = originalMessage.indexOf("NATIONAL WEATHER SERVICE");
|
|
||||||
String[] types = new String[] { "WARNING", "WATCH", "STATEMENT",
|
|
||||||
"ADVISORY" };
|
|
||||||
int typeIdx = -1, i = 0;
|
|
||||||
if (index > 0) {
|
|
||||||
for (i = 0; i < types.length; i++) {
|
|
||||||
if (originalMessage.lastIndexOf(types[i], index) != -1) {
|
|
||||||
typeIdx = originalMessage.lastIndexOf(types[i], index);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index > 0 && typeIdx > 0
|
|
||||||
&& !originalMessage.contains("...CORRECTED")) {
|
|
||||||
originalMessage = originalMessage.substring(0,
|
|
||||||
typeIdx + types[i].length())
|
|
||||||
+ "...CORRECTED"
|
|
||||||
+ originalMessage.substring(typeIdx + types[i].length());
|
|
||||||
}
|
|
||||||
|
|
||||||
return originalMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String applyLocks(String originalMessage,
|
|
||||||
List<AffectedAreas> areas, List<AffectedAreas> canceledAreas,
|
|
||||||
boolean initialWarning, WarningAction action) {
|
|
||||||
boolean firstBulletFound = false;
|
|
||||||
boolean insideFirstBullet = false;
|
|
||||||
boolean secondBulletFound = false;
|
|
||||||
boolean headlineFound = false;
|
|
||||||
// for CAN in a CANCON
|
|
||||||
boolean cancelVtecLineFound = false;
|
|
||||||
boolean insideLatLon = false;
|
|
||||||
boolean insideTML = false;
|
|
||||||
boolean checkForMND = true;
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
String[] seperatedLines = originalMessage.trim().split("\n");
|
|
||||||
Matcher m = null;
|
|
||||||
|
|
||||||
VtecObject vtecObj = VtecUtil.parseMessage(originalMessage);
|
|
||||||
boolean marineProduct = vtecObj != null
|
|
||||||
&& vtecObj.getPhenomena() != null
|
|
||||||
&& vtecObj.getPhenomena().equals("MA");
|
|
||||||
|
|
||||||
AffectedAreasComparator comparator = new AffectedAreasComparator(
|
|
||||||
new ArrayList<String>());
|
|
||||||
|
|
||||||
if (areas != null) {
|
|
||||||
Collections.sort(areas, comparator);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (canceledAreas != null) {
|
|
||||||
Collections.sort(canceledAreas, comparator);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean startLines = true;
|
|
||||||
|
|
||||||
// Set before to false if the line is beyond
|
|
||||||
// "THE NATIONAL WEATHER SERVICE IN" line.
|
|
||||||
boolean before = true;
|
|
||||||
|
|
||||||
boolean isCancelledFound = false;
|
|
||||||
|
|
||||||
// for CAN of CANCON of Special Marine Warning
|
|
||||||
boolean smwCan = false;
|
|
||||||
boolean lockSmwCan = false;
|
|
||||||
|
|
||||||
// for CAN of CANCON of Areal Flood Advisory
|
|
||||||
boolean afaCan = false;
|
|
||||||
int afaCanBlankline = 0;
|
|
||||||
|
|
||||||
String[] tokens = null;
|
|
||||||
if (canceledAreas != null) {
|
|
||||||
String areaNames = "";
|
|
||||||
for (AffectedAreas area : canceledAreas) {
|
|
||||||
String areaName = area.getName();
|
|
||||||
if (areaName != null && areaName.length() > 0) {
|
|
||||||
areaName = areaName.toUpperCase();
|
|
||||||
areaNames += areaName + " ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
areaNames = areaNames.trim();
|
|
||||||
HashSet<String> areaNameSet = new HashSet<String>();
|
|
||||||
String[] tokens0 = areaNames.split(" ");
|
|
||||||
int tokensLength = tokens0.length;
|
|
||||||
for (int i = 0; i < tokensLength; i++) {
|
|
||||||
areaNameSet.add(tokens0[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
tokens = (String[]) areaNameSet.toArray(new String[areaNameSet
|
|
||||||
.size()]);
|
|
||||||
String s0;
|
|
||||||
for (int i = 0; i < areaNameSet.size() - 1; i++) {
|
|
||||||
s0 = tokens[i];
|
|
||||||
String s1;
|
|
||||||
for (int j = i; j < areaNameSet.size(); j++) {
|
|
||||||
if (tokens[j].length() > s0.length()) {
|
|
||||||
s1 = s0;
|
|
||||||
s0 = tokens[j];
|
|
||||||
tokens[j] = s1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tokens[i] = s0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean ruralFound = false, ruralReplaced = false;
|
|
||||||
ArrayList<String> usedAreaNotations = new ArrayList<String>();
|
|
||||||
for (int lineIndex = 0; lineIndex < seperatedLines.length; ++lineIndex) {
|
|
||||||
String line = seperatedLines[lineIndex];
|
|
||||||
|
|
||||||
if (line.contains("THE NATIONAL WEATHER SERVICE IN")
|
|
||||||
|| line.contains("OTHER LOCATIONS IMPACTED")) {
|
|
||||||
before = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ruralFound && !ruralReplaced && line.contains("MAINLY RURAL AREAS")) {
|
|
||||||
ruralFound = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This prevents blank line(s) after the header from being locked.
|
|
||||||
if (startLines && lineIndex > 1) {
|
|
||||||
startLines = line.trim().length() == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// MND header
|
|
||||||
if (checkForMND
|
|
||||||
&& (line.contains("EAS ACTIVATION")
|
|
||||||
|| line.contains("IMMEDIATE BROADCAST")
|
|
||||||
|| line.startsWith("NATIONAL WEATHER SERVICE")
|
|
||||||
|| line.startsWith("THE NATIONAL WEATHER SERVICE")
|
|
||||||
|| line.startsWith("ISSUED BY ")
|
|
||||||
|| line.contains("...CORRECTED") || ((line
|
|
||||||
.endsWith("WARNING")
|
|
||||||
|| line.endsWith("WATCH")
|
|
||||||
|| line.endsWith("STATEMENT") || line
|
|
||||||
.endsWith("ADVISORY")) && line.startsWith("*") == false))) {
|
|
||||||
sb.append(LOCK_START + line + "\n" + LOCK_END);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Locking the UGC line
|
|
||||||
m = ugcPtrn.matcher(line);
|
|
||||||
if (m.find()) {
|
|
||||||
sb.append(LOCK_START + line + "\n" + LOCK_END);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Locking the VTEC
|
|
||||||
m = vtecPtrn.matcher(line);
|
|
||||||
if (m.find()) {
|
|
||||||
sb.append(LOCK_START + line + "\n" + LOCK_END);
|
|
||||||
// check out if .CAN. is in VTEC line of a CANCON product.
|
|
||||||
m = canVtecPtrn.matcher(line);
|
|
||||||
if (action == WarningAction.CANCON && m.find()) {
|
|
||||||
cancelVtecLineFound = true;
|
|
||||||
m = smwCanPtrn.matcher(line);
|
|
||||||
if (m.find())
|
|
||||||
smwCan = true;
|
|
||||||
m = afaCanPtrn.matcher(line);
|
|
||||||
if (m.find())
|
|
||||||
afaCan = true;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Locking the HTEC
|
|
||||||
m = htecPtrn.matcher(line);
|
|
||||||
if (m.find()) {
|
|
||||||
sb.append(LOCK_START + m.group(0) + "\n" + LOCK_END);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (before) {
|
|
||||||
m = listOfAreaNamePtrn.matcher(line);
|
|
||||||
if (m.matches()) {
|
|
||||||
if (!(line.contains("!**") || line.contains("**!") || line
|
|
||||||
.contains("OTHER LOCATIONS"))) {
|
|
||||||
sb.append(LOCK_START + line + "\n" + LOCK_END);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Locking Date in the MND header
|
|
||||||
m = datePtrn.matcher(line);
|
|
||||||
if (m.find()) {
|
|
||||||
sb.append(LOCK_START + line + "\n" + LOCK_END);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ruralFound)
|
|
||||||
if (line.trim().length() == 0)
|
|
||||||
ruralFound = false;
|
|
||||||
else {
|
|
||||||
line = line.replace("<L>", "");
|
|
||||||
line = line.replace("</L>", "");
|
|
||||||
sb.append(line + "\n");
|
|
||||||
if (!ruralReplaced)
|
|
||||||
ruralReplaced = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line.trim().length() == 0) {
|
|
||||||
insideTML = false;
|
|
||||||
insideLatLon = false;
|
|
||||||
headlineFound = false;
|
|
||||||
if (smwCan) {
|
|
||||||
if (lockSmwCan)
|
|
||||||
cancelVtecLineFound = false;
|
|
||||||
lockSmwCan = false;
|
|
||||||
}
|
|
||||||
if (afaCan) {
|
|
||||||
afaCanBlankline += 1;
|
|
||||||
if (afaCanBlankline > 1) {
|
|
||||||
afaCan = false;
|
|
||||||
cancelVtecLineFound = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (startLines) {
|
|
||||||
// Don't lock blank line after header
|
|
||||||
sb.append("\n");
|
|
||||||
} else if (sb.lastIndexOf("\n") == (sb.length() - 1)) {
|
|
||||||
// Put lock at end of previous line to prevent removal
|
|
||||||
// of leading blank line.
|
|
||||||
sb.setLength(sb.length() - 1);
|
|
||||||
sb.append(LOCK_START + "\n\n" + LOCK_END);
|
|
||||||
} else {
|
|
||||||
sb.append(LOCK_START + "\n" + LOCK_END);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hack!
|
|
||||||
// This is needed due to a drifting <L>
|
|
||||||
// due tothe replaceAll("</L>([\\s\\n\\r]*)<L>", "$1");
|
|
||||||
if (line.startsWith("* AT") || line.startsWith("AT")) {
|
|
||||||
sb.append(LOCK_START + "" + LOCK_END);
|
|
||||||
headlineFound = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (initialWarning) {
|
|
||||||
// Locking first bullet
|
|
||||||
m = firstBulletPtrn.matcher(line);
|
|
||||||
if (m.find() && firstBulletFound == false) {
|
|
||||||
checkForMND = false;
|
|
||||||
sb.append(LOCK_START + line + "\n" + LOCK_END);
|
|
||||||
firstBulletFound = true;
|
|
||||||
insideFirstBullet = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (insideFirstBullet) {
|
|
||||||
// Removes extra spaces between texts in the first
|
|
||||||
// bullet
|
|
||||||
line = line.replaceAll("\\s{3}", " ").replaceAll(
|
|
||||||
"\\b\\s{2,}\\b", " ");
|
|
||||||
|
|
||||||
// Lock immediate cause (hydro) (DR 10329)
|
|
||||||
if (immediateCausePtrn != null) {
|
|
||||||
m = immediateCausePtrn.matcher(line);
|
|
||||||
if (m.find()) {
|
|
||||||
sb.append(LOCK_START + line + "\n" + LOCK_END);
|
|
||||||
continue; // immediate cause on its own line
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean countyFound = false;
|
|
||||||
boolean areaNotationFound = false;
|
|
||||||
boolean stateFound = false;
|
|
||||||
|
|
||||||
if (areas != null && !marineProduct) {
|
|
||||||
for (int i = areas.size() - 1; i >= 0; i--) {
|
|
||||||
AffectedAreas area = areas.get(i);
|
|
||||||
// Lock counties & independent cities (DR 10331)
|
|
||||||
if (!countyFound
|
|
||||||
&& area.getName() != null
|
|
||||||
&& area.getName().length() > 0
|
|
||||||
&& line.contains(area.getName()
|
|
||||||
.toUpperCase())) {
|
|
||||||
line = line.replaceFirst(area.getName()
|
|
||||||
.toUpperCase(), LOCK_START
|
|
||||||
+ area.getName().toUpperCase()
|
|
||||||
+ LOCK_END);
|
|
||||||
countyFound = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!areaNotationFound
|
|
||||||
&& area.getAreaNotation() != null
|
|
||||||
&& area.getAreaNotation().length() > 0
|
|
||||||
&& line.contains(area.getAreaNotation()
|
|
||||||
.toUpperCase())) {
|
|
||||||
line = line.replaceFirst(
|
|
||||||
" " + area.getAreaNotation(),
|
|
||||||
LOCK_START + " "
|
|
||||||
+ area.getAreaNotation()
|
|
||||||
+ LOCK_END);
|
|
||||||
areaNotationFound = true;
|
|
||||||
}
|
|
||||||
// Lock States (DR 10325)
|
|
||||||
if (!stateFound
|
|
||||||
&& area.getParentRegion() != null
|
|
||||||
&& area.getParentRegion().length() > 0
|
|
||||||
&& line.contains(area.getParentRegion()
|
|
||||||
.toUpperCase())) {
|
|
||||||
line = line.replaceFirst(area
|
|
||||||
.getParentRegion().toUpperCase(),
|
|
||||||
LOCK_START
|
|
||||||
+ area.getParentRegion()
|
|
||||||
.toUpperCase()
|
|
||||||
+ LOCK_END);
|
|
||||||
stateFound = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Locking second bullet
|
|
||||||
m = secondBulletPtrn.matcher(line);
|
|
||||||
if (m.find() && secondBulletFound == false) {
|
|
||||||
sb.append(LOCK_START + line + "\n" + LOCK_END);
|
|
||||||
insideFirstBullet = false;
|
|
||||||
secondBulletFound = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
usedAreaNotations.clear();
|
|
||||||
// head line pattern
|
|
||||||
m = headlinePtrn.matcher(line);
|
|
||||||
if (m.find()) {
|
|
||||||
checkForMND = false;
|
|
||||||
headlineFound = true;
|
|
||||||
line = line.replace(m.group(2), LOCK_START + m.group(2)
|
|
||||||
+ LOCK_END);
|
|
||||||
}
|
|
||||||
// CAN portion in a CANCON
|
|
||||||
if (cancelVtecLineFound) {
|
|
||||||
if (smwCan) {
|
|
||||||
// lock marine zone names
|
|
||||||
if (lockSmwCan) {
|
|
||||||
if (line.length() == 0) {
|
|
||||||
lockSmwCan = false;
|
|
||||||
} else
|
|
||||||
line = LOCK_START + line + LOCK_END;
|
|
||||||
} else {
|
|
||||||
m = smwHeadlinePtrn.matcher(line);
|
|
||||||
if (m.find())
|
|
||||||
lockSmwCan = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (String s : tokens)
|
|
||||||
if (line.contains(s))
|
|
||||||
line = line.replace(s, LOCK_START + s
|
|
||||||
+ LOCK_END);
|
|
||||||
for (AffectedAreas area : canceledAreas) {
|
|
||||||
String areaNotation = area.getAreaNotation();
|
|
||||||
if (areaNotation != null) {
|
|
||||||
// areaNotation, e.g., COUNTY
|
|
||||||
if (areaNotation != null
|
|
||||||
&& areaNotation.length() > 0
|
|
||||||
&& !usedAreaNotations
|
|
||||||
.contains(areaNotation)
|
|
||||||
&& line.contains(areaNotation)) {
|
|
||||||
line = line.replaceAll(areaNotation,
|
|
||||||
LOCK_START + areaNotation
|
|
||||||
+ LOCK_END);
|
|
||||||
usedAreaNotations.add(areaNotation);
|
|
||||||
}
|
|
||||||
// areasNotation, e.g., COUNTIES
|
|
||||||
String areasNotation = area
|
|
||||||
.getAreasNotation().toUpperCase();
|
|
||||||
if (areasNotation != null
|
|
||||||
&& areasNotation.length() > 0
|
|
||||||
&& !usedAreaNotations
|
|
||||||
.contains(areasNotation)
|
|
||||||
&& line.contains(areasNotation)) {
|
|
||||||
line = line.replaceAll(areasNotation,
|
|
||||||
LOCK_START + areasNotation
|
|
||||||
+ LOCK_END);
|
|
||||||
usedAreaNotations.add(areasNotation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// locking "THE" in "THE CITY OF MANASSAS", "...THE"
|
|
||||||
// in "...THE CITY",
|
|
||||||
// and "IS" or "CANCELLED" in "IS CANCELLED...".
|
|
||||||
line = extraTokensPattern.matcher(line).replaceAll(
|
|
||||||
LOCK_REPLACEMENT_TEXT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cancelVtecLineFound && isCancelledFound)
|
|
||||||
cancelVtecLineFound = false;
|
|
||||||
|
|
||||||
m = cancelOnlyPtrn.matcher(line);
|
|
||||||
if (m.find())
|
|
||||||
cancelVtecLineFound = false;
|
|
||||||
|
|
||||||
sb.append(line + "\n");
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
// follow-ups other than CAN in a CANCON
|
|
||||||
if (headlineFound) {
|
|
||||||
usedAreaNotations.clear();
|
|
||||||
if (areas != null && !marineProduct) {
|
|
||||||
for (AffectedAreas area : areas) {
|
|
||||||
if (area.getName() != null
|
|
||||||
&& line.contains(area.getName()
|
|
||||||
.toUpperCase())) {
|
|
||||||
line = line.replaceFirst(area.getName()
|
|
||||||
.toUpperCase(), LOCK_START
|
|
||||||
+ area.getName().toUpperCase()
|
|
||||||
+ LOCK_END);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (area.getAreaNotation() != null
|
|
||||||
&& !usedAreaNotations.contains(area
|
|
||||||
.getAreaNotation()
|
|
||||||
.toUpperCase())
|
|
||||||
&& line.contains(area
|
|
||||||
.getAreaNotation())) {
|
|
||||||
line = line
|
|
||||||
.replaceAll(
|
|
||||||
" "
|
|
||||||
+ area.getAreaNotation()
|
|
||||||
.toUpperCase(),
|
|
||||||
LOCK_START
|
|
||||||
+ " "
|
|
||||||
+ area.getAreaNotation()
|
|
||||||
+ LOCK_END);
|
|
||||||
usedAreaNotations.add(area
|
|
||||||
.getAreaNotation()
|
|
||||||
.toUpperCase());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m = cancelPtrn.matcher(line);
|
|
||||||
if (m.find()) {
|
|
||||||
line = line.replaceFirst(m.group(3), LOCK_START
|
|
||||||
+ m.group(3) + LOCK_END);
|
|
||||||
if (canceledAreas != null) {
|
|
||||||
for (AffectedAreas canceledArea : canceledAreas) {
|
|
||||||
if (line.contains(canceledArea
|
|
||||||
.getName().toUpperCase())) {
|
|
||||||
line = line
|
|
||||||
.replaceFirst(
|
|
||||||
canceledArea
|
|
||||||
.getName()
|
|
||||||
.toUpperCase(),
|
|
||||||
LOCK_START
|
|
||||||
+ canceledArea
|
|
||||||
.getName()
|
|
||||||
.toUpperCase()
|
|
||||||
+ LOCK_END);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
headlineFound = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m = expirePtrn.matcher(line);
|
|
||||||
if (m.find()) {
|
|
||||||
line = line.replaceFirst(m.group(3), LOCK_START
|
|
||||||
+ m.group(3) + LOCK_END);
|
|
||||||
headlineFound = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.append(line + "\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Locking LAT...LON
|
|
||||||
m = latLonPtrn.matcher(line);
|
|
||||||
if (m.find()) {
|
|
||||||
sb.append(LOCK_START + line + "\n" + LOCK_END);
|
|
||||||
insideLatLon = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (insideLatLon) {
|
|
||||||
m = subLatLonPtrn.matcher(line);
|
|
||||||
if (m.find()) {
|
|
||||||
sb.append(LOCK_START + line + "\n" + LOCK_END);
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
insideLatLon = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PRECAUTIONARY/PREPAREDNESS ACTIONS, $$, &&
|
|
||||||
if (line.equals("PRECAUTIONARY/PREPAREDNESS ACTIONS...")
|
|
||||||
|| line.startsWith("$$") || line.startsWith("&&")) {
|
|
||||||
sb.append(LOCK_START + line + "\n" + LOCK_END);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Locking TIME...MOT..LOC
|
|
||||||
m = tmlPtrn.matcher(line);
|
|
||||||
if (m.find()) {
|
|
||||||
sb.append(LOCK_START + line + "\n" + LOCK_END);
|
|
||||||
insideTML = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (insideTML) {
|
|
||||||
m = subTMLPtrn.matcher(line);
|
|
||||||
if (m.matches()) {
|
|
||||||
sb.append(LOCK_START + line + "\n" + LOCK_END);
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
insideTML = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test lines
|
|
||||||
if (line.equals(TEST_MSG3)
|
|
||||||
|| line.equals(TEST_MSG1)
|
|
||||||
|| (line.startsWith("TEST...") && line
|
|
||||||
.endsWith("...TEST"))) {
|
|
||||||
sb.append(LOCK_START + line + LOCK_END + "\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
m = testMessagePtrn.matcher(line);
|
|
||||||
if (m.find()) {
|
|
||||||
line = line.replace(m.group(2), LOCK_START + m.group(2)
|
|
||||||
+ LOCK_END);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
// If an exception is thrown,
|
|
||||||
// log the exception but continue locking text
|
|
||||||
statusHandler.handle(Priority.PROBLEM, "Error locking line: "
|
|
||||||
+ line + "\n", e);
|
|
||||||
}
|
|
||||||
sb.append(line + "\n");
|
|
||||||
insideLatLon = false;
|
|
||||||
insideTML = false;
|
|
||||||
}
|
|
||||||
String rval = sb.toString().trim();
|
|
||||||
|
|
||||||
// where a lock close and lock open are only separated by whitespace
|
|
||||||
// remove the close and open to join the two locked areas
|
|
||||||
rval = rval.replaceAll("</L>([\\s\\n\\r]*)<L>", "$1");
|
|
||||||
|
|
||||||
return rval;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String wrap(String str) {
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
|
|
||||||
boolean inLocations = false;
|
|
||||||
boolean first = true;
|
|
||||||
boolean inBullet = false;
|
|
||||||
String[] values = str.split("\n");
|
|
||||||
for (String v : values) {
|
|
||||||
String ignoreLockTags = v.replace(LOCK_START, "").replace(LOCK_END,
|
|
||||||
"");
|
|
||||||
if (ignoreLockTags.length() <= MAX_WIDTH) {
|
|
||||||
if (!first) {
|
|
||||||
sb.append("\n");
|
|
||||||
if (inBullet && !ignoreLockTags.startsWith(" ")) {
|
|
||||||
sb.append(" ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ignoreLockTags.startsWith("* ")) {
|
|
||||||
inBullet = true;
|
|
||||||
if (ignoreLockTags.startsWith("* LOCATIONS")) {
|
|
||||||
inLocations = true;
|
|
||||||
}
|
|
||||||
} else if (ignoreLockTags.trim().equals("")) {
|
|
||||||
inBullet = false;
|
|
||||||
inLocations = false;
|
|
||||||
}
|
|
||||||
sb.append(v);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Matcher m = null;
|
|
||||||
|
|
||||||
if (ignoreLockTags.startsWith("* ")) {
|
|
||||||
inBullet = true;
|
|
||||||
if (ignoreLockTags.startsWith("* LOCATIONS")) {
|
|
||||||
inLocations = true;
|
|
||||||
}
|
|
||||||
} else if (ignoreLockTags.startsWith("...")
|
|
||||||
&& ignoreLockTags.endsWith("...")) {
|
|
||||||
// headline found
|
|
||||||
// use line without lock tags because, lock tags adds to
|
|
||||||
// character count with doing a regex pattern
|
|
||||||
v = ignoreLockTags;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inLocations) {
|
|
||||||
sb.append("\n");
|
|
||||||
sb.append(wrapLocations(v));
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
m = ugcPtrn.matcher(v);
|
|
||||||
if (m.find()) {
|
|
||||||
m = hyphenWrapRE.matcher(v);
|
|
||||||
} else {
|
|
||||||
m = listOfAreaNamePtrn.matcher(v);
|
|
||||||
if (m.matches()) {
|
|
||||||
m = hyphenWrapRE.matcher(v);
|
|
||||||
} else {
|
|
||||||
m = wrapRE.matcher(v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (m.find()) {
|
|
||||||
String group = m.group().trim();
|
|
||||||
|
|
||||||
if (group.trim().length() == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.append("\n");
|
|
||||||
if (group.startsWith("* ") == false && inBullet) {
|
|
||||||
sb.append(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.append(group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String wrapLocations(String locationsLine) {
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
|
|
||||||
String line = " ";
|
|
||||||
String[] locations = locationsLine.split("\\.\\.\\.");
|
|
||||||
|
|
||||||
for (int i = 0; i < locations.length; i++) {
|
|
||||||
String location = locations[i];
|
|
||||||
int size = (i == locations.length - 1) ? location.length()
|
|
||||||
: location.length() + 3;
|
|
||||||
|
|
||||||
if (line.length() + size >= MAX_WIDTH - 2) {
|
|
||||||
sb.append(line + "\n");
|
|
||||||
line = " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == locations.length - 1) {
|
|
||||||
line += location;
|
|
||||||
} else {
|
|
||||||
line += location + "...";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.append(line + "\n");
|
|
||||||
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String removeExtraLines(String originalMessage) {
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
String[] seperatedLines = originalMessage.replaceAll("\r", "").trim()
|
|
||||||
.split("\n");
|
|
||||||
boolean blankLine = false;
|
|
||||||
for (String line : seperatedLines) {
|
|
||||||
if (line.replace(LOCK_START, "").replace(LOCK_END, "").trim()
|
|
||||||
.length() > 0) {
|
|
||||||
sb.append(line + "\n");
|
|
||||||
blankLine = false;
|
|
||||||
} else if (blankLine == false) {
|
|
||||||
sb.append(line + "\n");
|
|
||||||
blankLine = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.toString().trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue