Mercurial > dive4elements > gnv-client
view gnv-artifacts/src/main/java/de/intevation/gnv/transition/TransitionBase.java @ 307:f0f106c7b906
Fixed some broken Method-Extentions.
Added some null-value checks.
gnv-artifacts/trunk@365 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Tim Englich <tim.englich@intevation.de> |
---|---|
date | Tue, 24 Nov 2009 14:39:36 +0000 |
parents | ce408af0ee57 |
children | 251f16a083f8 |
line wrap: on
line source
/** * */ package de.intevation.gnv.transition; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.log4j.Logger; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import de.intevation.artifactdatabase.Config; import de.intevation.artifacts.CallMeta; import de.intevation.gnv.artifacts.GNVArtifactBase; import de.intevation.gnv.artifacts.cache.CacheFactory; import de.intevation.gnv.artifacts.ressource.RessourceFactory; import de.intevation.gnv.geobackend.base.Result; import de.intevation.gnv.geobackend.base.query.QueryExecutor; import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; import de.intevation.gnv.geobackend.base.query.exception.QueryException; import de.intevation.gnv.geobackend.util.DateUtils; import de.intevation.gnv.transition.describedata.DefaultKeyValueDescribeData; import de.intevation.gnv.transition.describedata.KeyValueDescibeData; import de.intevation.gnv.transition.describedata.MinMaxDescribeData; import de.intevation.gnv.transition.describedata.NamedArrayList; import de.intevation.gnv.transition.describedata.NamedCollection; import de.intevation.gnv.transition.describedata.SingleValueDescribeData; import de.intevation.gnv.transition.exception.TransitionException; import de.intevation.gnv.utils.ArtifactXMLUtilities; import de.intevation.gnv.utils.InputValidator; /** * @author Tim Englich <tim.englich@intevation.de> * */ public abstract class TransitionBase implements Transition { /** * The UID of this Class */ private static final long serialVersionUID = 2411169179001645426L; /** * the logger, used to log exceptions and additonaly information */ private static Logger log = Logger.getLogger(GNVArtifactBase.class); private final static String MINVALUEFIELDNAME = "minvalue"; private final static String MAXVALUEFIELDNAME = "maxvalue"; private final static String NODATASELECTIONKEY = "n/n"; private final static String DESCRIBEDATAKEY = "_DESCRIBEDATA"; private String id = null; private String description = null; protected String dataName = null; protected boolean dataMultiSelect = false; protected boolean dataNoSelect = false; protected String queryID = null; private Collection<String> reachableTransitions = null; private Transition alternativeTransition = null; protected Collection<String> inputValueNames = null; private Map<String, InputValue> inputValues = null; private Transition parent = null; protected Map<String, InputData> inputData = null; /** * Constructor */ public TransitionBase() { super(); } /** * @see de.intevation.gnv.transition.Transition#getID() */ public String getID() { return this.id; } /** * @see de.intevation.gnv.transition.Transition#getDescription() */ public String getDescription() { return this.description; } /** * @see de.intevation.gnv.transition.Transition#reachableTransitions() */ public Collection<String> reachableTransitions() { if (this.couldAlternativeTransitionUsed()){ return this.alternativeTransition.reachableTransitions(); }else{ return this.reachableTransitions; } } /** * @return */ private boolean couldAlternativeTransitionUsed() { // TODO das muss hier noch etwas freier gestaltet werden. Object[] inputValues = this.inputValueNames.toArray(); String key = (String)inputValues[inputValues.length-1]; boolean returnValue= this.alternativeTransition != null && this.inputData != null && this.inputData.containsKey(key) && this.inputData.get(key).getValue(). equals(NODATASELECTIONKEY); return returnValue; } /** * @see de.intevation.gnv.transition.Transition#getRequiredInputValues() */ public Collection<InputValue> getRequiredInputValues() { return this.inputValues.values(); } /** * @see de.intevation.gnv.transition.Transition#setup(org.w3c.dom.Node) */ public void setup(Node configuration) { log.debug("TransitionBase.setup"); this.id = ((Element)configuration).getAttribute("id"); this.description = ((Element)configuration).getAttribute("description"); log.info("Transition-ID = " + this.id); NodeList nodes = Config.getNodeSetXPath(configuration, "reachableTransitions/transition"); this.reachableTransitions = new ArrayList<String>(nodes.getLength()); for (int i = 0; i < nodes.getLength(); i++) { String reachableTransition = nodes.item(i).getTextContent(); log.info("ReachableTransition ==> " + reachableTransition); this.reachableTransitions.add(reachableTransition); } Node alternativeTransitionNode = Config.getNodeXPath(configuration, "alternativeTransition/transition"); if (alternativeTransitionNode != null){ this.alternativeTransition = TransitionFactory.getInstance() .createTransition(alternativeTransitionNode); } NodeList inputValuesNodes = Config.getNodeSetXPath(configuration, "inputvalues/inputvalue"); this.inputValues = new HashMap<String, InputValue>(inputValuesNodes .getLength()); this.inputValueNames = new ArrayList<String>(inputValuesNodes .getLength()); for (int i = 0; i < inputValuesNodes.getLength(); i++) { Element inputValueNode = (Element)inputValuesNodes.item(i); String usedinQueryValue = inputValueNode.getAttribute("usedinquery"); int usedinQuery = 1; if (usedinQueryValue != null) { try { usedinQuery = Integer.parseInt(usedinQueryValue); } catch (NumberFormatException e) { log .warn("Used in Query Value cannot be transformed into a Number"); } } InputValue inputValue = new DefaultInputValue(inputValueNode.getAttribute("name"), inputValueNode.getAttribute("type"), Boolean.parseBoolean(inputValueNode. getAttribute("multiselect")), usedinQuery); log.debug(inputValue.toString()); this.inputValues.put(inputValue.getName(), inputValue); this.inputValueNames.add(inputValue.getName()); } this.queryID = Config.getStringXPath(configuration, "queryID"); log.info("QueryID ==> " + this.queryID); this.dataName = Config.getStringXPath(configuration, "dataname"); String dataMultiSelectValue = Config.getStringXPath(configuration, "data-multiselect"); if (dataMultiSelectValue != null) { this.dataMultiSelect = Boolean.parseBoolean(dataMultiSelectValue); } String dataNoSelectValue =Config.getStringXPath(configuration, "data-noselect"); if (dataNoSelectValue != null) { this. dataNoSelect = Boolean.parseBoolean(dataNoSelectValue); } } /** * @see de.intevation.gnv.transition.Transition#getParent() */ public Transition getParent() { return this.parent; } /** * @see de.intevation.gnv.transition.Transition#setParent(de.intevation.gnv.transition.Transition) */ public void setParent(Transition transition) { this.parent = transition; } /** * @see de.intevation.gnv.transition.Transition#putInputData(java.util.Collection) */ public void putInputData(Collection<InputData> inputData, String uuid) throws TransitionException { log.debug("TransitionBase.putInputData"); if (inputData != null) { Iterator<InputData> it = inputData.iterator(); InputValidator iv = new InputValidator(); while (it.hasNext()) { InputData tmpItem = it.next(); InputValue inputValue = this.inputValues.get(tmpItem.getName()); if (inputValue != null) { if (this.inputData == null) { this.inputData = new HashMap<String, InputData>( inputData.size()); } boolean valid = iv.isInputValid(tmpItem.getValue(), inputValue.getType()); if (valid) { if (tmpItem.getName().equals(MINVALUEFIELDNAME)){ String minValue = tmpItem.getValue(); String maxValue = this.getInputValue4ID(inputData, MAXVALUEFIELDNAME); valid = iv.isInputValid(maxValue,inputValue.getType()); if (!valid){ String errMsg = "Wrong input for " + tmpItem.getValue() + " is not an " + inputValue.getType() + " Value."; log.warn(errMsg); throw new TransitionException(errMsg); } valid = iv.isInputValid(minValue, maxValue, inputValue.getType()); if (!valid){ String errMsg = "MaxValue-Input is less than MinValue-Input "; log.warn(errMsg); throw new TransitionException(errMsg); } }else if (tmpItem.getName().equals(MAXVALUEFIELDNAME)){ String minValue = this.getInputValue4ID(inputData, MINVALUEFIELDNAME); String maxValue = tmpItem.getValue(); valid = iv.isInputValid(minValue,inputValue.getType()); if (!valid){ String errMsg = "Wrong input for " + tmpItem.getValue() + " is not an " + inputValue.getType() + " Value."; log.warn(errMsg); throw new TransitionException(errMsg); } valid = iv.isInputValid(minValue, maxValue, inputValue.getType()); if (!valid){ String errMsg = "MaxValue-Input is less than MinValue-Input "; log.warn(errMsg); throw new TransitionException(errMsg); } } this.setSelection(tmpItem, uuid); this.inputData.put(tmpItem.getName(), tmpItem); } else { String errMsg = "Wrong input for " + tmpItem.getValue() + " is not an " + inputValue.getType() + " Value."; log.warn(errMsg); throw new TransitionException(errMsg); } } else { String errMsg = "No Inputvalue given for Inputdata " + tmpItem.getName(); log.warn(errMsg + "Value will be ignored"); } } } else { log.warn("No Inputdata given"); } } private String getInputValue4ID(Collection<InputData> inputData, String inputName){ Iterator<InputData> it = inputData.iterator(); while (it.hasNext()) { InputData tmpItem = it.next(); if (tmpItem.getName().equals(inputName)){ return tmpItem.getValue(); } } return null; } private void setSelection(InputData inputData, String uuid) { log.debug("TransitionBase.setSelection"); Object o = this.getDescribeData(inputData.getName(),uuid); if (o != null) { if (o instanceof Collection<?>) { Collection<KeyValueDescibeData> values = (Collection<KeyValueDescibeData>) o; String value = inputData.getValue(); String[] selectedValues = value.split(","); Set<String> selectedItems = new HashSet<String>( selectedValues.length); for (int i = 0; i < selectedValues.length; i++) { selectedItems.add(selectedValues[i].trim()); } // Selektion umsetzen Iterator<KeyValueDescibeData> it = values.iterator(); while (it.hasNext()) { KeyValueDescibeData data = it.next(); String key = "" + data.getKey(); boolean selected = selectedItems.contains(key); data.setSelected(selected); } } else if (o instanceof MinMaxDescribeData) { MinMaxDescribeData data = (MinMaxDescribeData) o; if (inputData.getName().equals(MINVALUEFIELDNAME)) { data.setMinValue(inputData.getValue()); } if (inputData.getName().equals(MAXVALUEFIELDNAME)) { data.setMaxValue(inputData.getValue()); } } else if (o instanceof SingleValueDescribeData) { ((SingleValueDescribeData)o).setValue(inputData.getValue()); } } } private Object getDescribeData(String name, String uuid) { log.debug("TransitionBase.getDescribeData"); Collection<Object> descibeData = this.getDescibeData(uuid); if (descibeData != null) { Iterator<Object> it = descibeData.iterator(); while (it.hasNext()) { Object o = it.next(); if (o instanceof NamedCollection<?>) { if (name.equals(((NamedCollection<?>) o).getName())) { return o; } } else if (o instanceof MinMaxDescribeData) { if (name.equals(((MinMaxDescribeData) o).getMinName())) { return o; } if (name.equals(((MinMaxDescribeData) o).getMaxName())) { return o; } }else if (o instanceof SingleValueDescribeData) { if (name.equals(((SingleValueDescribeData)o).getName())){ return o; } } } } return null; } /** * @see de.intevation.gnv.transition.Transition#isTransitionReachable(java.lang.String) */ public boolean isTransitionReachable(String transitionID) { log.debug("TransitionBase.isTransitionReachable"); boolean returnValue = false; if (this.couldAlternativeTransitionUsed()){ return alternativeTransition.isTransitionReachable(transitionID); }else{ Iterator<String> transitions = reachableTransitions.iterator(); while (transitions.hasNext()) { if (transitions.next().equals(transitionID)) { log.debug("Transition " + transitionID + " wird unterst�tzt."); returnValue = true; break; } } } return returnValue; } /** * @see de.intevation.gnv.transition.Transition#advance(java.lang.String, * de.intevation.artifacts.CallMeta) */ public void advance(String uuid, CallMeta callMeta) throws TransitionException { log.debug("TransitionBase.advance"); if (this.couldAlternativeTransitionUsed()){ this.alternativeTransition.setParent(this.getParent()); this.alternativeTransition.putInputData(this.inputData != null ? this.inputData.values() : null,uuid); this.alternativeTransition.advance(uuid, callMeta); }else{ try { String[] filterValues = this.generateFilterValuesFromInputData(); Collection<Result> result = null; try { if (this.queryID != null) { QueryExecutor queryExecutor = QueryExecutorFactory .getInstance().getQueryExecutor(); result = queryExecutor.executeQuery(this.queryID, filterValues); } this.purifyResult(result, uuid); } catch (RuntimeException e) { log.error(e, e); } } catch (QueryException e) { log.error(e, e); throw new TransitionException(e); } } } /** * @return */ protected String[] generateFilterValuesFromInputData() { List<String> list = new ArrayList<String>(); Iterator<String> it = this.inputValueNames.iterator(); while (it.hasNext()) { String value = it.next(); InputData data = this.inputData.get(value); if (data != null && this.inputValues.containsKey(data.getName())) { int size = this.inputValues.get(data.getName()) .usedInQueries(); String type = this.inputValues.get(data.getName()) .getType(); String requestValue = data.getValue(); if (type.equalsIgnoreCase("string")) { requestValue = this .prepareInputData4DBQuery(requestValue); } else if (type.equalsIgnoreCase("date")) { requestValue = this .prepareInputData4DateDBQuery(requestValue); } else if (type.equalsIgnoreCase("coordinate")){ requestValue = this .prepareInputData4RegionDBQuery(requestValue); } for (int j = 0; j < size; j++) { list.add(requestValue); } } } String[] filterValues = list.toArray(new String[0]); return filterValues; } protected String prepareInputData4RegionDBQuery(String value){ return value; } private String prepareInputData4DateDBQuery(String value) { log.debug("TransitionBase.prepareInputData4DateDBQuery"); if (value != null) { String[] values = value.split(","); String newValue = ""; for (int i = 0; i < values.length; i++) { if (newValue.length() > 0) { newValue = newValue + " , "; } // TODO JUST HACK FIND A BETTER RESOLUTION newValue = newValue + "to_date('" + values[i].trim() + "', 'YYYY.MM.DD HH24:MI:SS')"; } return newValue; } return value; } private String prepareInputData4DBQuery(String value) { log.debug("TransitionBase.prepareInputData4DBQuery"); if (value != null) { String[] values = value.split(","); String newValue = ""; for (int i = 0; i < values.length; i++) { if (newValue.length() > 0) { newValue = newValue + " , "; } newValue = newValue + "'" + values[i].trim() + "'"; } return newValue; } return value; } /** * @param result */ protected void purifyResult(Collection<Result> result, String uuid) { log.debug("TransitionBase.purifyResult"); Collection<Object> describeData = this.getDescibeData(uuid); if (describeData == null) { describeData = new ArrayList<Object>(); } NamedCollection<KeyValueDescibeData> keyValueDescibeData = extractKVP(result, "KEY", "VALUE"); describeData.add(keyValueDescibeData); this.setDescibeData(uuid, describeData); } /** * @param result * @return */ protected NamedCollection<KeyValueDescibeData> extractKVP(Collection<Result> result, String keyid, String valueid) { Iterator<Result> rit = result.iterator(); int dataSize = (this.dataNoSelect ? result.size()+1 : result.size()); NamedCollection<KeyValueDescibeData> keyValueDescibeData = new NamedArrayList<KeyValueDescibeData>( this.dataName, dataSize); keyValueDescibeData.setMultiSelect(this.dataMultiSelect); if (this.dataNoSelect){ keyValueDescibeData.add(new DefaultKeyValueDescribeData(NODATASELECTIONKEY, "No Selection")); } String previousKey = null; while (rit.hasNext()) { Result resultValue = rit.next(); String tmpKey = resultValue.getString(keyid); // TODO: HACK da die ARCSDE kein DISTINCT auf r�umlichen Anfragen unterst�tzt. if (previousKey == null || !tmpKey.equals(previousKey)){ previousKey = tmpKey; keyValueDescibeData.add(new DefaultKeyValueDescribeData(tmpKey, resultValue.getString(valueid))); } } return keyValueDescibeData; } /** * @see de.intevation.gnv.transition.Transition#describe(org.w3c.dom.Document, * org.w3c.dom.Node, de.intevation.artifacts.CallMeta, * java.lang.String) */ public void describe(Document document, Node rootNode, CallMeta callMeta,String uuid) { log.debug("TransitionBase.describe"); Collection<Object> descibeData = this.getDescibeData(uuid); if (descibeData != null) { ArtifactXMLUtilities xmlutilities = new ArtifactXMLUtilities(); Iterator<Object> it = descibeData.iterator(); Node staticNode = xmlutilities.createArtifactElement(document, "static"); Node dynamic = xmlutilities.createArtifactElement(document, "dynamic"); rootNode.appendChild(staticNode); rootNode.appendChild(dynamic); while (it.hasNext()) { Object o = it.next(); if (o instanceof Collection<?>) { String name = null; boolean multiselect = false; if (o instanceof NamedCollection<?>) { NamedCollection<?> nc = ((NamedCollection<?>) o); name = nc.getName(); multiselect = nc.isMultiSelect(); } else { Object[] names = this.inputValueNames.toArray(); name = names[names.length - 1].toString(); } Element selectNode = xmlutilities.createXFormElement( document, multiselect ? "select" : "select1"); selectNode.setAttribute("ref", name); Element lableNode = xmlutilities.createXFormElement( document, "label"); lableNode.setTextContent(RessourceFactory.getInstance() .getRessource(callMeta.getLanguages(), name, name)); Element choiceNode = xmlutilities.createXFormElement( document, "choices"); Collection<KeyValueDescibeData> values = (Collection<KeyValueDescibeData>) o; Iterator<KeyValueDescibeData> resultIt = values.iterator(); while (resultIt.hasNext()) { KeyValueDescibeData result = resultIt.next(); Element itemNode = xmlutilities.createXFormElement( document, "item"); if (result.isSelected()) { itemNode.setAttribute("selected", "true"); } Element choiceLableNode = xmlutilities .createXFormElement(document, "label"); choiceLableNode.setTextContent(result.getValue()); itemNode.appendChild(choiceLableNode); Element choicValueNode = xmlutilities .createXFormElement(document, "value"); choicValueNode.setTextContent("" + result.getKey()); itemNode.appendChild(choicValueNode); choiceNode.appendChild(itemNode); } selectNode.appendChild(lableNode); selectNode.appendChild(choiceNode); if (!it.hasNext()) { dynamic.appendChild(selectNode); } else { staticNode.appendChild(selectNode); } } else if (o instanceof MinMaxDescribeData) { MinMaxDescribeData minMaxDescibeData = (MinMaxDescribeData) o; Object min = minMaxDescibeData.getMinValue(); Object max = minMaxDescibeData.getMaxValue(); if (min instanceof GregorianCalendar) { Date d = ((GregorianCalendar) min).getTime(); min = DateUtils.getPatternedDateAmer(d); } if (max instanceof GregorianCalendar) { Date d = ((GregorianCalendar) max).getTime(); max = DateUtils.getPatternedDateAmer(d); } Element groupNode = xmlutilities.createXFormElement( document, "group"); groupNode.setAttribute("ref", minMaxDescibeData.getName()); Element groupNodeLableNode = xmlutilities .createXFormElement(document, "label"); groupNodeLableNode.setTextContent(RessourceFactory .getInstance().getRessource( callMeta.getLanguages(), minMaxDescibeData.getName(), minMaxDescibeData.getName())); groupNode.appendChild(groupNodeLableNode); Element inputMinNode = xmlutilities.createXFormElement( document, "input"); inputMinNode.setAttribute("ref", MINVALUEFIELDNAME); Element inputMinLableNode = xmlutilities .createXFormElement(document, "label"); inputMinLableNode.setTextContent(RessourceFactory .getInstance().getRessource( callMeta.getLanguages(), MINVALUEFIELDNAME, MINVALUEFIELDNAME)); inputMinNode.appendChild(inputMinLableNode); Element inputMinValueNode = xmlutilities .createXFormElement(document, "value"); inputMinValueNode.setTextContent(min.toString()); inputMinNode.appendChild(inputMinValueNode); Element inputMaxNode = xmlutilities.createXFormElement( document, "input"); inputMaxNode.setAttribute("ref", MAXVALUEFIELDNAME); Element inputMaxLableNode = xmlutilities .createXFormElement(document, "label"); inputMaxLableNode.setTextContent(RessourceFactory .getInstance().getRessource( callMeta.getLanguages(), MAXVALUEFIELDNAME, MAXVALUEFIELDNAME)); inputMaxNode.appendChild(inputMaxLableNode); Element inputMaxValueNode = xmlutilities .createXFormElement(document, "value"); inputMaxValueNode.setTextContent(max.toString()); inputMaxNode.appendChild(inputMaxValueNode); groupNode.appendChild(inputMinNode); groupNode.appendChild(inputMaxNode); if (!it.hasNext()) { dynamic.appendChild(groupNode); } else { staticNode.appendChild(groupNode); } } else if (o instanceof SingleValueDescribeData) { SingleValueDescribeData svdb = (SingleValueDescribeData) o; Element groupNode = xmlutilities.createXFormElement( document, "group"); groupNode.setAttribute("ref", svdb.getName()); Element groupNodeLableNode = xmlutilities .createXFormElement(document, "label"); groupNodeLableNode.setTextContent(RessourceFactory .getInstance().getRessource( callMeta.getLanguages(), svdb.getName(), svdb.getName())); groupNode.appendChild(groupNodeLableNode); Element inputNode = xmlutilities.createXFormElement( document, "input"); inputNode.setAttribute("ref", svdb.getName()); Element inputLableNode = xmlutilities.createXFormElement( document, "label"); inputLableNode.setTextContent(""); inputNode.appendChild(inputLableNode); Element inputValueNode = xmlutilities.createXFormElement( document, "value"); inputValueNode.setTextContent(svdb.getValue()); inputNode.appendChild(inputValueNode); groupNode.appendChild(inputNode); if (!it.hasNext()) { dynamic.appendChild(groupNode); } else { staticNode.appendChild(groupNode); } } } } } /** * @see de.intevation.gnv.transition.Transition#getDescibeData() */ protected Collection<Object> getDescibeData(String uuid) { if (CacheFactory.getInstance().isInitialized()) { String key = uuid + DESCRIBEDATAKEY; log.debug("Hash for Queryelements: " + key); net.sf.ehcache.Element value = CacheFactory.getInstance().getCache().get(key); if (value != null) { return (Collection<Object>) (value.getObjectValue()); } } return null; } /** * @see de.intevation.gnv.transition.Transition#getDescibeData() */ protected void setDescibeData(String uuid, Collection<Object> describeData) { if (CacheFactory.getInstance().isInitialized()) { String key = uuid + DESCRIBEDATAKEY; log.debug("Hash for Queryelements: " + key); CacheFactory.getInstance().getCache().put(new net.sf.ehcache.Element(key, describeData)); } } /** * @see de.intevation.gnv.transition.Transition#getInputData() */ public Collection<InputData> getInputData() throws TransitionException { if (this.couldAlternativeTransitionUsed()){ return this.alternativeTransition.getInputData(); }else{ return this.inputData != null ? this.inputData.values() : null; } } }