Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTableFactory.java @ 443:5d65fe4c08d5
Separated the WST table loading logic from the calculations.
flys-artifacts/trunk@1931 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Tue, 17 May 2011 08:55:38 +0000 |
parents | |
children | 523a256451cd |
line wrap: on
line source
package de.intevation.flys.artifacts.model; import java.io.Serializable; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Collections; import org.hibernate.Session; import org.hibernate.Query; import org.hibernate.SQLQuery; import org.hibernate.type.StandardBasicTypes; import net.sf.ehcache.Cache; import net.sf.ehcache.Element; import org.apache.log4j.Logger; import de.intevation.flys.model.River; import de.intevation.flys.model.Wst; import de.intevation.flys.model.WstColumn; import de.intevation.flys.artifacts.cache.CacheFactory; import de.intevation.flys.backend.SessionHolder; public class WstValueTableFactory { private static Logger log = Logger.getLogger(WstValueTableFactory.class); public static final String CACHE_NAME = "wst-value-table"; // TODO: put this into a property file public static final String SQL_POS_WQ = "SELECT position, w, q, column_pos" + " FROM wst_value_table" + " WHERE wst_id = :wst_id"; public static final class CacheKey implements Serializable { private int riverId; private int kind; public CacheKey(int riverId, int kind) { this.riverId = riverId; this.kind = kind; } public int hashCode() { return (riverId << 8) | kind; } public boolean equals(Object other) { if (!(other instanceof CacheKey)) { return false; } CacheKey o = (CacheKey)other; return riverId == o.riverId && kind == o.kind; } } // class CacheKey private WstValueTableFactory() { } public static WstValueTable getTable(River river) { return getTable(river, 0); } public static WstValueTable getTable(River river, int kind) { Cache cache = CacheFactory.getCache(CACHE_NAME); CacheKey cacheKey; if (cache != null) { cacheKey = new CacheKey(river.getId(), kind); Element element = cache.get(cacheKey); if (element != null) { log.debug("got wst value table from cache"); return (WstValueTable)element.getValue(); } } else { cacheKey = null; } WstValueTable valueTable = getTableUncached(river, kind); if (cacheKey != null) { log.debug("store wst value table in cache"); Element element = new Element(cacheKey, valueTable); cache.put(element); } return valueTable; } public static WstValueTable getTableUncached(River river, int kind) { Session session = SessionHolder.HOLDER.get(); Query query = session.createQuery( "from Wst where river=:river and kind=:kind"); query.setParameter("river", river); query.setInteger("kind", kind); List<Wst> wsts = query.list(); if (wsts.isEmpty()) { return null; } Wst wst = wsts.get(0); // TODO: Do this sorting at database level List<WstColumn> wstColumns = new ArrayList(wst.getColumns()); Collections.sort(wstColumns, new Comparator<WstColumn>() { public int compare(WstColumn a, WstColumn b) { int pa = a.getPosition(); int pb = b.getPosition(); if (pa < pb) return -1; if (pa > pb) return +1; return 0; } }); WstValueTable.Column [] columns = new WstValueTable.Column[wstColumns.size()]; for (int i = 0; i < columns.length; ++i) { columns[i] = new WstValueTable.Column(wstColumns.get(i).getName()); } // using native SQL here to avoid myriad of small objects. SQLQuery sqlQuery = session.createSQLQuery(SQL_POS_WQ) .addScalar("position", StandardBasicTypes.DOUBLE) .addScalar("w", StandardBasicTypes.DOUBLE) .addScalar("q", StandardBasicTypes.DOUBLE) .addScalar("column_pos", StandardBasicTypes.INTEGER); sqlQuery.setInteger("wst_id", wst.getId()); WstValueTable valueTable = new WstValueTable(columns); int lastColumnNo = -1; WstValueTable.Row row = null; Double lastQ = -Double.MAX_VALUE; boolean qSorted = true; for (Object r: sqlQuery.list()) { Object[] result = (Object[]) r; double km = (Double) result[0]; Double w = (Double) result[1]; Double q = (Double) result[2]; int columnNo = (Integer)result[3]; if (columnNo > lastColumnNo) { // new row if (row != null) { row.qSorted = qSorted; valueTable.rows.add(row); } row = new WstValueTable.Row( km, new double[columnNo+1], new double[columnNo+1]); lastQ = -Double.MAX_VALUE; qSorted = true; } row.ws[columnNo] = w != null ? w : Double.NaN; row.qs[columnNo] = q != null ? q : Double.NaN; if (qSorted && (q == null || lastQ > q)) { qSorted = false; } lastQ = q; lastColumnNo = columnNo; } if (row != null) { valueTable.rows.add(row); } return valueTable; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :