Mercurial > dive4elements > river
comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/FLYSArtifact.java @ 704:eab5e5089d77
Merged revisions 2127-2133,2136-2137,2140,2143-2144,2146,2150-2151,2153-2154 via svnmerge from
svn+ssh://teichmann@thoe/home/projects/Geospatial/bsh-generischer-viewer/Material/SVN/flys-artifacts/branches/facets-slt
........
r2127 | ingo | 2011-06-16 09:50:56 +0200 (Do, 16 Jun 2011) | 1 line
Added a compute() method to WINFOArtifact which acts as a dispatcher for different computations. It triggers a calculation based on ComputeCallbacks that are generated by the current states.
........
r2128 | ingo | 2011-06-16 10:25:06 +0200 (Do, 16 Jun 2011) | 1 line
Moved Waterlevel state into the correct package.
........
r2129 | ingo | 2011-06-16 10:43:58 +0200 (Do, 16 Jun 2011) | 1 line
Added two more compute() methods to ComputeCallback to distinguish between different phases of the artifact.
........
r2130 | ingo | 2011-06-16 10:57:05 +0200 (Do, 16 Jun 2011) | 1 line
Use enums to dispatch computeFeed() and computeAdvance().
........
r2131 | ingo | 2011-06-16 11:04:59 +0200 (Do, 16 Jun 2011) | 1 line
Store facets for each state.
........
r2132 | ingo | 2011-06-16 12:05:44 +0200 (Do, 16 Jun 2011) | 1 line
Generated facets for each output aspect.
........
r2133 | ingo | 2011-06-16 15:24:00 +0200 (Do, 16 Jun 2011) | 1 line
Write computed facets into artifacts describe document.
........
r2136 | ingo | 2011-06-16 16:10:49 +0200 (Do, 16 Jun 2011) | 1 line
Add index and description of facets to collections describe document.
........
r2137 | ingo | 2011-06-16 16:31:41 +0200 (Do, 16 Jun 2011) | 1 line
OutGenerators doOut() takes a facet object now instead of just its name.
........
r2140 | ingo | 2011-06-17 11:19:43 +0200 (Fr, 17 Jun 2011) | 1 line
OutGenerators use now facets to fetch necessary data.
........
r2143 | teichmann | 2011-06-17 12:40:54 +0200 (Fr, 17 Jun 2011) | 1 line
Removed ComputeCallback because this was thought too complicated. Fixed issue with facets not be re-generated if same state is entered again.
........
r2144 | teichmann | 2011-06-17 13:08:31 +0200 (Fr, 17 Jun 2011) | 1 line
make getGauges() more robust
........
r2146 | teichmann | 2011-06-17 13:23:57 +0200 (Fr, 17 Jun 2011) | 1 line
mico opt: inter cmps are faster than str cmps.
........
r2150 | teichmann | 2011-06-17 15:10:20 +0200 (Fr, 17 Jun 2011) | 1 line
call computeAdvance() if we want to advance.
........
r2151 | teichmann | 2011-06-17 15:45:50 +0200 (Fr, 17 Jun 2011) | 1 line
Base WST/CSV exports on facets. TODO: generate the facets.
........
r2153 | teichmann | 2011-06-17 16:03:29 +0200 (Fr, 17 Jun 2011) | 1 line
Add facet to access raw computed data.
........
r2154 | teichmann | 2011-06-17 16:37:09 +0200 (Fr, 17 Jun 2011) | 1 line
Generate data facets for the computed states.
........
flys-artifacts/trunk@2156 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Fri, 17 Jun 2011 16:17:03 +0000 |
parents | d45c3ddaed1b 94f0f91be11c |
children | 853dceead0f4 |
comparison
equal
deleted
inserted
replaced
685:d45c3ddaed1b | 704:eab5e5089d77 |
---|---|
2 | 2 |
3 import java.util.ArrayList; | 3 import java.util.ArrayList; |
4 import java.util.Collection; | 4 import java.util.Collection; |
5 import java.util.Collections; | 5 import java.util.Collections; |
6 import java.util.HashMap; | 6 import java.util.HashMap; |
7 import java.util.TreeMap; | |
7 import java.util.List; | 8 import java.util.List; |
8 import java.util.Map; | 9 import java.util.Map; |
9 import java.util.Set; | 10 import java.util.Set; |
10 | 11 |
11 import javax.xml.xpath.XPathConstants; | 12 import javax.xml.xpath.XPathConstants; |
12 | 13 |
13 import gnu.trove.TDoubleArrayList; | 14 import gnu.trove.TDoubleArrayList; |
15 | |
16 import net.sf.ehcache.Cache; | |
14 | 17 |
15 import org.apache.log4j.Logger; | 18 import org.apache.log4j.Logger; |
16 | 19 |
17 import org.w3c.dom.Document; | 20 import org.w3c.dom.Document; |
18 import org.w3c.dom.Element; | 21 import org.w3c.dom.Element; |
26 import de.intevation.artifacts.common.utils.XMLUtils; | 29 import de.intevation.artifacts.common.utils.XMLUtils; |
27 | 30 |
28 import de.intevation.artifactdatabase.DefaultArtifact; | 31 import de.intevation.artifactdatabase.DefaultArtifact; |
29 import de.intevation.artifactdatabase.data.DefaultStateData; | 32 import de.intevation.artifactdatabase.data.DefaultStateData; |
30 import de.intevation.artifactdatabase.data.StateData; | 33 import de.intevation.artifactdatabase.data.StateData; |
34 import de.intevation.artifactdatabase.state.Facet; | |
31 import de.intevation.artifactdatabase.state.State; | 35 import de.intevation.artifactdatabase.state.State; |
32 import de.intevation.artifactdatabase.state.StateEngine; | 36 import de.intevation.artifactdatabase.state.StateEngine; |
33 import de.intevation.artifactdatabase.transition.TransitionEngine; | 37 import de.intevation.artifactdatabase.transition.TransitionEngine; |
34 | 38 |
35 import de.intevation.flys.utils.DoubleUtil; | 39 import de.intevation.flys.utils.DoubleUtil; |
38 import de.intevation.flys.model.Range; | 42 import de.intevation.flys.model.Range; |
39 import de.intevation.flys.model.River; | 43 import de.intevation.flys.model.River; |
40 | 44 |
41 import de.intevation.flys.artifacts.context.FLYSContext; | 45 import de.intevation.flys.artifacts.context.FLYSContext; |
42 | 46 |
47 import de.intevation.flys.artifacts.cache.CacheFactory; | |
48 | |
43 import de.intevation.flys.artifacts.model.DischargeTables; | 49 import de.intevation.flys.artifacts.model.DischargeTables; |
44 import de.intevation.flys.artifacts.model.RiverFactory; | 50 import de.intevation.flys.artifacts.model.RiverFactory; |
45 import de.intevation.flys.artifacts.model.Segment; | 51 import de.intevation.flys.artifacts.model.Segment; |
46 | 52 |
47 import de.intevation.flys.artifacts.states.DefaultState; | 53 import de.intevation.flys.artifacts.states.DefaultState; |
54 import de.intevation.flys.artifacts.states.DefaultState.ComputeType; | |
48 import de.intevation.flys.artifacts.states.LocationDistanceSelect; | 55 import de.intevation.flys.artifacts.states.LocationDistanceSelect; |
49 | 56 |
50 | 57 |
51 /** | 58 /** |
52 * The defaul FLYS artifact. | 59 * The defaul FLYS artifact. |
57 | 64 |
58 /** The logger that is used in this artifact.*/ | 65 /** The logger that is used in this artifact.*/ |
59 private static Logger logger = Logger.getLogger(FLYSArtifact.class); | 66 private static Logger logger = Logger.getLogger(FLYSArtifact.class); |
60 | 67 |
61 | 68 |
69 public static final String COMPUTING_CACHE = "computed.values"; | |
70 | |
62 /** The XPath that points to the input data elements of the FEED document.*/ | 71 /** The XPath that points to the input data elements of the FEED document.*/ |
63 public static final String XPATH_FEED_INPUT = | 72 public static final String XPATH_FEED_INPUT = |
64 "/art:action/art:data/art:input"; | 73 "/art:action/art:data/art:input"; |
65 | 74 |
66 /** The XPath that points to the name of the target state of ADVANCE.*/ | 75 /** The XPath that points to the name of the target state of ADVANCE.*/ |
91 protected String name; | 100 protected String name; |
92 | 101 |
93 /** The data that have been inserted into this artifact.*/ | 102 /** The data that have been inserted into this artifact.*/ |
94 protected Map<String, StateData> data; | 103 protected Map<String, StateData> data; |
95 | 104 |
105 /** The list of facets supported by this artifact.*/ | |
106 protected Map<String, List<Facet>> facets; | |
107 | |
96 | 108 |
97 /** | 109 /** |
98 * The default constructor that creates an empty FLYSArtifact. | 110 * The default constructor that creates an empty FLYSArtifact. |
99 */ | 111 */ |
100 public FLYSArtifact() { | 112 public FLYSArtifact() { |
101 data = new HashMap<String, StateData>(); | 113 data = new TreeMap<String, StateData>(); |
102 previousStateIds = new ArrayList<String>(); | 114 previousStateIds = new ArrayList<String>(); |
115 facets = new HashMap<String, List<Facet>>(); | |
103 } | 116 } |
104 | 117 |
105 | 118 |
106 /** | 119 /** |
107 * Returns the name of the concrete artifact. | 120 * Returns the name of the concrete artifact. |
180 Element result = creator.create("result"); | 193 Element result = creator.create("result"); |
181 doc.appendChild(result); | 194 doc.appendChild(result); |
182 | 195 |
183 try { | 196 try { |
184 saveData(target, XPATH_FEED_INPUT, context); | 197 saveData(target, XPATH_FEED_INPUT, context); |
198 | |
199 compute(context, ComputeType.FEED); | |
200 | |
185 return describe(target, context); | 201 return describe(target, context); |
186 } | 202 } |
187 catch (IllegalArgumentException iae) { | 203 catch (IllegalArgumentException iae) { |
188 // do not store state if validation fails. | 204 // do not store state if validation fails. |
189 context.afterCall(CallContext.NOTHING); | 205 context.afterCall(CallContext.NOTHING); |
226 List<String> prev = getPreviousStateIds(); | 242 List<String> prev = getPreviousStateIds(); |
227 prev.add(getCurrentStateId()); | 243 prev.add(getCurrentStateId()); |
228 | 244 |
229 setCurrentStateId(targetState); | 245 setCurrentStateId(targetState); |
230 | 246 |
247 logger.debug("Compute data for state: " + targetState); | |
248 compute(context, ComputeType.ADVANCE); | |
249 | |
231 return describe(target, context); | 250 return describe(target, context); |
232 } | 251 } |
233 else if (isPreviousState(targetState, context)) { | 252 else if (isPreviousState(targetState, context)) { |
234 logger.info("Advance: Step back to"); | 253 logger.info("Advance: Step back to"); |
235 | 254 |
239 | 258 |
240 for (int i = start; i >= targetIdx; i--) { | 259 for (int i = start; i >= targetIdx; i--) { |
241 String prev = prevs.get(i); | 260 String prev = prevs.get(i); |
242 logger.debug("Remove state id '" + prev + "'"); | 261 logger.debug("Remove state id '" + prev + "'"); |
243 prevs.remove(prev); | 262 prevs.remove(prev); |
263 facets.remove(prev); | |
244 } | 264 } |
245 | 265 |
246 setCurrentStateId(targetState); | 266 setCurrentStateId(targetState); |
247 | 267 |
248 return describe(target, context); | 268 return describe(target, context); |
333 * | 353 * |
334 * @return the StateData object if existing, otherwise null. | 354 * @return the StateData object if existing, otherwise null. |
335 */ | 355 */ |
336 public StateData getData(String name) { | 356 public StateData getData(String name) { |
337 return data.get(name); | 357 return data.get(name); |
358 } | |
359 | |
360 | |
361 public Facet getNativeFacet(Facet facet) { | |
362 String name = facet.getName(); | |
363 int index = facet.getIndex(); | |
364 | |
365 for (Map.Entry<String, List<Facet>> entry: facets.entrySet()) { | |
366 for (Facet f: entry.getValue()) { | |
367 if (f.getIndex() == index && f.getName().equals(name)) { | |
368 return f; | |
369 } | |
370 } | |
371 } | |
372 | |
373 logger.warn("Could not find facet: " + name + " at " + index); | |
374 return null; | |
338 } | 375 } |
339 | 376 |
340 | 377 |
341 /** | 378 /** |
342 * This method stores the data that is contained in the FEED document. | 379 * This method stores the data that is contained in the FEED document. |
671 * Returns the gauges that match the selected kilometer range. | 708 * Returns the gauges that match the selected kilometer range. |
672 * | 709 * |
673 * @return the gauges based on the selected kilometer range. | 710 * @return the gauges based on the selected kilometer range. |
674 */ | 711 */ |
675 public List<Gauge> getGauges() { | 712 public List<Gauge> getGauges() { |
676 River river = getRiver(); | 713 |
677 double[] dist = getDistance(); | 714 River river = getRiver(); |
715 if (river == null) { | |
716 return null; | |
717 } | |
718 | |
719 double [] dist = getDistance(); | |
720 if (dist == null) { | |
721 return null; | |
722 } | |
678 | 723 |
679 return river.determineGauges(dist[0], dist[1]); | 724 return river.determineGauges(dist[0], dist[1]); |
680 } | 725 } |
681 | 726 |
682 | 727 |
1021 ) { | 1066 ) { |
1022 return DoubleUtil.explode(from, to, step); | 1067 return DoubleUtil.explode(from, to, step); |
1023 } | 1068 } |
1024 | 1069 |
1025 /** | 1070 /** |
1071 * Computes the hash code of the entered values. | |
1072 * | |
1073 * @return a hash code. | |
1074 */ | |
1075 @Override | |
1076 public String hash() { | |
1077 Set<Map.Entry<String, StateData>> entries = data.entrySet(); | |
1078 | |
1079 int hash = 0; | |
1080 int shift = 3; | |
1081 | |
1082 for (Map.Entry<String, StateData> entry: entries) { | |
1083 String key = entry.getKey(); | |
1084 Object value = entry.getValue().getValue(); | |
1085 | |
1086 hash ^= (key.hashCode() << shift) | (value.hashCode() << 2 * shift); | |
1087 shift += 2; | |
1088 } | |
1089 | |
1090 return getCurrentStateId() + hash; | |
1091 } | |
1092 | |
1093 | |
1094 /** | |
1095 * Dispatches the computation request to compute(CallContext context, String | |
1096 * hash) with the current hash value of the artifact which is provided by | |
1097 * hash(). | |
1098 * | |
1099 * @param context The CallContext. | |
1100 */ | |
1101 public Object compute(CallContext context, ComputeType type) { | |
1102 return compute(context, hash(), type); | |
1103 } | |
1104 | |
1105 | |
1106 /** | |
1107 * Dispatches computation requests to the current state which needs to | |
1108 * implement a createComputeCallback(String hash, FLYSArtifact artifact) | |
1109 * method. | |
1110 * | |
1111 * @param context The CallContext. | |
1112 * @param hash The hash value which is used to fetch computed data from | |
1113 * cache. | |
1114 * | |
1115 * @return the computed data. | |
1116 */ | |
1117 public Object compute(CallContext context, String hash, ComputeType type) { | |
1118 DefaultState current = (DefaultState) getCurrentState(context); | |
1119 | |
1120 logger.debug("Create ComputeCallback for state: " + current.getID()); | |
1121 | |
1122 return compute(context, hash, current, type); | |
1123 } | |
1124 | |
1125 | |
1126 public Object compute( | |
1127 CallContext context, | |
1128 String key, | |
1129 DefaultState state, | |
1130 ComputeType type | |
1131 ) { | |
1132 String stateID = state.getID(); | |
1133 | |
1134 List<Facet> fs = new ArrayList<Facet>(); | |
1135 | |
1136 try { | |
1137 Cache cache = CacheFactory.getCache(COMPUTING_CACHE); | |
1138 | |
1139 Object old = null; | |
1140 | |
1141 if (cache != null) { | |
1142 net.sf.ehcache.Element element = cache.get(key); | |
1143 if (element != null) { | |
1144 logger.debug("Got computation result from cache."); | |
1145 old = element.getValue(); | |
1146 } | |
1147 } | |
1148 | |
1149 Object res; | |
1150 switch (type) { | |
1151 case FEED: | |
1152 res = state.computeFeed(this, key, context, fs, old); | |
1153 break; | |
1154 case ADVANCE: | |
1155 res = state.computeAdvance(this, key, context, fs, old); | |
1156 break; | |
1157 default: | |
1158 res = null; | |
1159 } | |
1160 | |
1161 if (cache != null && old != res && res != null) { | |
1162 logger.debug("Store computation result to cache."); | |
1163 net.sf.ehcache.Element element = | |
1164 new net.sf.ehcache.Element(key, res); | |
1165 cache.put(element); | |
1166 } | |
1167 | |
1168 return res; | |
1169 } | |
1170 finally { | |
1171 if (fs.isEmpty()) { | |
1172 facets.remove(stateID); | |
1173 } | |
1174 else { | |
1175 facets.put(stateID, fs); | |
1176 } | |
1177 } | |
1178 } | |
1179 | |
1180 | |
1181 /** | |
1026 * Method to dump the artifacts state/data. | 1182 * Method to dump the artifacts state/data. |
1027 */ | 1183 */ |
1028 protected void dumpArtifact() { | 1184 protected void dumpArtifact() { |
1029 if (logger.isDebugEnabled()) { | 1185 if (logger.isDebugEnabled()) { |
1030 logger.debug("++++++++++++++ DUMP ARTIFACT DATA +++++++++++++++++"); | 1186 logger.debug("++++++++++++++ DUMP ARTIFACT DATA +++++++++++++++++"); |