From df1542a66c30e36074b90fb65046875a284b49aa Mon Sep 17 00:00:00 2001 From: Brian Clements Date: Tue, 12 Nov 2013 16:58:33 -0600 Subject: [PATCH] Issue #2546 added fix for TAFs that contain legacy valid times added unit test Former-commit-id: 6d33448f0f6962a3da2a5c51f27253173f40cb93 --- .../taf/decoder/TAFChangeGroupFactory.java | 74 +++++++++++++++--- tests/.classpath | 1 + .../decoder/TAFChangeGroupFactoryTest.java | 77 +++++++++++++++++++ 3 files changed, 143 insertions(+), 9 deletions(-) create mode 100644 tests/unit/com/raytheon/edex/plugin/taf/decoder/TAFChangeGroupFactoryTest.java diff --git a/edexOsgi/com.raytheon.edex.plugin.taf/src/com/raytheon/edex/plugin/taf/decoder/TAFChangeGroupFactory.java b/edexOsgi/com.raytheon.edex.plugin.taf/src/com/raytheon/edex/plugin/taf/decoder/TAFChangeGroupFactory.java index 0d008824ad..d521b37157 100644 --- a/edexOsgi/com.raytheon.edex.plugin.taf/src/com/raytheon/edex/plugin/taf/decoder/TAFChangeGroupFactory.java +++ b/edexOsgi/com.raytheon.edex.plugin.taf/src/com/raytheon/edex/plugin/taf/decoder/TAFChangeGroupFactory.java @@ -34,15 +34,13 @@ import java.util.Set; import java.util.regex.Matcher; 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.plugin.taf.common.ChangeGroup; import com.raytheon.edex.plugin.taf.common.TafPeriod; import com.raytheon.edex.plugin.taf.common.TafRecord; import com.raytheon.uf.common.time.DataTime; 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.wmo.message.WMOHeader; @@ -55,6 +53,7 @@ import com.raytheon.uf.edex.wmo.message.WMOHeader; * ------------ ---------- ----------- -------------------------- * Oct 20, 2008 1515 jkorman Initial implementation to * add 30 Hour tafs. + * Nov 12, 2013 2546 bclement added check for legacy valid time * * * @author jkorman @@ -90,6 +89,9 @@ public class TAFChangeGroupFactory { 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_TEMPO = Pattern.compile(TEMPO); @@ -100,8 +102,6 @@ public class TAFChangeGroupFactory { private final Pattern PAT_FM = Pattern.compile(FM); - private final Log logger = LogFactory.getLog(getClass()); - private Calendar issueTime = null; private String issueTimeString = null; @@ -165,17 +165,19 @@ public class TAFChangeGroupFactory { if (locations.size() > 2) { stopPos = locations.get(0); } + String firstChunk = tafData.substring(startPos, stopPos); Matcher m = PAT_VALID_TIME - .matcher(tafData.substring(startPos, stopPos)); + .matcher(firstChunk); if (m.find()) { startPos = m.start(); stopPos = m.end(); locations.add(0, stopPos); locations.add(0, startPos); } + return locations; } - + /** * * @param tafData @@ -288,10 +290,12 @@ public class TAFChangeGroupFactory { * @param tafData * @return */ - private List parse30HourTaf(String tafData) + private List parse30HourTaf(WMOHeader wmo, String tafData) throws DecoderException { List groups = null; + + tafData = checkForLegacyFormat(wmo, tafData); List locations = findPositions(new StringBuilder(tafData)); @@ -331,6 +335,57 @@ public class TAFChangeGroupFactory { } 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 @@ -449,7 +504,7 @@ public class TAFChangeGroupFactory { String testData = tafParts.getTafHeader() + tafParts.getTafBody(); // ********************* - List groups = parse30HourTaf(testData); + List groups = parse30HourTaf(wmoHeader, testData); if (groups != null) { List changeGroups = null; @@ -547,4 +602,5 @@ public class TAFChangeGroupFactory { return record; } + } diff --git a/tests/.classpath b/tests/.classpath index 13e4b6f88b..a1e2615423 100644 --- a/tests/.classpath +++ b/tests/.classpath @@ -161,5 +161,6 @@ + diff --git a/tests/unit/com/raytheon/edex/plugin/taf/decoder/TAFChangeGroupFactoryTest.java b/tests/unit/com/raytheon/edex/plugin/taf/decoder/TAFChangeGroupFactoryTest.java new file mode 100644 index 0000000000..1cc384b6ab --- /dev/null +++ b/tests/unit/com/raytheon/edex/plugin/taf/decoder/TAFChangeGroupFactoryTest.java @@ -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 + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Nov 13, 2013            bclement     Initial creation
+ * 
+ * 
+ * + * @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); + } + +}