sascha@443: package de.intevation.flys.artifacts.model; sascha@443: sascha@633: import java.util.List; sascha@443: import java.util.ArrayList; sascha@633: sascha@633: import net.sf.ehcache.Cache; sascha@633: import net.sf.ehcache.Element; sascha@633: sascha@633: import de.intevation.flys.artifacts.cache.CacheFactory; sascha@633: sascha@633: import de.intevation.flys.backend.SessionHolder; sascha@633: sascha@633: import org.apache.log4j.Logger; sascha@633: sascha@633: import de.intevation.flys.model.River; sascha@633: import de.intevation.flys.model.Wst; 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: public class WstValueTableFactory sascha@443: { sascha@443: private static Logger log = Logger.getLogger(WstValueTableFactory.class); sascha@443: sascha@633: public static final int DEFAULT_KIND = 0; sascha@633: sascha@443: // TODO: put this into a property file sascha@633: sascha@633: public static final String HQL_WST = sascha@633: "from Wst where river=:river and kind=:kind"; sascha@633: sascha@633: public static final String SQL_SELECT_NAMES_POS = sascha@633: "SELECT position, name FROM wst_columns " + sascha@633: "WHERE wst_id = :wst_id ORDER BY position"; sascha@633: sascha@633: public static final String SQL_SELECT_QS = sascha@633: "SELECT column_pos, q, a, b FROM wst_q_values " + sascha@633: "WHERE wst_id = :wst_id"; sascha@633: sascha@633: public static final String SQL_SELECT_WS = sascha@633: "SELECT km, w, column_pos FROM wst_w_values " + sascha@633: "WHERE wst_id = :wst_id"; sascha@443: sascha@443: private WstValueTableFactory() { sascha@443: } sascha@443: sascha@443: public static WstValueTable getTable(River river) { sascha@633: return getTable(river, DEFAULT_KIND); sascha@443: } sascha@443: sascha@443: public static WstValueTable getTable(River river, int kind) { sascha@443: sascha@632: Cache cache = CacheFactory.getCache(WstValueTableCacheKey.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@632: if (valueTable != null && 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@633: public static WstValueTable getTableUncached(River river) { sascha@633: return getTableUncached(river, DEFAULT_KIND); sascha@633: } sascha@633: sascha@443: public static WstValueTable getTableUncached(River river, int kind) { sascha@443: sascha@443: Session session = SessionHolder.HOLDER.get(); sascha@443: sascha@633: Wst wst = loadWst(session, river, kind); sascha@633: sascha@633: if (wst == null) { sascha@633: return null; sascha@633: } sascha@633: sascha@633: WstValueTable.Column [] columns = loadColumns(session, wst); sascha@633: sascha@633: loadQRanges(session, columns, wst); sascha@633: sascha@633: List rows = loadRows(session, wst, columns.length); sascha@633: sascha@633: return new WstValueTable(columns, rows); sascha@633: } sascha@633: felix@1780: /** felix@1780: * @param kind Kind of wst. felix@1780: */ sascha@633: protected static Wst loadWst(Session session, River river, int kind) { sascha@633: Query query = session.createQuery(HQL_WST); sascha@443: query.setParameter("river", river); sascha@443: query.setInteger("kind", kind); sascha@443: sascha@443: List wsts = query.list(); sascha@443: sascha@633: return wsts.isEmpty() ? null : wsts.get(0); sascha@633: } sascha@443: sascha@633: protected static List loadRows( sascha@742: Session session, sascha@633: Wst wst, sascha@633: int numColumns sascha@633: ) { sascha@633: SQLQuery sqlQuery = session.createSQLQuery(SQL_SELECT_WS) sascha@633: .addScalar("km", StandardBasicTypes.DOUBLE) sascha@443: .addScalar("w", StandardBasicTypes.DOUBLE) sascha@443: .addScalar("column_pos", StandardBasicTypes.INTEGER); sascha@443: sascha@443: sqlQuery.setInteger("wst_id", wst.getId()); sascha@443: sascha@633: List results = sqlQuery.list(); sascha@443: sascha@633: int lastColumn = Integer.MAX_VALUE; sascha@633: double [] ws = null; sascha@443: sascha@633: ArrayList rows = new ArrayList(); sascha@633: sascha@633: for (Object [] result: results) { sascha@633: int column = (Integer)result[2]; sascha@633: if (column < lastColumn) { sascha@633: ws = new double[numColumns]; sascha@633: WstValueTable.Row row = sascha@633: new WstValueTable.Row((Double)result[0], ws); sascha@633: rows.add(row); sascha@633: } sascha@633: Double w = (Double)result[1]; sascha@633: ws[column] = w != null ? w : Double.NaN; sascha@633: lastColumn = column; sascha@633: } sascha@633: sascha@633: rows.trimToSize(); sascha@633: return rows; sascha@633: } sascha@633: sascha@633: protected static WstValueTable.Column [] loadColumns( sascha@633: Session session, sascha@633: Wst wst sascha@633: ) { sascha@633: SQLQuery sqlQuery = session.createSQLQuery(SQL_SELECT_NAMES_POS) sascha@633: .addScalar("position", StandardBasicTypes.INTEGER) sascha@633: .addScalar("name", StandardBasicTypes.STRING); sascha@633: sascha@633: sqlQuery.setInteger("wst_id", wst.getId()); sascha@633: sascha@633: List columnNames = sqlQuery.list(); sascha@633: sascha@633: WstValueTable.Column [] columns = sascha@633: new WstValueTable.Column[columnNames.size()]; sascha@633: sascha@633: for (int i = 0; i < columns.length; ++i) { sascha@633: columns[i] = new WstValueTable.Column( sascha@633: (String)columnNames.get(i)[1]); sascha@633: } sascha@633: return columns; sascha@633: } sascha@633: sascha@633: protected static void loadQRanges( sascha@633: Session session, sascha@633: WstValueTable.Column [] columns, sascha@633: Wst wst sascha@633: ) { sascha@633: SQLQuery sqlQuery = session.createSQLQuery(SQL_SELECT_QS) sascha@633: .addScalar("column_pos", StandardBasicTypes.INTEGER) sascha@633: .addScalar("q", StandardBasicTypes.DOUBLE) sascha@633: .addScalar("a", StandardBasicTypes.DOUBLE) sascha@633: .addScalar("b", StandardBasicTypes.DOUBLE); sascha@633: sascha@633: sqlQuery.setInteger("wst_id", wst.getId()); sascha@633: sascha@633: List qRanges = sqlQuery.list(); sascha@633: sascha@633: int start = -1; sascha@633: int Q = qRanges.size(); sascha@633: Integer lastColumn = null; sascha@633: sascha@633: for (int i = 0; i < Q; ++i) { sascha@633: Object [] qRange = qRanges.get(i); sascha@633: Integer columnId = (Integer)qRange[0]; sascha@633: if (lastColumn == null) { sascha@633: lastColumn = columnId; sascha@633: start = i; sascha@633: } sascha@633: else if (!lastColumn.equals(columnId)) { sascha@633: QRangeTree qRangeTree = new QRangeTree(qRanges, start, i); sascha@633: columns[lastColumn].setQRangeTree(qRangeTree); sascha@633: lastColumn = columnId; sascha@633: start = i; sascha@633: } sascha@633: } sascha@633: sascha@633: if (start != -1) { sascha@633: QRangeTree qRangeTree = new QRangeTree(qRanges, start, Q); sascha@633: columns[lastColumn].setQRangeTree(qRangeTree); sascha@633: } sascha@633: sascha@742: /* This is debug code to visualize the q ranges trees sascha@633: sascha@633: java.io.PrintWriter out = null; sascha@633: try { sascha@633: out = new java.io.PrintWriter( sascha@633: new java.io.FileWriter( sascha@633: "/tmp/qranges" + System.currentTimeMillis() + ".dot")); sascha@633: sascha@633: out.println("graph \"Q ranges trees\" {"); sascha@633: sascha@633: for (int i = 0; i < columns.length; ++i) { sascha@633: QRangeTree tree = columns[i].getQRangeTree(); sascha@633: out.println(tree.toGraph()); sascha@443: } sascha@443: sascha@633: out.println("}"); sascha@443: sascha@633: out.flush(); sascha@443: } sascha@633: catch (java.io.IOException ioe) { sascha@633: log.error(ioe); sascha@443: } sascha@633: finally { sascha@633: if (out != null) { sascha@633: out.close(); sascha@633: } sascha@633: } sascha@633: */ sascha@633: } sascha@443: sascha@443: } sascha@443: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :