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 +++++++++++++++++");

http://dive4elements.wald.intevation.org