Issue #2546 added fix for TAFs that contain legacy valid times
added unit test Former-commit-id: 6d33448f0f6962a3da2a5c51f27253173f40cb93
This commit is contained in:
parent
f0b386b632
commit
df1542a66c
3 changed files with 143 additions and 9 deletions
|
@ -34,15 +34,13 @@ import java.util.Set;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
|
|
||||||
import com.raytheon.edex.exception.DecoderException;
|
import com.raytheon.edex.exception.DecoderException;
|
||||||
import com.raytheon.edex.plugin.taf.common.ChangeGroup;
|
import com.raytheon.edex.plugin.taf.common.ChangeGroup;
|
||||||
import com.raytheon.edex.plugin.taf.common.TafPeriod;
|
import com.raytheon.edex.plugin.taf.common.TafPeriod;
|
||||||
import com.raytheon.edex.plugin.taf.common.TafRecord;
|
import com.raytheon.edex.plugin.taf.common.TafRecord;
|
||||||
import com.raytheon.uf.common.time.DataTime;
|
import com.raytheon.uf.common.time.DataTime;
|
||||||
import com.raytheon.uf.common.time.TimeRange;
|
import com.raytheon.uf.common.time.TimeRange;
|
||||||
|
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||||
import com.raytheon.uf.edex.decodertools.time.TimeTools;
|
import com.raytheon.uf.edex.decodertools.time.TimeTools;
|
||||||
import com.raytheon.uf.edex.wmo.message.WMOHeader;
|
import com.raytheon.uf.edex.wmo.message.WMOHeader;
|
||||||
|
|
||||||
|
@ -55,6 +53,7 @@ import com.raytheon.uf.edex.wmo.message.WMOHeader;
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Oct 20, 2008 1515 jkorman Initial implementation to
|
* Oct 20, 2008 1515 jkorman Initial implementation to
|
||||||
* add 30 Hour tafs.
|
* add 30 Hour tafs.
|
||||||
|
* Nov 12, 2013 2546 bclement added check for legacy valid time
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author jkorman
|
* @author jkorman
|
||||||
|
@ -90,6 +89,9 @@ public class TAFChangeGroupFactory {
|
||||||
|
|
||||||
private final Pattern PAT_VALID_TIME = Pattern.compile(VALID_TIME);
|
private final Pattern PAT_VALID_TIME = Pattern.compile(VALID_TIME);
|
||||||
|
|
||||||
|
private static final Pattern PAT_LEGACY_VALID_TIME = Pattern.compile("\\s"
|
||||||
|
+ DAY + HOUR + HOUR + "\\s");
|
||||||
|
|
||||||
private final Pattern PAT_PROB = Pattern.compile(PROB);
|
private final Pattern PAT_PROB = Pattern.compile(PROB);
|
||||||
|
|
||||||
private final Pattern PAT_TEMPO = Pattern.compile(TEMPO);
|
private final Pattern PAT_TEMPO = Pattern.compile(TEMPO);
|
||||||
|
@ -100,8 +102,6 @@ public class TAFChangeGroupFactory {
|
||||||
|
|
||||||
private final Pattern PAT_FM = Pattern.compile(FM);
|
private final Pattern PAT_FM = Pattern.compile(FM);
|
||||||
|
|
||||||
private final Log logger = LogFactory.getLog(getClass());
|
|
||||||
|
|
||||||
private Calendar issueTime = null;
|
private Calendar issueTime = null;
|
||||||
|
|
||||||
private String issueTimeString = null;
|
private String issueTimeString = null;
|
||||||
|
@ -165,17 +165,19 @@ public class TAFChangeGroupFactory {
|
||||||
if (locations.size() > 2) {
|
if (locations.size() > 2) {
|
||||||
stopPos = locations.get(0);
|
stopPos = locations.get(0);
|
||||||
}
|
}
|
||||||
|
String firstChunk = tafData.substring(startPos, stopPos);
|
||||||
Matcher m = PAT_VALID_TIME
|
Matcher m = PAT_VALID_TIME
|
||||||
.matcher(tafData.substring(startPos, stopPos));
|
.matcher(firstChunk);
|
||||||
if (m.find()) {
|
if (m.find()) {
|
||||||
startPos = m.start();
|
startPos = m.start();
|
||||||
stopPos = m.end();
|
stopPos = m.end();
|
||||||
locations.add(0, stopPos);
|
locations.add(0, stopPos);
|
||||||
locations.add(0, startPos);
|
locations.add(0, startPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
return locations;
|
return locations;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param tafData
|
* @param tafData
|
||||||
|
@ -288,10 +290,12 @@ public class TAFChangeGroupFactory {
|
||||||
* @param tafData
|
* @param tafData
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private List<TAFSubGroup> parse30HourTaf(String tafData)
|
private List<TAFSubGroup> parse30HourTaf(WMOHeader wmo, String tafData)
|
||||||
throws DecoderException {
|
throws DecoderException {
|
||||||
|
|
||||||
List<TAFSubGroup> groups = null;
|
List<TAFSubGroup> groups = null;
|
||||||
|
|
||||||
|
tafData = checkForLegacyFormat(wmo, tafData);
|
||||||
|
|
||||||
List<Integer> locations = findPositions(new StringBuilder(tafData));
|
List<Integer> locations = findPositions(new StringBuilder(tafData));
|
||||||
|
|
||||||
|
@ -331,6 +335,57 @@ public class TAFChangeGroupFactory {
|
||||||
}
|
}
|
||||||
return groups;
|
return groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert from legacy TAF format for valid times (DDHHHH) to the current
|
||||||
|
* extended format for valid times (DDHH/DDHH) if needed.
|
||||||
|
*
|
||||||
|
* @param wmo
|
||||||
|
* @param tafData
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected String checkForLegacyFormat(WMOHeader wmo, String tafData) {
|
||||||
|
Matcher m = PAT_LEGACY_VALID_TIME.matcher(tafData);
|
||||||
|
boolean isLegacy = m.find();
|
||||||
|
if (!isLegacy) {
|
||||||
|
return tafData;
|
||||||
|
}
|
||||||
|
StringBuilder rval = new StringBuilder();
|
||||||
|
int last = 0;
|
||||||
|
do {
|
||||||
|
int day1 = Integer.parseInt(m.group(1));
|
||||||
|
int day2 = day1;
|
||||||
|
int hr1 = Integer.parseInt(m.group(4));
|
||||||
|
int hr2 = Integer.parseInt(m.group(7));
|
||||||
|
if (hr2 == 24) {
|
||||||
|
// legacy format uses 00 for valid start but 24 for valid end
|
||||||
|
hr2 = 00;
|
||||||
|
}
|
||||||
|
if (hr2 <= hr1) {
|
||||||
|
// valid time crosses midnight
|
||||||
|
Calendar cal = wmo.getHeaderDate();
|
||||||
|
if (cal == null) {
|
||||||
|
// no month information in header, assume this month
|
||||||
|
cal = TimeUtil.newCalendar(TimeUtil.GMT_TIME_ZONE);
|
||||||
|
}
|
||||||
|
// cal may be set to a day different than the valid start
|
||||||
|
cal.set(Calendar.DAY_OF_MONTH, day1);
|
||||||
|
// handles month roll over
|
||||||
|
cal.add(Calendar.DAY_OF_MONTH, 1);
|
||||||
|
day2 = cal.get(Calendar.DAY_OF_MONTH);
|
||||||
|
}
|
||||||
|
// +1 to include preceding white space
|
||||||
|
rval.append(tafData.substring(last, m.start() + 1));
|
||||||
|
rval.append(String
|
||||||
|
.format("%02d%02d/%02d%02d", day1, hr1, day2,
|
||||||
|
hr2));
|
||||||
|
// -1 to include following white space
|
||||||
|
last = m.end() - 1;
|
||||||
|
} while (m.find());
|
||||||
|
// handle tail
|
||||||
|
rval.append(tafData.substring(last));
|
||||||
|
return rval.toString();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This processes the initial taf group containing the taf issue time, any
|
* This processes the initial taf group containing the taf issue time, any
|
||||||
|
@ -449,7 +504,7 @@ public class TAFChangeGroupFactory {
|
||||||
String testData = tafParts.getTafHeader() + tafParts.getTafBody();
|
String testData = tafParts.getTafHeader() + tafParts.getTafBody();
|
||||||
// *********************
|
// *********************
|
||||||
|
|
||||||
List<TAFSubGroup> groups = parse30HourTaf(testData);
|
List<TAFSubGroup> groups = parse30HourTaf(wmoHeader, testData);
|
||||||
if (groups != null) {
|
if (groups != null) {
|
||||||
List<ChangeGroup> changeGroups = null;
|
List<ChangeGroup> changeGroups = null;
|
||||||
|
|
||||||
|
@ -547,4 +602,5 @@ public class TAFChangeGroupFactory {
|
||||||
|
|
||||||
return record;
|
return record;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,5 +161,6 @@
|
||||||
<classpathentry kind="lib" path="lib/jetty-util-7.6.14.v20131031.jar"/>
|
<classpathentry kind="lib" path="lib/jetty-util-7.6.14.v20131031.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/servlet-api-2.5.jar"/>
|
<classpathentry kind="lib" path="lib/servlet-api-2.5.jar"/>
|
||||||
<classpathentry kind="lib" path="lib/jetty-security-7.6.14.v20131031.jar"/>
|
<classpathentry kind="lib" path="lib/jetty-security-7.6.14.v20131031.jar"/>
|
||||||
|
<classpathentry combineaccessrules="false" kind="src" path="/com.raytheon.edex.plugin.taf"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.edex.plugin.taf.decoder;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.raytheon.edex.esb.Headers;
|
||||||
|
import com.raytheon.uf.edex.decodertools.core.DecoderTools;
|
||||||
|
import com.raytheon.uf.edex.wmo.message.WMOHeader;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TAF change group parsing test
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Nov 13, 2013 bclement Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author bclement
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class TAFChangeGroupFactoryTest {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test conversion from legacy valid time format to extended TAF format
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testValidTimeReformat() {
|
||||||
|
final String input = "TAF SKCC 121000Z 121212 00000KT 9999 SCT018 SCT090\n"
|
||||||
|
+ " TEMPO 121213 8000 MIFG SCT017\n"
|
||||||
|
+ " TEMPO 300024 36007KT SCT023 PROB40 1219/1221 8000 DZRA\n"
|
||||||
|
+ " SCT018TCU\n" + " TEMPO 1300/1302 VCSH SCT017TCU\n"
|
||||||
|
+ " TEMPO 1310/1312 5000 BCFG SCT015 TX31/1218Z TN23/1311Z=";
|
||||||
|
|
||||||
|
final String expected = "TAF SKCC 121000Z 1212/1312 00000KT 9999 SCT018 SCT090\n"
|
||||||
|
+ " TEMPO 1212/1213 8000 MIFG SCT017\n"
|
||||||
|
+ " TEMPO 3000/0100 36007KT SCT023 PROB40 1219/1221 8000 DZRA\n"
|
||||||
|
+ " SCT018TCU\n"
|
||||||
|
+ " TEMPO 1300/1302 VCSH SCT017TCU\n"
|
||||||
|
+ " TEMPO 1310/1312 5000 BCFG SCT015 TX31/1218Z TN23/1311Z=";
|
||||||
|
|
||||||
|
TAFChangeGroupFactory factory = new TAFChangeGroupFactory();
|
||||||
|
final Headers headers = new Headers();
|
||||||
|
headers.put(DecoderTools.INGEST_FILE_NAME, "/tmp/sbn/manual/nctext/20131112/11/FTXX99_KWBC_121100_20738883.2013111211");
|
||||||
|
String result = factory.checkForLegacyFormat(new WMOHeader(
|
||||||
|
"FTXX99 KWBC 121100".getBytes(), headers), input);
|
||||||
|
Assert.assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue