Merge "Issue #1126 Refactored locking and wrapping Change-Id: I8053e8a8562eba9224a032c482f1cbca5af01df0" into development
Former-commit-id:82248ebbd0
[formerlyd29865eccc
] [formerly82248ebbd0
[formerlyd29865eccc
] [formerly51b63c1667
[formerly 4d389f0276dd843fac7fdf4d680be188a0ebf815]]] Former-commit-id:51b63c1667
Former-commit-id:0081b12244
[formerly6c1c43333b
] Former-commit-id:5fd0c87652
This commit is contained in:
commit
dee969da7d
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.WarngenLayer;
|
||||
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.FipsUtil;
|
||||
import com.raytheon.viz.warngen.util.FollowUpUtil;
|
||||
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.WeatherAdvisoryWatch;
|
||||
import com.raytheon.viz.warnings.DateUtil;
|
||||
|
@ -127,6 +128,7 @@ import com.vividsolutions.jts.io.WKTReader;
|
|||
* 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.
|
||||
* 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>
|
||||
*
|
||||
* @author njensen
|
||||
|
@ -760,16 +762,19 @@ public class TemplateRunner {
|
|||
System.out.println("velocity time: "
|
||||
+ (System.currentTimeMillis() - tz0));
|
||||
|
||||
return WarningTextHandler.handle(script.toString().toUpperCase(),
|
||||
areas, cancelareas, selectedAction,
|
||||
WarningAction.valueOf((String) context.get("action")),
|
||||
config.getAutoLockText());
|
||||
String text = script.toString();
|
||||
WarningTextHandler handler = WarningTextHandlerFactory.getHandler(
|
||||
selectedAction, text, config.getAutoLockText());
|
||||
String handledText = handler.handle(text, areas, cancelareas);
|
||||
|
||||
return handledText;
|
||||
}
|
||||
|
||||
private static VelocityEngine ENGINE = new VelocityEngine();
|
||||
|
||||
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();
|
||||
try {
|
||||
Properties p = new Properties();
|
||||
|
@ -780,8 +785,7 @@ public class TemplateRunner {
|
|||
p.setProperty(
|
||||
"velocimacro.permissions.allow.inline.to.replace.global",
|
||||
"true");
|
||||
p.setProperty("runtime.log",
|
||||
FileUtil.join(logDir, "velocity.log"));
|
||||
p.setProperty("runtime.log", FileUtil.join(logDir, "velocity.log"));
|
||||
ENGINE.init(p);
|
||||
context.put("scriptLibrary", "VM_global_library.vm");
|
||||
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;
|
||||
|
||||
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.GisUtil;
|
||||
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
|
||||
|
@ -64,8 +46,9 @@ public class FollowUpUtil {
|
|||
* This method checks whether a particular followup should be available
|
||||
* given a Warning Record, a vtec Action, and a template configuration
|
||||
*/
|
||||
public static boolean checkApplicable(String site, WarngenConfiguration config,
|
||||
AbstractWarningRecord record, WarningAction action) {
|
||||
public static boolean checkApplicable(String site,
|
||||
WarngenConfiguration config, AbstractWarningRecord record,
|
||||
WarningAction action) {
|
||||
|
||||
// Current Time
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
@ -91,14 +74,16 @@ public class FollowUpUtil {
|
|||
rval = true;
|
||||
}
|
||||
}
|
||||
if (action == WarningAction.COR && checkCorApplicable(site, config, record)) {
|
||||
if (action == WarningAction.COR
|
||||
&& checkCorApplicable(site, config, record)) {
|
||||
rval = true;
|
||||
}
|
||||
}
|
||||
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 allowsCORProduct = false;
|
||||
for (String s : config.getFollowUps()) {
|
||||
|
@ -115,7 +100,8 @@ public class FollowUpUtil {
|
|||
}
|
||||
|
||||
CurrentWarnings cw = CurrentWarnings.getInstance(site);
|
||||
List<AbstractWarningRecord> correctableWarnings = cw.getCorrectableWarnings(warnRec);
|
||||
List<AbstractWarningRecord> correctableWarnings = cw
|
||||
.getCorrectableWarnings(warnRec);
|
||||
|
||||
boolean wasContinued = false;
|
||||
for (AbstractWarningRecord w : correctableWarnings) {
|
||||
|
@ -125,8 +111,8 @@ public class FollowUpUtil {
|
|||
}
|
||||
|
||||
// Adding a COR option for continuation follow ups
|
||||
if (correctableWarnings.isEmpty() == false && ((allowsCONProduct && wasContinued)
|
||||
|| (allowsCONProduct == false && wasContinued == false))) {
|
||||
if (correctableWarnings.isEmpty() == false
|
||||
&& ((allowsCONProduct && wasContinued) || (allowsCONProduct == false && wasContinued == false))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -134,8 +120,9 @@ public class FollowUpUtil {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the raw message of the record but removes
|
||||
* the first wmoid and the pil (the first two lines of the warning)
|
||||
* Returns the raw message of the record but removes the first wmoid and the
|
||||
* pil (the first two lines of the warning)
|
||||
*
|
||||
* @param record
|
||||
* @return
|
||||
*/
|
||||
|
@ -172,22 +159,24 @@ public class FollowUpUtil {
|
|||
|
||||
/**
|
||||
* Returns a list of the canceled areas from the original text
|
||||
*
|
||||
* @param originalText
|
||||
* @return
|
||||
*/
|
||||
public static ArrayList<AffectedAreas> canceledAreasFromText(String originalText) {
|
||||
public static ArrayList<AffectedAreas> canceledAreasFromText(
|
||||
String originalText) {
|
||||
boolean ugcdone = false;
|
||||
boolean namedone = false;
|
||||
boolean insideHeadline = false;
|
||||
String ugcLine = "";
|
||||
String namesLine = "";
|
||||
String headline = "";
|
||||
Pattern ugcPtrn = Pattern.compile(ICommonPatterns.ugc);
|
||||
for (String line : originalText.trim().split("\n")) {
|
||||
if (line.contains("TEST") || line.trim().length() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Matcher m = WarningTextHandler.ugcPtrn.matcher(line);
|
||||
Matcher m = ugcPtrn.matcher(line);
|
||||
if (!ugcdone && m.find()) {
|
||||
ugcLine += m.group();
|
||||
continue;
|
||||
|
@ -195,7 +184,7 @@ public class FollowUpUtil {
|
|||
ugcdone = true;
|
||||
}
|
||||
|
||||
m = WarningTextHandler.listOfAreaNamePtrn.matcher(line);
|
||||
m = ICommonPatterns.listOfAreaNamePtrn.matcher(line);
|
||||
if (!namedone && m.find()) {
|
||||
namesLine += m.group();
|
||||
continue;
|
||||
|
@ -209,7 +198,7 @@ public class FollowUpUtil {
|
|||
} else if (insideHeadline) {
|
||||
|
||||
if (line.trim().endsWith("...")) {
|
||||
headline += line.substring(0,line.length() - 3);
|
||||
headline += line.substring(0, line.length() - 3);
|
||||
insideHeadline = false;
|
||||
break;
|
||||
}
|
||||
|
@ -232,7 +221,7 @@ public class FollowUpUtil {
|
|||
AffectedAreas affectedArea = new AffectedAreas();
|
||||
String ugc = ugcs[i].trim();
|
||||
if (ugc.length() == 6) {
|
||||
stateAbbreviation = ugc.substring(0,2);
|
||||
stateAbbreviation = ugc.substring(0, 2);
|
||||
if (ugc.charAt(2) == 'Z') {
|
||||
areaNotation = "ZONE";
|
||||
areasNotation = "ZONES";
|
||||
|
@ -245,13 +234,14 @@ public class FollowUpUtil {
|
|||
fips = ugc.substring(ugc.length() - 3);
|
||||
|
||||
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) {
|
||||
for (String area : areas) {
|
||||
if (area.contains(name)) {
|
||||
EnumSet<Direction> set = EnumSet.noneOf(Direction.class);
|
||||
EnumSet<Direction> set = EnumSet
|
||||
.noneOf(Direction.class);
|
||||
for (Direction direction : Direction.values()) {
|
||||
if (area.contains(direction.name())) {
|
||||
set.add(direction);
|
||||
|
@ -277,8 +267,9 @@ public class FollowUpUtil {
|
|||
|
||||
public static String getUgcLineCanFromText(String originalText) {
|
||||
String ugcLine = "";
|
||||
Pattern ugcPtrn = Pattern.compile(ICommonPatterns.ugc);
|
||||
for (String line : originalText.trim().split("\n")) {
|
||||
Matcher m = WarningTextHandler.ugcPtrn.matcher(line);
|
||||
Matcher m = ugcPtrn.matcher(line);
|
||||
if (m.find()) {
|
||||
ugcLine += line;
|
||||
continue;
|
||||
|
|
|
@ -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