sascha@2561: package de.intevation.flys.artifacts.model; sascha@2561: sascha@2561: import java.io.Serializable; sascha@2561: sascha@2561: import java.text.SimpleDateFormat; sascha@2561: sascha@2561: import java.util.ArrayList; sascha@2561: import java.util.Collections; sascha@2561: import java.util.Comparator; sascha@2561: import java.util.Date; sascha@2561: import java.util.List; sascha@2561: sascha@2561: import org.apache.log4j.Logger; sascha@2561: sascha@2561: import org.hibernate.SQLQuery; sascha@2561: import org.hibernate.Session; sascha@2561: sascha@2561: import org.hibernate.type.StandardBasicTypes; sascha@2561: sascha@2561: import org.w3c.dom.Document; sascha@2561: import org.w3c.dom.Element; sascha@2561: felix@5343: felix@5343: /** Generate Fixings Table chart. */ sascha@2561: public class FixingsOverview sascha@2561: implements Serializable sascha@2561: { sascha@2561: private static Logger log = Logger.getLogger(FixingsOverview.class); sascha@2561: sascha@3430: public static final double EPSILON = 1e-2; sascha@2561: sascha@2632: public static final String DATE_FORMAT = "dd.MM.yyyy"; sascha@2564: sascha@2561: public static final String SQL_RIVER_ID = sascha@2561: "SELECT" + sascha@2561: " id AS river_id," + sascha@2561: " km_up " + sascha@2561: "FROM rivers " + sascha@2561: "WHERE" + sascha@2561: " name = :name"; sascha@2561: felix@5725: /** All kind-2 wsts from given river. */ sascha@2561: public static final String SQL_FIXINGS = sascha@2561: "SELECT" + sascha@2561: " id AS wst_id," + sascha@2561: " description " + sascha@2561: "FROM wsts " + sascha@2561: "WHERE" + sascha@2561: " river_id = :river_id AND kind = 2"; sascha@2561: felix@5725: /** All columns from given wst. */ sascha@2561: public static final String SQL_FIXING_COLUMNS = sascha@2561: "SELECT" + sascha@2561: " wc.id AS wst_column_id," + sascha@2561: " ti.start_time AS start_time," + sascha@2561: " wc.name AS name " + sascha@2561: "FROM wst_columns wc" + sascha@2561: " JOIN time_intervals ti ON wc.time_interval_id = ti.id " + sascha@2561: "WHERE" + sascha@2561: " wc.wst_id = :wst_id " + sascha@2561: "ORDER BY position"; sascha@2561: sascha@2561: public static final String SQL_FIXING_COLUMN_Q_RANGES = sascha@2561: "SELECT" + sascha@2561: " wqr.q AS q," + sascha@2561: " r.a AS start_km," + sascha@2561: " r.b AS stop_km " + sascha@2561: "FROM wst_column_q_ranges wcqr" + sascha@2561: " JOIN wst_q_ranges wqr ON wcqr.wst_q_range_id = wqr.id" + sascha@2561: " JOIN ranges r ON wqr.range_id = r.id " + sascha@2561: "WHERE" + sascha@2561: " wcqr.wst_column_id = :column_id " + sascha@2561: "ORDER BY r.a"; sascha@2561: sascha@2561: public static final String SQL_FIXING_COLUMN_KM_RANGE = sascha@2561: "SELECT" + sascha@2561: " MIN(position) AS start_km," + sascha@2561: " MAX(position) AS stop_km " + sascha@2561: "FROM" + sascha@2561: " wst_column_values " + sascha@2562: "WHERE" + sascha@2561: " wst_column_id = :column_id"; sascha@2561: sascha@2561: sascha@2561: public static class QRange extends Range { sascha@2561: sascha@2561: protected double q; sascha@2561: sascha@2561: public QRange() { sascha@2561: } sascha@2561: sascha@2561: public QRange(double start, double end, double q) { sascha@2561: super(start, end); sascha@2561: this.q = q; sascha@2561: } sascha@2561: } // class QRange sascha@2561: sascha@2561: public static class SectorRange extends Range { sascha@2561: sascha@2561: protected int sector; sascha@2561: sascha@2561: public SectorRange() { sascha@2561: } sascha@2561: sascha@2562: public SectorRange(SectorRange other) { sascha@2562: start = other.start; sascha@2562: end = other.end; sascha@2562: sector = other.sector; sascha@2562: } sascha@2562: sascha@3401: public SectorRange(Range range) { sascha@3401: super(range); sascha@3401: } sascha@3401: sascha@2561: public SectorRange(double start, double end, int sector) { sascha@2561: super(start, end); sascha@2561: this.sector = sector; sascha@2561: } sascha@2561: sascha@2562: public int getSector() { sascha@2562: return sector; sascha@2562: } sascha@2562: sascha@3401: public void setSector(int sector) { sascha@3401: this.sector = sector; sascha@3401: } sascha@3401: sascha@2561: public boolean enlarge(SectorRange other) { sascha@2561: if (sector == other.sector sascha@3430: && Math.abs(end-other.start) < FixingsOverview.EPSILON) { sascha@2561: end = other.end; sascha@2561: return true; sascha@2561: } sascha@2561: return false; sascha@2561: } sascha@2561: } // class SectorRange sascha@2561: sascha@2561: public static class Fixing implements Serializable { sascha@2561: sascha@2561: public static final Comparator DATE_CMP = sascha@2561: new Comparator() { sascha@2561: @Override sascha@2561: public int compare(Column a, Column b) { sascha@2561: return a.startTime.compareTo(b.startTime); sascha@2561: } sascha@2561: }; sascha@2561: sascha@2563: public interface Filter { sascha@2563: sascha@2563: boolean accept(Column column); sascha@2563: sascha@2563: } // interface Filter sascha@2563: sascha@2561: public class Column extends Range { sascha@2561: sascha@2561: protected int columnId; sascha@2561: protected Date startTime; sascha@2561: protected String name; sascha@2561: sascha@2562: protected List sectors; sascha@2561: sascha@2561: public Column() { sascha@2561: } sascha@2561: sascha@2561: public Column(int columnId, Date startTime, String name) { sascha@2561: this.columnId = columnId; sascha@2561: this.startTime = startTime; sascha@2561: this.name = name; sascha@3076: sascha@2562: sectors = new ArrayList(); sascha@2561: } sascha@2561: sascha@2563: public int getId() { sascha@2563: return columnId; sascha@2563: } sascha@2563: sascha@2561: public Fixing getFixing() { sascha@2561: return Fixing.this; sascha@2561: } sascha@2561: sascha@2563: public Date getStartTime() { sascha@2563: return startTime; sascha@2563: } sascha@2563: sascha@2563: public String getName() { sascha@2563: return name; sascha@2563: } sascha@2563: sascha@2707: public String getDescription() { sascha@2707: return Fixing.this.description + "/" + name; sascha@2707: } sascha@2707: sascha@2562: public List getSectors() { sascha@2562: return sectors; sascha@2562: } sascha@2561: teichmann@5804: public boolean hasSectorsInRange(Range range) { teichmann@5804: for (SectorRange sector: sectors) { teichmann@5804: if (sector.intersects(range)) { teichmann@5804: return true; teichmann@5804: } teichmann@5804: } teichmann@5804: return false; teichmann@5804: } teichmann@5804: sascha@2563: public List getSectors(Range range) { sascha@2563: sascha@2563: List result = sascha@2563: new ArrayList(sectors.size()); sascha@2563: sascha@2563: for (SectorRange src: sectors) { sascha@2563: SectorRange dst = new SectorRange(src); sascha@2613: if (range == null || dst.clip(range)) { sascha@2563: result.add(dst); sascha@2563: } sascha@2563: } sascha@2563: sascha@2563: return result; sascha@2563: } sascha@2563: sascha@3002: public int findQSector(double km) { sascha@3002: for (SectorRange sector: sectors) { sascha@3002: if (sector.inside(km)) { sascha@3002: return sector.getSector(); sascha@3002: } sascha@3002: } sascha@3002: return -1; sascha@3002: } sascha@3002: sascha@3401: public void buildSectors( sascha@3401: GaugeFinder gaugeFinder, sascha@3401: List qRanges sascha@3401: ) { sascha@2561: for (QRange qRange: qRanges) { sascha@3401: for (GaugeRange gRange: gaugeFinder.getGauges()) { sascha@3401: SectorRange sector = new SectorRange(qRange); sascha@3401: if (!sector.clip(gRange)) { sascha@3401: continue; sascha@3401: } sascha@3401: sector.setSector(gRange.classify(qRange.q)); sascha@3401: sascha@3401: if (sectors.isEmpty() sascha@3401: || !sectors.get(sectors.size()-1).enlarge(sector)) { sascha@3401: sectors.add(sector); sascha@3401: } sascha@3401: } // for all gauges sascha@3401: } // for all Q ranges sascha@2561: } sascha@2561: sascha@2561: public void loadKmRange(SQLQuery query) { sascha@2561: query.setInteger("column_id", columnId); sascha@2561: sascha@2561: List kms = query.list(); sascha@2561: sascha@2561: if (kms.isEmpty()) { sascha@2561: log.warn("No km range for column " + columnId + "."); sascha@2561: } sascha@2561: else { sascha@2561: Object [] obj = kms.get(0); sascha@2561: start = (Double)obj[0]; sascha@2561: end = (Double)obj[1]; sascha@2561: } sascha@2561: } sascha@2561: sascha@2562: public void loadQRanges( sascha@2562: SQLQuery query, sascha@2562: GaugeFinder gaugeFinder sascha@2562: ) { sascha@2561: query.setInteger("column_id", columnId); sascha@2561: List list = query.list(); sascha@2561: sascha@2562: List qRanges = new ArrayList(list.size()); sascha@2562: sascha@2561: for (Object [] row: list) { sascha@2561: double q = (Double)row[0]; sascha@2561: double start = (Double)row[1]; sascha@2561: double end = (Double)row[2]; sascha@2561: QRange qRange = new QRange(start, end, q); sascha@2561: if (qRange.clip(this)) { sascha@2561: qRanges.add(qRange); sascha@2561: } sascha@2561: } sascha@2562: sascha@3401: buildSectors(gaugeFinder, qRanges); sascha@2561: } sascha@2561: } // class Column sascha@2561: sascha@2562: protected int wstId; sascha@2562: protected String description; sascha@2561: protected List columns; sascha@2561: sascha@2561: public Fixing() { sascha@2561: } sascha@2561: sascha@2563: public int getId() { sascha@2563: return wstId; sascha@2563: } sascha@2563: sascha@2563: public String getDescription() { sascha@2563: return description; sascha@2563: } sascha@2563: sascha@2561: public Fixing(int wstId, String description) { sascha@2561: this.wstId = wstId; sascha@2561: this.description = description; sascha@2561: columns = new ArrayList(); sascha@2561: } sascha@2561: sascha@2561: public void loadColumns(SQLQuery query) { sascha@2561: query.setInteger("wst_id", wstId); sascha@2561: List list = query.list(); sascha@2561: for (Object [] row: list) { sascha@2561: int columnId = (Integer)row[0]; sascha@2561: Date startTime = (Date) row[1]; sascha@2561: String name = (String) row[2]; sascha@2561: columns.add(new Column(columnId, startTime, name)); sascha@2561: } sascha@2561: } sascha@2561: sascha@2561: public void loadColumnsKmRange(SQLQuery query) { sascha@2561: for (Column column: columns) { sascha@2561: column.loadKmRange(query); sascha@2561: } sascha@2561: } sascha@2561: sascha@2565: public void adjustExtent(Range extent) { sascha@2565: for (Column column: columns) { sascha@2565: extent.extend(column); sascha@2565: } sascha@2565: } sascha@2565: sascha@2562: public void loadColumnsQRanges( sascha@2562: SQLQuery query, sascha@2562: GaugeFinder gaugeFinder sascha@2562: ) { sascha@2561: for (Column column: columns) { sascha@2562: column.loadQRanges(query, gaugeFinder); sascha@2561: } sascha@2561: } sascha@2561: felix@5725: /** felix@5725: * @param allColumns[out] Columns will be put here. felix@5725: * @param range can be null. felix@5725: * @param filter filter to apply. felix@5725: */ sascha@2563: public void addAllColumns( sascha@2563: List allColumns, sascha@2563: Range range, sascha@2563: Filter filter sascha@2563: ) { sascha@2562: for (Column column: columns) { teichmann@5804: if ((range == null || column.hasSectorsInRange(range)) sascha@3076: && (filter == null || filter.accept(column))) { sascha@2562: allColumns.add(column); sascha@2562: } sascha@2562: } sascha@2561: } sascha@2561: } // class Fixing sascha@2561: sascha@2561: sascha@2562: protected String riverName; sascha@2562: protected int riverId; sascha@2562: protected boolean isKmUp; sascha@2562: protected List fixings; sascha@2562: protected Range extent; sascha@2561: sascha@2561: public FixingsOverview() { sascha@2561: fixings = new ArrayList(); sascha@2565: extent = new Range(Double.MAX_VALUE, -Double.MAX_VALUE); sascha@2561: } sascha@2561: sascha@2561: public FixingsOverview(String riverName) { sascha@2561: this(); sascha@2561: this.riverName = riverName; sascha@2561: } sascha@2561: sascha@2561: protected boolean loadRiver(Session session) { sascha@2561: SQLQuery query = session.createSQLQuery(SQL_RIVER_ID) sascha@2561: .addScalar("river_id", StandardBasicTypes.INTEGER) sascha@2561: .addScalar("km_up", StandardBasicTypes.BOOLEAN); sascha@2561: sascha@2561: query.setString("name", riverName); sascha@2561: sascha@2561: List list = query.list(); sascha@2561: sascha@2561: if (list.isEmpty()) { sascha@2561: log.warn("No river '" + riverName + "' found."); sascha@2561: return false; sascha@2561: } sascha@2561: sascha@2561: Object [] row = list.get(0); sascha@2561: sascha@2561: riverId = (Integer)row[0]; sascha@2561: isKmUp = (Boolean)row[1]; sascha@2561: sascha@2561: return true; sascha@2561: } sascha@2561: sascha@2561: protected void loadFixings(Session session) { sascha@2561: SQLQuery query = session.createSQLQuery(SQL_FIXINGS) sascha@2561: .addScalar("wst_id", StandardBasicTypes.INTEGER) sascha@2561: .addScalar("description", StandardBasicTypes.STRING); sascha@2561: sascha@2561: query.setInteger("river_id", riverId); sascha@2561: sascha@2561: List list = query.list(); sascha@2561: sascha@2561: if (list.isEmpty()) { sascha@2561: log.warn("River " + riverId + " has no fixings."); sascha@2561: // Its pretty fine to have no fixings. sascha@2561: } sascha@2561: sascha@2561: for (Object [] row: list) { sascha@2561: int wstId = (Integer)row[0]; sascha@2561: String description = (String) row[1]; sascha@2561: Fixing fixing = new Fixing(wstId, description); sascha@2561: fixings.add(fixing); sascha@2561: } sascha@2561: } sascha@2561: sascha@2561: protected void loadFixingsColumns(Session session) { sascha@2561: SQLQuery query = session.createSQLQuery(SQL_FIXING_COLUMNS) sascha@2561: .addScalar("wst_column_id", StandardBasicTypes.INTEGER) sascha@2561: .addScalar("start_time", StandardBasicTypes.DATE) sascha@2561: .addScalar("name", StandardBasicTypes.STRING); sascha@2561: sascha@2561: for (Fixing fixing: fixings) { sascha@2561: fixing.loadColumns(query); sascha@2561: } sascha@2561: } sascha@2561: sascha@2561: protected void loadFixingsColumnsKmRange(Session session) { sascha@2561: SQLQuery query = session.createSQLQuery(SQL_FIXING_COLUMN_KM_RANGE) sascha@2561: .addScalar("start_km", StandardBasicTypes.DOUBLE) sascha@2561: .addScalar("stop_km", StandardBasicTypes.DOUBLE); sascha@2561: sascha@2561: for (Fixing fixing: fixings) { sascha@2561: fixing.loadColumnsKmRange(query); sascha@2561: } sascha@2561: } sascha@2561: sascha@2562: protected void loadFixingsColumnsQRanges( sascha@2562: Session session, sascha@2562: GaugeFinder gaugeFinder sascha@2562: ) { sascha@2561: SQLQuery query = session.createSQLQuery(SQL_FIXING_COLUMN_Q_RANGES) sascha@2561: .addScalar("q", StandardBasicTypes.DOUBLE) sascha@2561: .addScalar("start_km", StandardBasicTypes.DOUBLE) sascha@2561: .addScalar("stop_km", StandardBasicTypes.DOUBLE); sascha@2561: sascha@2561: for (Fixing fixing: fixings) { sascha@2562: fixing.loadColumnsQRanges(query, gaugeFinder); sascha@2561: } sascha@2561: } sascha@2561: sascha@2565: protected void adjustExtent() { sascha@2565: for (Fixing fixing: fixings) { sascha@2565: fixing.adjustExtent(extent); sascha@2565: } sascha@2565: } sascha@2565: sascha@2561: public boolean load(Session session) { sascha@2561: sascha@2565: if (!loadRiver(session)) { sascha@2561: return false; sascha@2561: } sascha@2561: sascha@3143: GaugeFinderFactory gff = GaugeFinderFactory.getInstance(); sascha@2561: sascha@3143: GaugeFinder gaugeFinder = gff.getGaugeFinder(riverId, isKmUp); sascha@3143: sascha@3143: if (gaugeFinder == null) { sascha@2561: return false; sascha@2561: } sascha@2561: sascha@2561: loadFixings(session); sascha@2561: loadFixingsColumns(session); sascha@2561: loadFixingsColumnsKmRange(session); sascha@2565: sascha@2565: adjustExtent(); sascha@2565: sascha@2562: loadFixingsColumnsQRanges(session, gaugeFinder); sascha@2561: sascha@2561: return true; sascha@2561: } sascha@2561: sascha@2563: public static final Range FULL_EXTENT = sascha@2562: new Range(-Double.MAX_VALUE, Double.MAX_VALUE); sascha@2562: sascha@2563: public static final Fixing.Filter ACCEPT = new Fixing.Filter() { sascha@2563: @Override sascha@2563: public boolean accept(Fixing.Column column) { sascha@2563: return true; sascha@2563: } sascha@2563: }; sascha@2563: sascha@2563: public static class NotFilter implements Fixing.Filter { sascha@2563: protected Fixing.Filter child; sascha@2563: sascha@2563: public NotFilter(Fixing.Filter child) { sascha@2563: this.child = child; sascha@2563: } sascha@2563: sascha@2563: @Override sascha@2563: public boolean accept(Fixing.Column column) { sascha@2563: return !child.accept(column); sascha@2563: } sascha@2563: } // class NotFilter sascha@2563: sascha@2563: public static abstract class ComponentFilter implements Fixing.Filter { sascha@2563: protected List children; sascha@2563: sascha@2744: public ComponentFilter() { sascha@2744: children = new ArrayList(); sascha@2744: } sascha@2744: sascha@2563: public ComponentFilter(List children) { sascha@2563: this.children = children; sascha@2563: } sascha@2744: sascha@3121: public ComponentFilter add(Fixing.Filter filter) { sascha@2744: children.add(filter); sascha@3121: return this; sascha@2744: } sascha@2563: } // class ComponentFilter sascha@2563: sascha@2563: public static class OrFilter extends ComponentFilter { sascha@2563: sascha@2744: public OrFilter() { sascha@2744: } sascha@2744: sascha@2563: public OrFilter(List children) { sascha@2563: super(children); sascha@2563: } sascha@2563: sascha@2563: @Override sascha@2563: public boolean accept(Fixing.Column column) { sascha@2563: for (Fixing.Filter child: children) { sascha@2563: if (child.accept(column)) { sascha@2563: return true; sascha@2563: } sascha@2563: } sascha@2563: return false; sascha@2563: } sascha@2563: } // class OrFilter sascha@2563: sascha@2563: public static class AndFilter extends ComponentFilter { sascha@2563: sascha@2744: public AndFilter() { sascha@2744: } sascha@2744: sascha@2563: public AndFilter(List children) { sascha@2563: super(children); sascha@2563: } sascha@2563: sascha@2563: @Override sascha@2563: public boolean accept(Fixing.Column column) { sascha@2563: for (Fixing.Filter child: children) { sascha@2563: if (!child.accept(column)) { sascha@2563: return false; sascha@2563: } sascha@2563: } sascha@2563: return true; sascha@2563: } sascha@2563: } // class AndFilter sascha@2563: sascha@2563: public static class IdFilter implements Fixing.Filter { sascha@2563: sascha@2563: protected int columnId; sascha@2563: sascha@2563: public IdFilter(int columnId) { sascha@2563: this.columnId = columnId; sascha@2563: } sascha@2563: sascha@2563: @Override sascha@2563: public boolean accept(Fixing.Column column) { sascha@2563: return column.getId() == columnId; sascha@2563: } sascha@2563: } // class IdFilter sascha@2563: felix@5725: /** Accept Fixing columns whose id is in id list. */ sascha@3121: public static class IdsFilter implements Fixing.Filter { sascha@3121: sascha@3121: protected int [] columnIds; sascha@3121: sascha@3121: public IdsFilter(int [] columnIds) { sascha@3121: this.columnIds = columnIds; sascha@3121: } sascha@3121: sascha@3121: @Override sascha@3121: public boolean accept(Fixing.Column column) { sascha@3121: int cid = column.getId(); sascha@3121: for (int i = columnIds.length-1; i >= 0; --i) { sascha@3121: if (columnIds[i] == cid) { sascha@3121: return true; sascha@3121: } sascha@3121: } sascha@3121: return false; sascha@3121: } sascha@3121: } // class IdFilter sascha@3121: sascha@2563: public static class DateFilter implements Fixing.Filter { sascha@2563: sascha@2563: protected Date date; sascha@2563: sascha@2563: public DateFilter(Date date) { sascha@2563: this.date = date; sascha@2563: } sascha@2563: sascha@2563: @Override sascha@2563: public boolean accept(Fixing.Column column) { sascha@2563: return date.equals(column.getStartTime()); sascha@2563: } sascha@2563: } // class DateFilter sascha@2563: sascha@2563: public static class DateRangeFilter implements Fixing.Filter { sascha@2563: sascha@2563: protected Date start; sascha@2563: protected Date end; sascha@2563: sascha@2563: public DateRangeFilter(Date start, Date end) { sascha@2563: this.start = start; sascha@2563: this.end = end; sascha@2563: } sascha@2563: sascha@2563: @Override sascha@2563: public boolean accept(Fixing.Column column) { sascha@2563: Date date = column.getStartTime(); sascha@2563: return start.compareTo(date) <= 0 && end.compareTo(date) >= 0; sascha@2563: } sascha@2563: } // class DateRangeFilter sascha@2563: sascha@3008: public static class SectorFilter implements Fixing.Filter { sascha@3008: sascha@3008: protected int sector; sascha@3008: sascha@3008: public SectorFilter(int sector) { sascha@3008: this.sector = sector; sascha@3008: } sascha@3008: sascha@3008: @Override sascha@3008: public boolean accept(Fixing.Column column) { sascha@3008: for (SectorRange s: column.getSectors()) { sascha@3008: if (s.getSector() == sector) { sascha@3008: return true; sascha@3008: } sascha@3008: } sascha@3008: return false; sascha@3008: } sascha@3008: } // class SectorFilter sascha@3008: sascha@2563: public static class SectorRangeFilter implements Fixing.Filter { sascha@2563: sascha@2563: protected int min; sascha@2563: protected int max; sascha@2563: sascha@2563: public SectorRangeFilter(int min, int max) { sascha@2563: this.min = Math.min(min, max); sascha@2563: this.max = Math.max(min, max); sascha@2563: } sascha@2563: sascha@2563: @Override sascha@2563: public boolean accept(Fixing.Column column) { sascha@2563: for (SectorRange s: column.getSectors()) { sascha@2563: int v = s.getSector(); felix@5153: if (v < min || v > max) { felix@5153: return false; sascha@2563: } sascha@2563: } felix@5153: return true; sascha@2563: } sascha@2563: } // class SectorRangeFilter sascha@2563: sascha@3006: public static class KmFilter implements Fixing.Filter { sascha@3006: sascha@3006: protected double km; sascha@3006: sascha@3006: public KmFilter(double km) { sascha@3006: this.km = km; sascha@3006: } sascha@3006: sascha@3006: @Override sascha@3006: public boolean accept(Fixing.Column column) { sascha@3006: for (SectorRange s: column.getSectors()) { sascha@3006: if (s.inside(km)) { sascha@3006: return true; sascha@3006: } sascha@3006: } sascha@3006: return false; sascha@3006: } sascha@3006: } // class KmFilter sascha@3006: sascha@2561: public void generateOverview(Document document) { sascha@2563: generateOverview(document, FULL_EXTENT, ACCEPT); sascha@2562: } sascha@2562: sascha@2608: public List filter(Range range, Fixing.Filter filter) { sascha@2561: List allColumns = new ArrayList(); sascha@2561: sascha@2561: for (Fixing fixing: fixings) { sascha@2563: fixing.addAllColumns(allColumns, range, filter); sascha@2561: } sascha@2561: sascha@2561: Collections.sort(allColumns, Fixing.DATE_CMP); sascha@2561: sascha@2608: return allColumns; sascha@2608: } sascha@2608: sascha@3421: protected static Range realRange(List columns) { sascha@3421: Range range = null; sascha@3421: for (Fixing.Column column: columns) { sascha@3421: if (range == null) { sascha@3421: range = new Range(column); sascha@3421: } sascha@3421: else { sascha@3421: range.extend(column); sascha@3421: } sascha@3421: } sascha@3421: return range; sascha@3421: } sascha@3421: sascha@3421: protected Element intersectingGauges(Document document, Range range) { sascha@3421: Element gauges = document.createElement("gauges"); sascha@3421: sascha@3421: if (range == null) { sascha@3421: return gauges; sascha@3421: } sascha@3421: sascha@3421: GaugeFinderFactory gff = GaugeFinderFactory.getInstance(); sascha@3421: sascha@3421: GaugeFinder gf = gff.getGaugeFinder(riverId, isKmUp); sascha@3421: sascha@3421: if (gf == null) { sascha@3421: return gauges; sascha@3421: } sascha@3421: sascha@3421: for (GaugeRange gr: gf.getGauges()) { sascha@3421: if (gr.intersects(range)) { sascha@3421: Element gauge = document.createElement("gauge"); sascha@3421: gauge.setAttribute("from", String.valueOf(gr.getStart())); sascha@3421: gauge.setAttribute("to", String.valueOf(gr.getEnd())); sascha@3421: gauge.setAttribute("name", gr.getName()); sascha@3421: gauges.appendChild(gauge); sascha@3421: } sascha@3421: } sascha@3421: sascha@3421: return gauges; sascha@3421: } sascha@3421: felix@5335: /** Populate document with fixings, filtered by range and filter. */ sascha@2608: public void generateOverview( sascha@2608: Document document, sascha@2608: Range range, sascha@2608: Fixing.Filter filter sascha@2608: ) { sascha@2608: List allColumns = filter(range, filter); sascha@2608: sascha@2561: Element fixingsElement = document.createElement("fixings"); sascha@2561: sascha@2561: Element riverElement = document.createElement("river"); sascha@2561: sascha@2561: riverElement.setAttribute("from", String.valueOf(extent.start)); sascha@2561: riverElement.setAttribute("to", String.valueOf(extent.end)); sascha@2561: riverElement.setAttribute("rid", String.valueOf(riverId)); sascha@2565: riverElement.setAttribute("name", riverName); sascha@2561: sascha@2561: fixingsElement.appendChild(riverElement); sascha@2561: sascha@3421: fixingsElement.appendChild( sascha@3421: intersectingGauges( sascha@3421: document, sascha@3421: realRange(allColumns))); sascha@3421: sascha@2564: SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT); sascha@2561: sascha@2561: Element esE = document.createElement("events"); sascha@2561: sascha@2561: for (Fixing.Column column: allColumns) { sascha@2561: sascha@2563: List sectors = column.getSectors(range); sascha@2561: sascha@2561: if (!sectors.isEmpty()) { sascha@2561: Element eE = document.createElement("event"); sascha@2707: eE.setAttribute("description", sascha@2707: String.valueOf(column.getDescription())); sascha@2561: eE.setAttribute("cid", String.valueOf(column.columnId)); sascha@2561: eE.setAttribute("date", df.format(column.startTime)); sascha@2561: sascha@2561: for (SectorRange sector: sectors) { sascha@2561: Element sE = document.createElement("sector"); sascha@2561: sascha@2561: sE.setAttribute("from", String.valueOf(sector.start)); sascha@2561: sE.setAttribute("to", String.valueOf(sector.end)); sascha@2561: sE.setAttribute("class", String.valueOf(sector.sector)); sascha@2561: sascha@2561: eE.appendChild(sE); sascha@2561: } sascha@2561: sascha@2561: esE.appendChild(eE); sascha@2561: } sascha@2561: } sascha@2561: sascha@2561: fixingsElement.appendChild(esE); sascha@2561: sascha@2561: document.appendChild(fixingsElement); sascha@2561: } sascha@2561: } sascha@2561: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :