sascha@4077: package de.intevation.aft;
sascha@4077: 
sascha@4077: import de.intevation.db.ConnectedStatements;
sascha@4077: 
teichmann@4772: import java.sql.ResultSet;
teichmann@4772: import java.sql.SQLException;
teichmann@4772: 
teichmann@4772: import java.util.Date;
teichmann@4772: import java.util.HashMap;
teichmann@4772: import java.util.Map;
teichmann@4772: import java.util.TreeMap;
sascha@4084: 
sascha@4084: import org.apache.log4j.Logger;
sascha@4077: 
teichmann@4772: import org.w3c.dom.Document;
teichmann@4772: import org.w3c.dom.Element;
teichmann@4772: import org.w3c.dom.NodeList;
teichmann@4772: 
sascha@4077: public class SyncContext
sascha@4077: {
sascha@4084:     private static Logger log = Logger.getLogger(SyncContext.class);
sascha@4084: 
sascha@4090:     protected ConnectedStatements             aftStatements;
sascha@4090:     protected ConnectedStatements             flysStatements;
sascha@4090:     protected Document                        dips;
sascha@4090: 
sascha@4090:     protected Map<Long, DIPSGauge>            numberToGauge;
sascha@4090:     protected Map<TimeInterval, TimeInterval> flysTimeIntervals;
sascha@4077: 
sascha@4077:     public SyncContext() {
sascha@4077:     }
sascha@4077: 
sascha@4077:     public SyncContext(
sascha@4077:         ConnectedStatements aftStatements,
sascha@4077:         ConnectedStatements flysStatements,
sascha@4077:         Document            dips
sascha@4077:     ) {
sascha@4077:         this.aftStatements  = aftStatements;
sascha@4077:         this.flysStatements = flysStatements;
sascha@4077:         this.dips           = dips;
sascha@4089:     }
sascha@4089: 
sascha@4089:     public void init() throws SQLException {
sascha@4084:         numberToGauge       = indexByNumber(dips);
sascha@4089:         flysTimeIntervals   = loadTimeIntervals();
sascha@4077:     }
sascha@4077: 
sascha@4077:     public ConnectedStatements getAftStatements() {
sascha@4077:         return aftStatements;
sascha@4077:     }
sascha@4077: 
sascha@4077:     public void setAftStatements(ConnectedStatements aftStatements) {
sascha@4077:         this.aftStatements = aftStatements;
sascha@4077:     }
sascha@4077: 
sascha@4077:     public ConnectedStatements getFlysStatements() {
sascha@4077:         return flysStatements;
sascha@4077:     }
sascha@4077: 
sascha@4077:     public void setFlysStatements(ConnectedStatements flysStatements) {
sascha@4077:         this.flysStatements = flysStatements;
sascha@4077:     }
sascha@4077: 
sascha@4077:     public Document getDips() {
sascha@4077:         return dips;
sascha@4077:     }
sascha@4077: 
sascha@4077:     public void setDips(Document dips) {
sascha@4077:         this.dips = dips;
sascha@4077:     }
sascha@4077: 
sascha@4077:     void close() {
sascha@4077:         aftStatements.close();
sascha@4077:         flysStatements.close();
sascha@4077:     }
sascha@4084: 
sascha@4084:     public static Long numberToLong(String s) {
sascha@4084:         try {
sascha@4084:             return Long.valueOf(s.trim());
sascha@4084:         }
sascha@4084:         catch (NumberFormatException nfe) {
sascha@4084:         }
sascha@4084:         return null;
sascha@4084:     }
sascha@4084: 
sascha@4084:     public Map<Long, DIPSGauge> getDIPSGauges() {
sascha@4084:         return numberToGauge;
sascha@4084:     }
sascha@4084: 
teichmann@5188:     public Map<Long, DIPSGauge> getDIPSGauges(
teichmann@5188:         String riverName,
teichmann@5188:         double from,
teichmann@5188:         double to
teichmann@5188:     ) {
teichmann@5188:         if (from > to) {
teichmann@5188:             double t = from;
teichmann@5188:             from = to;
teichmann@5188:             to = t;
teichmann@5188:         }
teichmann@5188: 
teichmann@5188:         riverName = riverName.toLowerCase();
teichmann@5188: 
teichmann@5188:         Map<Long, DIPSGauge> result = new HashMap<Long, DIPSGauge>();
teichmann@5188: 
teichmann@5188:         for (Map.Entry<Long, DIPSGauge> entry: numberToGauge.entrySet()) {
teichmann@5188:             DIPSGauge gauge = entry.getValue();
teichmann@5188:             // XXX: Maybe a bit too sloppy.
teichmann@5188:             if (!riverName.contains(gauge.getRiverName().toLowerCase())) {
teichmann@5188:                 continue;
teichmann@5188:             }
teichmann@5188:             double station = gauge.getStation();
teichmann@5188:             if (station >= from && station <= to) {
teichmann@5188:                 result.put(entry.getKey(), gauge);
teichmann@5188:             }
teichmann@5188:         }
teichmann@5188: 
teichmann@5188:         return result;
teichmann@5188:     }
teichmann@5188: 
sascha@4084:     protected static Map<Long, DIPSGauge> indexByNumber(Document document) {
sascha@4084:         Map<Long, DIPSGauge> map = new HashMap<Long, DIPSGauge>();
sascha@4084:         NodeList nodes = document.getElementsByTagName("PEGELSTATION");
sascha@4084:         for (int i = nodes.getLength()-1; i >= 0; --i) {
sascha@4084:             Element element = (Element)nodes.item(i);
sascha@4084:             String numberString = element.getAttribute("NUMMER");
sascha@4084:             Long number = numberToLong(numberString);
sascha@4084:             if (number != null) {
sascha@4084:                 DIPSGauge newG = new DIPSGauge(element);
sascha@4084:                 DIPSGauge oldG = map.put(number, newG);
sascha@4084:                 if (oldG != null) {
sascha@4084:                     log.warn("DIPS: '" + newG.getName() +
teichmann@4736:                         "' collides with '" + oldG.getName() +
sascha@4084:                         "' on gauge number " + number + ".");
sascha@4084:                 }
sascha@4084:             }
sascha@4084:             else {
sascha@4110:                 log.warn("DIPS: Gauge '" + element.getAttribute("NAME") +
sascha@4110:                     "' has invalid gauge number '" + numberString + "'.");
sascha@4084:             }
sascha@4084:         }
sascha@4084:         return map;
sascha@4084:     }
sascha@4084: 
teichmann@4736:     protected Map<TimeInterval, TimeInterval> loadTimeIntervals()
sascha@4090:     throws SQLException {
sascha@4089: 
sascha@4089:         boolean debug = log.isDebugEnabled();
sascha@4089: 
sascha@4090:         Map<TimeInterval, TimeInterval> intervals =
sascha@4090:             new TreeMap<TimeInterval, TimeInterval>();
sascha@4090: 
teichmann@4771:         ResultSet rs = flysStatements
teichmann@4771:             .getStatement("select.timeintervals")
teichmann@4771:             .executeQuery();
teichmann@4736: 
sascha@4089:         try {
sascha@4089:             while (rs.next()) {
sascha@4089:                 int  id    = rs.getInt("id");
sascha@4089:                 Date start = rs.getDate("start_time");
sascha@4089:                 Date stop  = rs.getDate("stop_time");
sascha@4089: 
sascha@4089:                 if (debug) {
sascha@4089:                     log.debug("id:    " + id);
sascha@4089:                     log.debug("start: " + start);
sascha@4089:                     log.debug("stop:  " + stop);
sascha@4089:                 }
sascha@4089: 
sascha@4089:                 TimeInterval ti = new TimeInterval(id, start, stop);
sascha@4090:                 intervals.put(ti, ti);
sascha@4089:             }
sascha@4089:         }
sascha@4089:         finally {
teichmann@4771:             rs.close();
sascha@4089:         }
sascha@4089: 
sascha@4089:         if (debug) {
sascha@4089:             log.debug("loaded time intervals: " + intervals.size());
sascha@4089:         }
sascha@4089: 
sascha@4089:         return intervals;
sascha@4089:     }
sascha@4089: 
sascha@4090:     public TimeInterval fetchOrCreateFLYSTimeInterval(TimeInterval key)
sascha@4090:     throws SQLException
sascha@4090:     {
sascha@4090:         TimeInterval old = flysTimeIntervals.get(key);
sascha@4090:         if (old != null) {
sascha@4090:             return old;
sascha@4090:         }
sascha@4090: 
teichmann@4771:         ResultSet rs = flysStatements
teichmann@4771:             .getStatement("next.timeinterval.id")
teichmann@4771:             .executeQuery();
teichmann@4771: 
sascha@4090:         try {
sascha@4090:             rs.next();
sascha@4090:             key.setId(rs.getInt("time_interval_id"));
sascha@4090:         }
sascha@4090:         finally {
teichmann@4771:             rs.close();
sascha@4090:         }
sascha@4090: 
teichmann@4771:         if (log.isDebugEnabled()) {
teichmann@4771:             log.debug("FLYS: Created time interval id: " + key.getId());
teichmann@4771:             log.debug("FLYS: " + key);
teichmann@4771:         }
teichmann@4771: 
teichmann@4771:         flysStatements.getStatement("insert.timeinterval")
teichmann@4771:             .clearParameters()
teichmann@4771:             .setInt("id", key.getId())
teichmann@4771:             .setObject("start_time", key.getStart())
teichmann@4771:             .setObject("stop_time", key.getStop())
teichmann@4771:             .execute();
teichmann@4771: 
sascha@4090:         flysTimeIntervals.put(key, key);
sascha@4090: 
sascha@4090:         return key;
sascha@4090:     }
sascha@4077: }
sascha@4077: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :