Mercurial > dive4elements > gnv-client
view gnv-artifacts/src/main/java/de/intevation/gnv/state/MeasurementState.java @ 1062:58b4a07db856
Cach improvement: remove the cached elements of each visited state that is visited while stepping back to a previous state.
gnv-artifacts/trunk@1147 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Ingo Weinzierl <ingo.weinzierl@intevation.de> |
---|---|
date | Wed, 02 Jun 2010 09:52:39 +0000 |
parents | 9981452c7e75 |
children | aaacced2a0cc |
line wrap: on
line source
package de.intevation.gnv.state; import de.intevation.artifactdatabase.XMLUtils; import de.intevation.artifacts.CallContext; import de.intevation.artifacts.CallMeta; import de.intevation.gnv.artifacts.ressource.RessourceFactory; import de.intevation.gnv.geobackend.base.Result; import de.intevation.gnv.geobackend.base.ResultDescriptor; import de.intevation.gnv.state.describedata.ExtendedKeyValueData; import de.intevation.gnv.state.describedata.KeyValueDescibeData; import de.intevation.gnv.state.describedata.NamedArrayList; import de.intevation.gnv.state.describedata.NamedCollection; import de.intevation.gnv.state.exception.StateException; import de.intevation.gnv.utils.InputValidator; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.TreeMap; import org.apache.log4j.Logger; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; /** * This state handles input of measurements relating to a parameter. The user * interface description created by this class represents a matrix - each * parameter in a single row, each measurement in a column. An invalid * measurement column for a specific parameter is marked as disabled and should * not be selected. * * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> */ public class MeasurementState extends DefaultState { private static Logger logger = Logger.getLogger(MeasurementState.class); public static final String SQL_KEY_PARAMETERID = "PARAMETERID"; public static final String SEPARATOR = ";"; /** * This class is used to generate the Matrix in <code>MinMaxDateState</code>. * Parameter and Measurements are stored in separate lists and can be * requested via different methods. * * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> */ private class ParameterMatrix { private final Logger logger = Logger.getLogger(ParameterMatrix.class); private List measurements; private List mDescriptions; private List parameters; private boolean[][] values; /** * Constructs a new matrix. * * @param data A collection containing the measurements. * @param parameter An array of parameters. */ public ParameterMatrix(Collection data, String[] parameter) { measurements = new ArrayList(data.size()); mDescriptions = new ArrayList(data.size()); parameters = new ArrayList(parameter.length); values = new boolean[data.size()][parameter.length]; for (int i = 0; i < data.size(); i++) { Arrays.fill(values[i], false); } initParameters(parameter); initMeasurements(data); } /** * Initialize the measurements used in this matrix. * * @param data The measurements. */ private void initMeasurements(Collection data) { Iterator iter = data.iterator(); while (iter.hasNext()) { ExtendedKeyValueData value = (ExtendedKeyValueData) iter.next(); String key = value.getKey(); String val = value.getValue(); String parameter = value.getParameter(); int i = measurements.indexOf(key); int j = parameters.indexOf(parameter); int tmp = mDescriptions.indexOf(val); if (i < 0) { measurements.add(key); i = measurements.indexOf(key); } if (j < 0) { logger.warn("Not a valid parameter: " + parameter); } if (tmp < 0) { mDescriptions.add(val); tmp = mDescriptions.indexOf(val); } if (i >= 0 && i < measurements.size() && j >= 0 && j < parameters.size()) { values[i][j] = true; } } } /** * Initialize the parameters used in this matrix. * * @param parameter Parameters. */ private void initParameters(String[] parameter) { for (String param: parameter) { parameters.add(param); } } /** * Returns the number of measurements. * * @return the number of measurements. */ public int measurementSize() { if (measurements != null) return measurements.size(); return 0; } /** * Returns the number of parameters. * * @return number of parameters. */ public int parameterSize() { if (parameters != null) return parameters.size(); return 0; } /** * Returns the measurement at idx. * * @param idx Index. * @return the measurement. */ public String getMeasurement(int idx) { if (idx >= 0 && idx < measurements.size()) return (String) measurements.get(idx); logger.warn("Index is out of bounds: " + idx); return ""; } /** * Returns the parameter at idx. * * @param idx Index * @return the parameter. */ public String getParameter(int idx) { if (idx >= 0 && idx < parameters.size()) { return (String) parameters.get(idx); } logger.warn("Index is out of bounds: " + idx); return ""; } /** * Returns a description text for a specific measurement. * * @param idx Index of a measurement. * @return measurement's description. */ public String getMDescription(int idx) { if (mDescriptions != null) { return (String) mDescriptions.get(idx); } return null; } /** * This method returns true, if a measurement is valid for a specific * parameter - otherwise false. * * @param i Index of a measurement column. * @param j Index of a parameter row. * @return true, if valid, else false. */ public boolean isValid(int i, int j) { if (i < 0 || i > measurements.size() || j < 0 || j > parameters.size()) { logger.warn("Index out of bounds: " + i + "|" + j); return false; } return values[i][j]; } } // End of ParameterMatrix public MeasurementState() { super(); } @Override protected NamedCollection<KeyValueDescibeData> extractKVP( Collection<Result> result, String keyid, String valueid ) { NamedCollection<KeyValueDescibeData> kvdd = new NamedArrayList<KeyValueDescibeData>(dataName, result.size()); kvdd.setMultiSelect(true); int keyPos = -1; int valPos = -1; int parPos = -1; for (Result res: result) { if (keyPos < 0 || valPos < 0 || parPos < 0) { ResultDescriptor rd = res.getResultDescriptor(); keyPos = rd.getColumnIndex(keyid); valPos = rd.getColumnIndex(valueid); parPos = rd.getColumnIndex(SQL_KEY_PARAMETERID); } kvdd.add(new ExtendedKeyValueData( res.getString(keyPos), res.getString(valPos), getID(), res.getString(parPos))); } return kvdd; } /** * This method create the user interface description for measurement and * parameters as matrix. A row for each parameter, a column for each * measurement. */ @Override protected void appendToDynamicNode( XMLUtils.ElementCreator artCreator, XMLUtils.ElementCreator creator, Document document, Node dynamicNode, CallMeta callMeta, Object o ) { NamedArrayList all = (NamedArrayList) o; String name = all.getName(); RessourceFactory factory = RessourceFactory.getInstance(); Element matrixNode = creator.create("group"); Element matrixLabel = creator.create("label"); matrixLabel.setTextContent(factory.getRessource( callMeta.getLanguages(), all.getName(), all.getName())); creator.addAttr(matrixNode, "mode", "matrix"); matrixNode.appendChild(matrixLabel); InputData inputParam = inputData.get("parameterid"); ParameterMatrix matrix = new ParameterMatrix(all, inputParam.splitValue()); int measurements = matrix.measurementSize(); int parameters = matrix.parameterSize(); for (int i = 0; i < parameters; i++) { Element select = creator.create("select"); String param = matrix.getParameter(i); creator.addAttr(select, "label", inputParam.getDescription(param)); creator.addAttr(select, "ref", name); for (int j = 0; j < measurements; j++) { Element item = creator.create("item"); Element label = creator.create("label"); Element value = creator.create("value"); creator.addAttr(item, "ref", name); creator.addAttr( item, "parameter", matrix.getMDescription(j)); if (!matrix.isValid(j, i)) { creator.addAttr(item, "disabled", "true"); } else { creator.addAttr(item, "disabled", "false"); } String tmpValue = matrix.getMeasurement(j) + ";" + param; label.setTextContent(matrix.getMDescription(j)); value.setTextContent(tmpValue); item.appendChild(label); item.appendChild(value); select.appendChild(item); } matrixNode.appendChild(select); } dynamicNode.appendChild(matrixNode); } /** * This feed takes some input data storing measurement ids and parameter ids * and put them into ExtendedInputData objects to save the relation between * a measurement and the parameter it belongs to. */ @Override public Document feed( CallContext context, Collection<InputData> input, String uuid) throws StateException { RessourceFactory resFactory = RessourceFactory.getInstance(); Locale[] serverLocales = resFactory.getLocales(); Locale locale = context.getMeta().getPreferredLocale( serverLocales); if (input == null) { String msg = resFactory.getRessource( locale, EXCEPTION_NO_INPUT, EXCEPTION_NO_INPUT); logger.warn(msg); return feedFailure(msg); } for(InputData item: input) { String name = item.getName(); InputValue inputValue = inputValues.get(name); String[] tupel = extractValuesAndParams(item.getValue()); String type = inputValue.getType(); if (inputValue == null) { String msg = resFactory.getRessource( locale, EXCEPTION_INVALID_INPUT, EXCEPTION_INVALID_INPUT); logger.warn(msg); return feedFailure(msg); } if (!InputValidator.isInputValid(tupel[0], type)) { String msg = resFactory.getRessource( locale, EXCEPTION_INVALID_INPUT, EXCEPTION_INVALID_INPUT); logger.warn(msg); return feedFailure(msg); } if (inputData == null) { inputData = new TreeMap<String, InputData>(); } ExtendedInputData extended = new ExtendedInputData( name, tupel[0], item.getObject(), tupel[1]); if (name.equals(dataName)) { String[] desc = getDescriptionForInputData( extended, context, uuid); extended.setDescription(desc); } inputData.put(name, extended); } return feedSuccess(); } /** * Extract parameter ids and measurement ids from DefaultInputData objects * and return an array. In the first position of this array, the measurement * ids are placed, in the second position the parameter ids - all separated * by a character. * * @param tmp String containing measurement ids and parameter ids. * @return An array with separated measurements and parameters. */ protected String[] extractValuesAndParams(String tmp) { String[] array = tmp.split(DefaultInputData.VALUE_SEPARATOR); String[] extracted = new String[2]; for (String item: array) { String[] tupel = item.split(ExtendedInputData.SEPARATOR); if (extracted[0] == null) { extracted[0] = tupel[0]; } else { extracted[0] += DefaultInputData.VALUE_SEPARATOR + tupel[0]; } if (extracted[1] == null) { extracted[1] = tupel[1]; } else { extracted[1] += DefaultInputData.VALUE_SEPARATOR + tupel[1]; } } logger.debug("VALUES RESULT: " + extracted[0]); logger.debug("PARAMS RESULT: " + extracted[1]); return extracted; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :