sascha@443: package de.intevation.flys.artifacts.model; sascha@443: sascha@443: import java.util.ArrayList; sascha@443: import java.util.Comparator; sascha@443: import java.util.List; sascha@443: import java.util.Collections; sascha@443: sascha@443: import org.hibernate.Session; sascha@443: import org.hibernate.Query; sascha@443: import org.hibernate.SQLQuery; sascha@443: sascha@443: import org.hibernate.type.StandardBasicTypes; sascha@443: sascha@443: import net.sf.ehcache.Cache; sascha@443: import net.sf.ehcache.Element; sascha@443: sascha@443: import org.apache.log4j.Logger; sascha@443: sascha@443: import de.intevation.flys.model.River; sascha@443: import de.intevation.flys.model.Wst; sascha@443: import de.intevation.flys.model.WstColumn; sascha@443: sascha@443: import de.intevation.flys.artifacts.cache.CacheFactory; sascha@443: sascha@443: import de.intevation.flys.backend.SessionHolder; sascha@443: sascha@443: public class WstValueTableFactory sascha@443: { sascha@443: private static Logger log = Logger.getLogger(WstValueTableFactory.class); sascha@443: sascha@443: public static final String CACHE_NAME = "wst-value-table"; sascha@443: sascha@443: // TODO: put this into a property file sascha@443: public static final String SQL_POS_WQ = sascha@443: "SELECT position, w, q, column_pos" + sascha@443: " FROM wst_value_table" + sascha@443: " WHERE wst_id = :wst_id"; sascha@443: sascha@443: private WstValueTableFactory() { sascha@443: } sascha@443: sascha@443: public static WstValueTable getTable(River river) { sascha@443: return getTable(river, 0); sascha@443: } sascha@443: sascha@443: public static WstValueTable getTable(River river, int kind) { sascha@443: sascha@443: Cache cache = CacheFactory.getCache(CACHE_NAME); sascha@443: sascha@626: WstValueTableCacheKey cacheKey; sascha@443: sascha@443: if (cache != null) { sascha@626: cacheKey = new WstValueTableCacheKey(river.getId(), kind); sascha@443: Element element = cache.get(cacheKey); sascha@443: if (element != null) { sascha@443: log.debug("got wst value table from cache"); sascha@443: return (WstValueTable)element.getValue(); sascha@443: } sascha@443: } sascha@443: else { sascha@443: cacheKey = null; sascha@443: } sascha@443: sascha@443: WstValueTable valueTable = getTableUncached(river, kind); sascha@443: sascha@443: if (cacheKey != null) { sascha@443: log.debug("store wst value table in cache"); sascha@443: Element element = new Element(cacheKey, valueTable); sascha@443: cache.put(element); sascha@443: } sascha@443: sascha@443: return valueTable; sascha@443: } sascha@443: sascha@443: public static WstValueTable getTableUncached(River river, int kind) { sascha@443: sascha@443: Session session = SessionHolder.HOLDER.get(); sascha@443: sascha@443: Query query = session.createQuery( sascha@443: "from Wst where river=:river and kind=:kind"); sascha@443: query.setParameter("river", river); sascha@443: query.setInteger("kind", kind); sascha@443: sascha@443: List wsts = query.list(); sascha@443: sascha@443: if (wsts.isEmpty()) { sascha@443: return null; sascha@443: } sascha@443: sascha@443: Wst wst = wsts.get(0); sascha@443: sascha@443: // TODO: Do this sorting at database level sascha@443: List wstColumns = new ArrayList(wst.getColumns()); sascha@443: Collections.sort(wstColumns, new Comparator() { sascha@443: public int compare(WstColumn a, WstColumn b) { sascha@443: int pa = a.getPosition(); sascha@443: int pb = b.getPosition(); sascha@443: if (pa < pb) return -1; sascha@443: if (pa > pb) return +1; sascha@443: return 0; sascha@443: } sascha@443: }); sascha@443: sascha@443: WstValueTable.Column [] columns = sascha@443: new WstValueTable.Column[wstColumns.size()]; sascha@443: sascha@443: for (int i = 0; i < columns.length; ++i) { sascha@443: columns[i] = new WstValueTable.Column(wstColumns.get(i).getName()); sascha@443: } sascha@443: sascha@443: // using native SQL here to avoid myriad of small objects. sascha@443: SQLQuery sqlQuery = session.createSQLQuery(SQL_POS_WQ) sascha@443: .addScalar("position", StandardBasicTypes.DOUBLE) sascha@443: .addScalar("w", StandardBasicTypes.DOUBLE) sascha@443: .addScalar("q", StandardBasicTypes.DOUBLE) sascha@443: .addScalar("column_pos", StandardBasicTypes.INTEGER); sascha@443: sascha@443: sqlQuery.setInteger("wst_id", wst.getId()); sascha@443: sascha@443: WstValueTable valueTable = new WstValueTable(columns); sascha@443: sascha@443: int lastColumnNo = -1; sascha@443: WstValueTable.Row row = null; sascha@443: sascha@443: Double lastQ = -Double.MAX_VALUE; sascha@443: boolean qSorted = true; sascha@443: sascha@443: for (Object r: sqlQuery.list()) { sascha@443: Object[] result = (Object[]) r; sascha@443: sascha@443: double km = (Double) result[0]; sascha@443: Double w = (Double) result[1]; sascha@443: Double q = (Double) result[2]; sascha@443: int columnNo = (Integer)result[3]; sascha@443: sascha@443: if (columnNo > lastColumnNo) { // new row sascha@443: if (row != null) { sascha@443: row.qSorted = qSorted; sascha@443: valueTable.rows.add(row); sascha@443: } sascha@443: row = new WstValueTable.Row( sascha@443: km, sascha@443: new double[columnNo+1], sascha@443: new double[columnNo+1]); sascha@443: lastQ = -Double.MAX_VALUE; sascha@443: qSorted = true; sascha@443: } sascha@443: sascha@443: row.ws[columnNo] = w != null ? w : Double.NaN; sascha@443: row.qs[columnNo] = q != null ? q : Double.NaN; sascha@443: sascha@443: if (qSorted && (q == null || lastQ > q)) { sascha@443: qSorted = false; sascha@443: } sascha@443: lastQ = q; sascha@443: sascha@443: lastColumnNo = columnNo; sascha@443: } sascha@443: sascha@443: if (row != null) { sascha@443: valueTable.rows.add(row); sascha@443: } sascha@443: sascha@458: // XXX: should not be necessary sascha@458: valueTable.sortRows(); sascha@458: sascha@443: return valueTable; sascha@443: } sascha@443: } sascha@443: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :