Mercurial > dive4elements > river
comparison 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 |
comparison
equal
deleted
inserted
replaced
442:c1ef5f63278e | 443:5d65fe4c08d5 |
---|---|
1 package de.intevation.flys.artifacts.model; | |
2 | |
3 import java.io.Serializable; | |
4 | |
5 import java.util.ArrayList; | |
6 import java.util.Comparator; | |
7 import java.util.List; | |
8 import java.util.Collections; | |
9 | |
10 import org.hibernate.Session; | |
11 import org.hibernate.Query; | |
12 import org.hibernate.SQLQuery; | |
13 | |
14 import org.hibernate.type.StandardBasicTypes; | |
15 | |
16 import net.sf.ehcache.Cache; | |
17 import net.sf.ehcache.Element; | |
18 | |
19 import org.apache.log4j.Logger; | |
20 | |
21 import de.intevation.flys.model.River; | |
22 import de.intevation.flys.model.Wst; | |
23 import de.intevation.flys.model.WstColumn; | |
24 | |
25 import de.intevation.flys.artifacts.cache.CacheFactory; | |
26 | |
27 import de.intevation.flys.backend.SessionHolder; | |
28 | |
29 public class WstValueTableFactory | |
30 { | |
31 private static Logger log = Logger.getLogger(WstValueTableFactory.class); | |
32 | |
33 public static final String CACHE_NAME = "wst-value-table"; | |
34 | |
35 // TODO: put this into a property file | |
36 public static final String SQL_POS_WQ = | |
37 "SELECT position, w, q, column_pos" + | |
38 " FROM wst_value_table" + | |
39 " WHERE wst_id = :wst_id"; | |
40 | |
41 public static final class CacheKey | |
42 implements Serializable | |
43 { | |
44 private int riverId; | |
45 private int kind; | |
46 | |
47 public CacheKey(int riverId, int kind) { | |
48 this.riverId = riverId; | |
49 this.kind = kind; | |
50 } | |
51 | |
52 public int hashCode() { | |
53 return (riverId << 8) | kind; | |
54 } | |
55 | |
56 public boolean equals(Object other) { | |
57 if (!(other instanceof CacheKey)) { | |
58 return false; | |
59 } | |
60 CacheKey o = (CacheKey)other; | |
61 return riverId == o.riverId && kind == o.kind; | |
62 } | |
63 } // class CacheKey | |
64 | |
65 private WstValueTableFactory() { | |
66 } | |
67 | |
68 public static WstValueTable getTable(River river) { | |
69 return getTable(river, 0); | |
70 } | |
71 | |
72 public static WstValueTable getTable(River river, int kind) { | |
73 | |
74 Cache cache = CacheFactory.getCache(CACHE_NAME); | |
75 | |
76 CacheKey cacheKey; | |
77 | |
78 if (cache != null) { | |
79 cacheKey = new CacheKey(river.getId(), kind); | |
80 Element element = cache.get(cacheKey); | |
81 if (element != null) { | |
82 log.debug("got wst value table from cache"); | |
83 return (WstValueTable)element.getValue(); | |
84 } | |
85 } | |
86 else { | |
87 cacheKey = null; | |
88 } | |
89 | |
90 WstValueTable valueTable = getTableUncached(river, kind); | |
91 | |
92 if (cacheKey != null) { | |
93 log.debug("store wst value table in cache"); | |
94 Element element = new Element(cacheKey, valueTable); | |
95 cache.put(element); | |
96 } | |
97 | |
98 return valueTable; | |
99 } | |
100 | |
101 public static WstValueTable getTableUncached(River river, int kind) { | |
102 | |
103 Session session = SessionHolder.HOLDER.get(); | |
104 | |
105 Query query = session.createQuery( | |
106 "from Wst where river=:river and kind=:kind"); | |
107 query.setParameter("river", river); | |
108 query.setInteger("kind", kind); | |
109 | |
110 List<Wst> wsts = query.list(); | |
111 | |
112 if (wsts.isEmpty()) { | |
113 return null; | |
114 } | |
115 | |
116 Wst wst = wsts.get(0); | |
117 | |
118 // TODO: Do this sorting at database level | |
119 List<WstColumn> wstColumns = new ArrayList(wst.getColumns()); | |
120 Collections.sort(wstColumns, new Comparator<WstColumn>() { | |
121 public int compare(WstColumn a, WstColumn b) { | |
122 int pa = a.getPosition(); | |
123 int pb = b.getPosition(); | |
124 if (pa < pb) return -1; | |
125 if (pa > pb) return +1; | |
126 return 0; | |
127 } | |
128 }); | |
129 | |
130 WstValueTable.Column [] columns = | |
131 new WstValueTable.Column[wstColumns.size()]; | |
132 | |
133 for (int i = 0; i < columns.length; ++i) { | |
134 columns[i] = new WstValueTable.Column(wstColumns.get(i).getName()); | |
135 } | |
136 | |
137 // using native SQL here to avoid myriad of small objects. | |
138 SQLQuery sqlQuery = session.createSQLQuery(SQL_POS_WQ) | |
139 .addScalar("position", StandardBasicTypes.DOUBLE) | |
140 .addScalar("w", StandardBasicTypes.DOUBLE) | |
141 .addScalar("q", StandardBasicTypes.DOUBLE) | |
142 .addScalar("column_pos", StandardBasicTypes.INTEGER); | |
143 | |
144 sqlQuery.setInteger("wst_id", wst.getId()); | |
145 | |
146 WstValueTable valueTable = new WstValueTable(columns); | |
147 | |
148 int lastColumnNo = -1; | |
149 WstValueTable.Row row = null; | |
150 | |
151 Double lastQ = -Double.MAX_VALUE; | |
152 boolean qSorted = true; | |
153 | |
154 for (Object r: sqlQuery.list()) { | |
155 Object[] result = (Object[]) r; | |
156 | |
157 double km = (Double) result[0]; | |
158 Double w = (Double) result[1]; | |
159 Double q = (Double) result[2]; | |
160 int columnNo = (Integer)result[3]; | |
161 | |
162 if (columnNo > lastColumnNo) { // new row | |
163 if (row != null) { | |
164 row.qSorted = qSorted; | |
165 valueTable.rows.add(row); | |
166 } | |
167 row = new WstValueTable.Row( | |
168 km, | |
169 new double[columnNo+1], | |
170 new double[columnNo+1]); | |
171 lastQ = -Double.MAX_VALUE; | |
172 qSorted = true; | |
173 } | |
174 | |
175 row.ws[columnNo] = w != null ? w : Double.NaN; | |
176 row.qs[columnNo] = q != null ? q : Double.NaN; | |
177 | |
178 if (qSorted && (q == null || lastQ > q)) { | |
179 qSorted = false; | |
180 } | |
181 lastQ = q; | |
182 | |
183 lastColumnNo = columnNo; | |
184 } | |
185 | |
186 if (row != null) { | |
187 valueTable.rows.add(row); | |
188 } | |
189 | |
190 return valueTable; | |
191 } | |
192 } | |
193 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |