# HG changeset patch # User Felix Wolfsteller # Date 1320326575 0 # Node ID 02cd002205a3fda938cfba7ff8c1e6e5d0c18322 # Parent 982956bde69ee3bd32e8e82976720d152eeb01aa Added 'static' wqkms data access. flys-artifacts/trunk@3154 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 982956bde69e -r 02cd002205a3 flys-artifacts/ChangeLog --- a/flys-artifacts/ChangeLog Thu Nov 03 12:28:38 2011 +0000 +++ b/flys-artifacts/ChangeLog Thu Nov 03 13:22:55 2011 +0000 @@ -1,3 +1,23 @@ +2011-11-03 Felix Wolfsteller + + Added access to static W_Q_Kms - data in much the same way then static + WKms. + + * src/main/java/de/intevation/flys/artifacts/model/StaticWQKmsCacheKey.java: + Cache Key for static wqkms data. + + * src/main/java/de/intevation/flys/artifacts/model/WQKmsFacet.java: + Facet for WQKms. + + * src/main/java/de/intevation/flys/artifacts/model/WQKmsFactory.java: + Factory to access WQKms. + + * src/main/java/de/intevation/flys/artifacts/StaticWQKmsArtifact.java: + Artifact that provides 'static' WQKms. + + * src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java: + Added STATIC_WQKMS type. + 2011-11-03 Sascha L. Teichmann * src/main/java/de/intevation/flys/jfree/XYDatasetToZeroMapper.java: diff -r 982956bde69e -r 02cd002205a3 flys-artifacts/src/main/java/de/intevation/flys/artifacts/StaticWQKmsArtifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/StaticWQKmsArtifact.java Thu Nov 03 13:22:55 2011 +0000 @@ -0,0 +1,247 @@ +package de.intevation.flys.artifacts; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +import de.intevation.artifactdatabase.state.Facet; +import de.intevation.artifactdatabase.state.DefaultOutput; +import de.intevation.artifactdatabase.state.State; + +import de.intevation.artifacts.Artifact; +import de.intevation.artifacts.ArtifactFactory; +import de.intevation.artifacts.ArtifactNamespaceContext; +import de.intevation.artifacts.CallMeta; + +import de.intevation.flys.artifacts.model.FacetTypes; +import de.intevation.flys.artifacts.model.WQKms; +import de.intevation.flys.artifacts.model.WQKmsFacet; +import de.intevation.flys.artifacts.model.WKmsFactory; +import de.intevation.flys.artifacts.model.WQKmsFactory; + +import de.intevation.flys.artifacts.states.StaticState; +import de.intevation.flys.artifacts.resources.Resources; + +import de.intevation.artifacts.common.utils.XMLUtils; + +/** + * Artifact to access additional "waterlevel/discharge"-type of data, like + * fixation measurements. + * + * This artifact neglects (Static)FLYSArtifacts capabilities of interaction + * with the StateEngine by overriding the getState*-methods. + */ +public class StaticWQKmsArtifact +extends StaticFLYSArtifact +implements FacetTypes +{ + /** The logger for this class. */ + private static Logger logger = + Logger.getLogger(StaticWQKmsArtifact.class); + + /** XPath to access initial parameter. */ + public static final String XPATH_DATA = + "/art:action/art:ids/@value"; + + public static final String STATIC_STATE_NAME = + "state.additional_wqkms.static"; + + /** One and only state to be in. */ + protected transient State state = null; + + + /** + * Trivial Constructor. + */ + public StaticWQKmsArtifact() { + logger.debug("StaticWQKmsArtifact.StaticWQKmsArtifact"); + } + + + /** + * Gets called from factory, to set things up. + */ + @Override + public void setup( + String identifier, + ArtifactFactory factory, + Object context, + CallMeta callMeta, + Document data) + { + logger.debug("StaticWQKmsArtifact.setup"); + + state = new StaticState(STATIC_STATE_NAME); + + List fs = new ArrayList(); + logger.debug(XMLUtils.toString(data)); + String code = XMLUtils.xpathString( + data, XPATH_DATA, ArtifactNamespaceContext.INSTANCE); + + // TODO Go for JSON, one day. + //ex.: flood_protection-wstv-114-12 + if (code != null) { + String [] parts = code.split("-"); + + if (parts.length >= 4) { + try { + int col = Integer.valueOf(parts[2]); + int wst = Integer.valueOf(parts[3]); + + addStringData("col_pos", parts[2]); + addStringData("wst_id", parts[3]); + + String wkmsName = WKmsFactory.getWKmsName(col, wst); + + String name; + if (parts[0].equals(HEIGHTMARKS_POINTS)) { + name = HEIGHTMARKS_POINTS; + } + else { + name = STATIC_WQKMS; + } + + Facet facet = new WQKmsFacet( + name, + Resources.getMsg( + callMeta, + wkmsName, + wkmsName)); + fs.add(facet); + facets.put(state.getID(), fs); + } + catch (Exception e) {} + } + } + + spawnState(); + super.setup(identifier, factory, context, callMeta, data); + } + + + /** + * Initialize the static state with output. + * @return static state + */ + protected State spawnState() { + state = new StaticState(STATIC_STATE_NAME); + List fs = facets.get(STATIC_STATE_NAME); + DefaultOutput output1 = new DefaultOutput( + "w_differences", + "w_differences.longitudinal_section", "image/png", + fs, + "chart"); + DefaultOutput output2 = new DefaultOutput( + "longitudinal_section", + "longitudinal_section.longitudinal_section", "image/png", + fs, + "chart"); + + state.getOutputs().add(output1); + state.getOutputs().add(output2); + return state; + } + + + /** + * Called via setup. + * + * @param artifact The master-artifact. + */ + @Override + protected void initialize( + Artifact artifact, + Object context, + CallMeta meta) + { + logger.debug("StaticWQKmsArtifact.initialize"); + WINFOArtifact winfo = (WINFOArtifact) artifact; + // TODO: The river is of no interest, so far. + addData("river", winfo.getData("river")); + } + + + /** + * Get a list containing the one and only State. + * @param context ignored. + * @return list with one and only state. + */ + @Override + protected List getStates(Object context) { + ArrayList states = new ArrayList(); + states.add(getState()); + return states; + } + + + /** + * Get the "current" state (there is but one). + * @param cc ignored. + * @return the "current" (only possible) state. + */ + @Override + public State getCurrentState(Object cc) { + return getState(); + } + + + /** + * Get the only possible state. + * @return the state. + */ + protected State getState() { + return getState(null, null); + } + + + /** + * Get the state. + * @param context ignored. + * @param stateID ignored. + * @return the state. + */ + @Override + protected State getState(Object context, String stateID) { + return (state != null) + ? state + : spawnState(); + } + + + /** + * Get WQKms from factory. + * @param TODO idx param is not needed + * @return WQKms according to parameterization (can be null); + */ + public WQKms getWQKms(int idx) { + logger.debug("StaticWQKmsArtifact.getWQKms"); + + return WQKmsFactory.getWQKms( + Integer.valueOf(getDataAsString("col_pos")), + Integer.valueOf(getDataAsString("wst_id"))); + } + + + /** + * Determines Facets initial disposition regarding activity (think of + * selection in Client ThemeList GUI). This will be checked one time + * when the facet enters a collections describe document. + * + * @param facetName name of the facet. + * @param index index of the facet. + * + * @return Always 0. Static Data will enter plots inactive. + */ + @Override + public int getInitialFacetActivity( + String outputName, + String facetName, + int index) + { + return 0; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r 982956bde69e -r 02cd002205a3 flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java --- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java Thu Nov 03 12:28:38 2011 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java Thu Nov 03 13:22:55 2011 +0000 @@ -34,6 +34,7 @@ String DURATION_Q = "duration_curve.q"; String STATIC_WKMS = "other.wkms"; + String STATIC_WQKMS = "other.wqkms"; String HEIGHTMARKS_POINTS = "heightmarks_points"; diff -r 982956bde69e -r 02cd002205a3 flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/StaticWQKmsCacheKey.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/StaticWQKmsCacheKey.java Thu Nov 03 13:22:55 2011 +0000 @@ -0,0 +1,33 @@ +package de.intevation.flys.artifacts.model; + +import java.io.Serializable; + +/** + * Caching-Key object for 'static' wst- data. + */ +public final class StaticWQKmsCacheKey +implements Serializable +{ + public static final String CACHE_NAME = "wst-wq--value-table-static"; + + private int column; + private int wst_id; + + public StaticWQKmsCacheKey(int column, int wst_id) { + this.wst_id = wst_id; + this.column = column; + } + + public int hashCode() { + return (wst_id << 8) | column; + } + + public boolean equals(Object other) { + if (!(other instanceof StaticWQKmsCacheKey)) { + return false; + } + StaticWQKmsCacheKey o = (StaticWQKmsCacheKey) other; + return wst_id == o.wst_id && this.column == o.column; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 982956bde69e -r 02cd002205a3 flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WQKmsFacet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WQKmsFacet.java Thu Nov 03 13:22:55 2011 +0000 @@ -0,0 +1,57 @@ +package de.intevation.flys.artifacts.model; + +import de.intevation.artifacts.Artifact; +import de.intevation.artifacts.CallContext; + +import de.intevation.artifactdatabase.state.DefaultFacet; + +import de.intevation.flys.artifacts.StaticWQKmsArtifact; +import de.intevation.flys.artifacts.model.FacetTypes; + +/** + * Facet to show W|Q|km Values. + */ +public class WQKmsFacet +extends DefaultFacet +implements FacetTypes { + + /** Trivial Constructor. */ + public WQKmsFacet(String description) { + this(STATIC_WQKMS, description); + } + + public WQKmsFacet(String name, String description) { + this.name = name; + this.description = description; + this.index = 0; + } + + + /** + * Returns the data this facet requires. + * + * @param artifact the owner artifact. + * @param context the CallContext (ignored). + * + * @return the data. + */ + @Override + public Object getData(Artifact artifact, CallContext context) { + StaticWQKmsArtifact staticData = + (StaticWQKmsArtifact) artifact; + return staticData.getWQKms(0); + } + + + /** + * Create a deep copy of this Facet. + * @return a deep copy. + */ + @Override + public WQKmsFacet deepCopy() { + WQKmsFacet copy = new WQKmsFacet(description); + copy.set(this); + return copy; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 982956bde69e -r 02cd002205a3 flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WQKmsFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WQKmsFactory.java Thu Nov 03 13:22:55 2011 +0000 @@ -0,0 +1,119 @@ +package de.intevation.flys.artifacts.model; + +import java.util.List; + +import net.sf.ehcache.Cache; +import net.sf.ehcache.Element; + +import org.apache.log4j.Logger; + +import org.hibernate.Session; + +import org.hibernate.SQLQuery; +import org.hibernate.type.StandardBasicTypes; + +import de.intevation.flys.artifacts.model.WQKms; + +import de.intevation.flys.artifacts.cache.CacheFactory; + +import de.intevation.flys.backend.SessionHolder; + +/** + * Factory to access ready-made WQKms for other (than computed) 'kinds' of + * WST-data. + */ +public class WQKmsFactory +{ + private static Logger log = Logger.getLogger(WQKmsFactory.class); + + /** Query to get km and wqs for wst_id and column_pos. */ + public static final String SQL_SELECT_WQS = + "SELECT position, w, q FROM wst_value_table " + + "WHERE wst_id = :wst_id AND column_pos = :column_pos"; + + /** Query to get name for wst_id and column_pos. */ + public static final String SQL_SELECT_NAME = + "SELECT name " + + "FROM wst_columns "+ + "WHERE wst_id = :wst_id AND position = :column_pos"; + + + /** Hidden constructor, use static methods instead. */ + private WQKmsFactory() { + ; + } + + + /** + * Get WKms for given column and wst_id, caring about the cache. + */ + public static WQKms getWQKms(int column, int wst_id) { + log.debug("WQKmsFactory.getWQKms"); + Cache cache = CacheFactory.getCache(StaticWQKmsCacheKey.CACHE_NAME); + + StaticWQKmsCacheKey cacheKey; + + if (cache != null) { + cacheKey = new StaticWQKmsCacheKey(wst_id, column); + Element element = cache.get(cacheKey); + if (element != null) { + log.debug("Got static wst values from cache"); + return (WQKms)element.getValue(); + } + } + else { + cacheKey = null; + } + + WQKms values = getWQKmsUncached(column, wst_id); + + if (values != null && cacheKey != null) { + log.debug("Store static wst values in cache."); + Element element = new Element(cacheKey, values); + cache.put(element); + } + return values; + } + + + /** + * Get WQKms from db. + * @param column the position columns value + * @param wst_id database id of the wst + * @return respective WQKms. + */ + public static WQKms getWQKmsUncached(int column, int wst_id) { + + if (log.isDebugEnabled()) { + log.debug("WQKmsFactory.getWQKmsUncached, column " + + column + ", wst_id " + wst_id); + } + + WQKms wqkms = new WQKms(WKmsFactory.getWKmsName(column, wst_id)); + + Session session = SessionHolder.HOLDER.get(); + SQLQuery sqlQuery = session.createSQLQuery(SQL_SELECT_WQS) + .addScalar("position", StandardBasicTypes.DOUBLE) + .addScalar("w", StandardBasicTypes.DOUBLE) + .addScalar("q", StandardBasicTypes.DOUBLE); + sqlQuery.setInteger("wst_id", wst_id); + sqlQuery.setInteger("column_pos", column); + + List results = sqlQuery.list(); + + double kms [] = new double[results.size()]; + double ws [] = new double[results.size()]; + double qs [] = new double[results.size()]; + + int lastColumn = Integer.MAX_VALUE; + + for (int i = 0, N = results.size(); i < N; i++) { + Object[] row = results.get(i); + // add(w, q, km) + wqkms.add((Double) row[1], (Double) row[2], (Double) row[0]); + } + + return wqkms; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :