/**
* 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.uf.edex.activetable;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import com.raytheon.edex.esb.Headers;
import com.raytheon.uf.common.activetable.ActiveTableMode;
import com.raytheon.uf.common.activetable.ActiveTableRecord;
import com.raytheon.uf.common.activetable.OperationalActiveTableRecord;
import com.raytheon.uf.common.activetable.PracticeActiveTableRecord;
import com.raytheon.uf.common.dataplugin.warning.AbstractWarningRecord;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.PerformanceStatus;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.time.util.ITimer;
import com.raytheon.uf.common.time.util.TimeUtil;
/**
* Service for the VTEC active table. Determines if the VTEC product corresponds
* to a site we want in the active table, and if so, updates the active table.
*
*
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------- -------- --------- --------------------------------------------
* Mar 17, 2009 njensen Initial creation
* Jul 14, 2009 2950 njensen Multiple site support
* Dec 21, 2009 4055 njensen No site filtering
* Jun 17, 2014 3296 randerso Added performance logging
* Dec 09, 2014 3885 dgilling Handle offset time from camel route headers.
* Nov 03, 2016 5934 randerso Moved transformFromWarnings method to
* ActiveTableSrv
* Sep 25, 2017 6449 randerso Changed to convert operational warnings to
* active table records before sending to
* vtecArrived. Made sure all active table
* records share a single instance of the
* rawMessage.
*
*
*
* @author njensen
*/
public class ActiveTableSrv {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(ActiveTableSrv.class);
private static ThreadLocal threadLocalActiveTable = new ThreadLocal() {
/*
* (non-Javadoc)
*
* @see java.lang.ThreadLocal#initialValue()
*/
@Override
protected ActiveTable initialValue() {
return new ActiveTable();
}
};
/**
* Merge VTEC info from new warning records into the active table
*
* @param records
*/
public void vtecArrived(List records) {
ITimer timer = TimeUtil.getTimer();
timer.start();
try {
ActiveTable activeTable = threadLocalActiveTable.get();
if ((records != null) && (records.size() > 0)) {
activeTable.merge(records);
}
} catch (Throwable t) {
statusHandler.handle(Priority.PROBLEM, "Error merging active table",
t);
}
timer.stop();
PerformanceStatus.getHandler("ActiveTable").logDuration(
"Total time to process " + records.size() + " records",
timer.getElapsedTime());
}
/**
* Merge new warning records into the practice active table
*
* @param records
* @param headers
*/
public void practiceVtecArrived(List records,
Headers headers) {
int offsetSeconds = getOffsetTime((String) headers.get("drtstring"));
if ((records != null) && (records.size() > 0)) {
ActiveTable activeTable = threadLocalActiveTable.get();
try {
activeTable.merge(transformFromWarnings(records,
ActiveTableMode.PRACTICE), offsetSeconds);
} catch (Throwable t) {
statusHandler.handle(Priority.PROBLEM,
"Error processing new VTEC products for PRACTICE active table",
t);
}
}
}
private int getOffsetTime(String drtTimeString) {
if (drtTimeString != null) {
DateFormat drtParse = new SimpleDateFormat("yyyyMMdd_HHmm");
drtParse.setTimeZone(TimeZone.getTimeZone("GMT"));
try {
Date drtTime = drtParse.parse(drtTimeString);
Date currentTime = new Date();
long diffInMillis = drtTime.getTime() - currentTime.getTime();
return (int) TimeUnit.SECONDS.convert(diffInMillis,
TimeUnit.MILLISECONDS);
} catch (ParseException e) {
statusHandler.error(
"Could not parse DRT time string: " + drtTimeString, e);
}
}
return 0;
}
/**
* Transform warning records to operational active table records
*
* @param warnings
* @return list of active table records
*/
public List transformFromOperationalWarnings(
List warnings) {
return transformFromWarnings(warnings, ActiveTableMode.OPERATIONAL);
}
private List transformFromWarnings(
List warnings, ActiveTableMode mode) {
List list = new ArrayList<>();
String rawMessage = null;
/*
* All warning records in the list will have the same rawMessage since
* they were all decoded from the same product.
*
* Save off the value from the first record here and use it to populate
* the active table records so they all share a single Java String
* instance.
*/
if (!warnings.isEmpty()) {
rawMessage = warnings.get(0).getRawmessage();
}
for (AbstractWarningRecord wr : warnings) {
ActiveTableRecord atr = null;
if (mode.equals(ActiveTableMode.OPERATIONAL)) {
atr = new OperationalActiveTableRecord();
} else {
atr = new PracticeActiveTableRecord();
}
atr.setAct(wr.getAct());
atr.setCountyheader(wr.getCountyheader());
atr.setEndTime(calendarToDate(wr.getEndTime()));
atr.setEtn(wr.getEtn());
atr.setFloodBegin(calendarToDate(wr.getFloodBegin()));
atr.setFloodCrest(calendarToDate(wr.getFloodCrest()));
atr.setFloodEnd(calendarToDate(wr.getFloodEnd()));
atr.setFloodRecordStatus(wr.getFloodRecordStatus());
atr.setFloodSeverity(wr.getFloodSeverity());
atr.setForecaster(wr.getForecaster());
atr.setImmediateCause(wr.getImmediateCause());
atr.setIssueTime(calendarToDate(wr.getIssueTime()));
atr.setLoc(wr.getLoc());
atr.setLocationID(wr.getLocationID());
atr.setMotdir(wr.getMotdir());
atr.setMotspd(wr.getMotspd());
atr.setOfficeid(wr.getOfficeid());
atr.setOverviewText(wr.getOverviewText());
atr.setPhen(wr.getPhen());
atr.setPhensig(wr.getPhensig());
atr.setPil(wr.getPil());
atr.setProductClass(wr.getProductClass());
atr.setPurgeTime(calendarToDate(wr.getPurgeTime()));
atr.setRawmessage(rawMessage);
atr.setRegion(wr.getRegion());
atr.setSeg(wr.getSeg());
atr.setSegText(wr.getSegText());
atr.setSig(wr.getSig());
atr.setStartTime(calendarToDate(wr.getStartTime()));
atr.setUfn(wr.isUfn());
atr.setVtecstr(wr.getVtecstr());
atr.setWmoid(wr.getWmoid());
atr.setXxxid(wr.getXxxid());
for (String ugc : wr.getUgcZones()) {
ActiveTableRecord ugcRecord = (ActiveTableRecord) atr.clone();
ugcRecord.setUgcZone(ugc);
list.add(ugcRecord);
}
}
return list;
}
private static Date calendarToDate(Calendar calendar) {
Date date = null;
if (calendar != null) {
date = calendar.getTime();
}
return date;
}
}