tim@335: /** tim@335: * tim@335: */ tim@335: package de.intevation.gnv.state; tim@335: tim@335: import java.io.OutputStream; tim@335: import java.util.ArrayList; tim@335: import java.util.Collection; ingo@610: import java.util.HashMap; ingo@610: import java.util.Iterator; ingo@626: import java.util.List; tim@335: import java.util.Locale; tim@335: ingo@626: import javax.xml.xpath.XPathConstants; ingo@626: ingo@631: import net.sf.ehcache.Cache; ingo@631: sascha@480: import org.apache.log4j.Logger; tim@335: import org.w3c.dom.Document; tim@335: import org.w3c.dom.Element; tim@335: import org.w3c.dom.Node; tim@335: import org.w3c.dom.NodeList; tim@335: tim@616: import de.intevation.artifactdatabase.Config; ingo@626: import de.intevation.artifactdatabase.XMLUtils; tim@616: import de.intevation.artifacts.CallContext; tim@616: import de.intevation.artifacts.CallMeta; tim@616: import de.intevation.gnv.artifacts.cache.CacheFactory; tim@616: import de.intevation.gnv.artifacts.ressource.RessourceFactory; tim@616: import de.intevation.gnv.geobackend.base.Result; tim@616: import de.intevation.gnv.geobackend.base.query.QueryExecutor; tim@616: import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; tim@616: import de.intevation.gnv.geobackend.base.query.exception.QueryException; tim@616: import de.intevation.gnv.state.describedata.MinMaxDescribeData; tim@616: import de.intevation.gnv.state.exception.StateException; tim@616: import de.intevation.gnv.utils.InputValidator; tim@616: tim@335: /** tim@335: * @author Tim Englich tim@335: * tim@335: */ sascha@480: public abstract class OutputStateBase sascha@480: extends StateBase sascha@480: implements OutputState sascha@480: { sascha@480: public static final String XPATH_OUTPUT_MODE = sascha@480: "/art:action/art:out/@name"; sascha@480: sascha@480: public static final String XPATH_MIME_TYPE = sascha@480: "/art:action/art:out/art:mime-type/@value"; tim@335: ingo@626: public static final String XPATH_EXPORTS = ingo@626: "exportModes/export"; ingo@626: tim@335: /** tim@335: * The UID of this Class tim@335: */ tim@335: private static final long serialVersionUID = -1718732895737303823L; tim@335: tim@335: /** tim@335: * the logger, used to log exceptions and additonaly information tim@335: */ tim@335: private static Logger log = Logger.getLogger(OutputStateBase.class); tim@335: tim@335: /** tim@335: * The different Outputmodes which are provided by an OutputState tim@335: */ tim@335: protected Collection outputModes = null; tim@335: tim@335: protected String queryODVID = null; tim@335: tim@335: /** tim@335: * Constructor tim@335: */ tim@335: public OutputStateBase() { tim@335: super(); tim@335: } tim@335: tim@335: /** tim@335: * @see de.intevation.gnv.state.OutputState#getOutputModes() tim@335: */ tim@335: public Collection getOutputModes() { tim@335: log.debug("OutputStateBase.getOutputModes"); tim@335: return this.outputModes; tim@335: } tim@335: tim@335: /** tim@335: * @see de.intevation.gnv.state.StateBase#setup(org.w3c.dom.Node) tim@335: */ tim@335: @Override tim@335: public void setup(Node configuration) { tim@335: log.debug("OutputStateBase.setup"); tim@335: super.setup(configuration); tim@335: tim@335: this.queryODVID = Config.getStringXPath(configuration,"queryID-odv"); tim@335: tim@335: NodeList outputModeList = Config.getNodeSetXPath(configuration, tim@335: "outputsModes/outputsMode"); tim@335: if (outputModeList != null) { tim@335: log.debug(outputModeList.getLength() + " were found."); tim@335: this.outputModes = new ArrayList(outputModeList tim@335: .getLength()); tim@335: for (int i = 0; i < outputModeList.getLength(); i++) { tim@335: Element currentNode = (Element)outputModeList.item(i); tim@335: String name = currentNode.getAttribute("name"); tim@335: String description =currentNode.getAttribute("description"); tim@335: String mimeType = currentNode.getAttribute("mime-type"); tim@335: NodeList inputValuesList = Config.getNodeSetXPath(currentNode, tim@335: "parameters/inputvalue"); tim@335: Collection inputParameters = null; tim@335: if (inputValuesList != null) { tim@335: inputParameters = new ArrayList(inputValuesList tim@335: .getLength()); tim@335: for (int j = 0; j < inputValuesList.getLength(); j++) { tim@335: Element currentInputValuesNode = (Element)inputValuesList.item(j); tim@335: String inputValueName = currentInputValuesNode.getAttribute("name"); tim@335: String inputValueType = currentInputValuesNode.getAttribute("type"); tim@335: String defaultValue =currentInputValuesNode.getAttribute("value"); tim@335: boolean isMultiselect = false; tim@335: InputValue inputValue = new DefaultInputValue( tim@335: inputValueName, inputValueType, defaultValue, tim@335: isMultiselect); tim@335: inputParameters.add(inputValue); tim@335: } tim@335: } tim@335: ingo@626: // parse export modes ingo@626: List exportList = null; ingo@626: NodeList exports = (NodeList) XMLUtils.xpath( ingo@626: currentNode, XPATH_EXPORTS, XPathConstants.NODESET); ingo@626: ingo@626: if (exports != null) { ingo@626: int exportSize = exports.getLength(); ingo@626: ingo@626: exportList = new ArrayList(exportSize); ingo@626: for (int k = 0; k < exportSize; k++) { ingo@626: Element exp = (Element) exports.item(k); ingo@626: String expName = exp.getAttribute("name"); ingo@626: String expDesc = exp.getAttribute("description"); ingo@626: String expMime = exp.getAttribute("mime-type"); ingo@626: ingo@626: exportList.add( ingo@626: new DefaultExportMode(expName, expDesc, expMime)); ingo@626: } ingo@626: } ingo@626: tim@335: OutputMode outputMode = new DefaultOutputMode(name, ingo@626: description, mimeType, inputParameters, exportList); tim@335: log.debug(outputMode.toString()); tim@335: this.outputModes.add(outputMode); tim@335: tim@335: } tim@335: } tim@335: } tim@335: tim@335: /** tim@335: * @see de.intevation.gnv.state.StateBase#advance() tim@335: */ tim@335: @Override ingo@493: public void advance(String uuid, CallContext context) ingo@493: throws StateException ingo@493: { tim@335: } tim@335: tim@335: @Override ingo@493: public void initialize(String uuid, CallContext context) ingo@493: throws StateException ingo@493: { tim@335: } tim@335: sascha@480: public void out( sascha@480: Document format, sascha@480: Collection inputData, sascha@480: OutputStream outputStream, sascha@480: String uuid, sascha@480: CallMeta callMeta sascha@480: ) sascha@480: throws StateException sascha@480: { tim@335: } tim@335: tim@335: /** tim@335: * @see de.intevation.gnv.state.OutputState#out(java.lang.String, tim@335: * java.util.Collection, java.io.OutputStream) tim@335: */ tim@335: public void out(String outputMode, Collection inputData, tim@335: OutputStream outputStream) throws StateException { tim@335: } tim@335: tim@335: /** tim@335: * @return tim@335: */ sascha@439: protected Object getChartResult(String uuid, CallContext callContext) { tim@335: log.debug("OutputStateBase.getChartResult"); ingo@631: CacheFactory factory = CacheFactory.getInstance(); ingo@631: ingo@631: if (factory.isInitialized()) { ingo@631: // we use a cache ingo@631: log.info("Using cache."); ingo@631: Cache cache = factory.getCache(); ingo@631: String key = "chart_" + getHash(); ingo@631: ingo@631: net.sf.ehcache.Element value = cache.get(key); tim@335: if (value != null) { ingo@631: log.debug("Found element in cache."); ingo@631: return value.getObjectValue(); ingo@631: } ingo@631: else { ingo@631: log.debug("Element not in cache, we need to ask the database"); ingo@631: Object result = getData(queryID); ingo@631: cache.put(new net.sf.ehcache.Element(key, result)); ingo@631: ingo@631: return result; tim@335: } tim@335: } ingo@631: else { ingo@631: // we don't use a cache, so we have to query the database every ingo@631: // single time ingo@631: log.info("Not using a cache."); ingo@631: return getData(queryID); ingo@631: } tim@335: } tim@335: sascha@439: protected Object getChartFromCache(String uuid, CallContext callContext) { tim@335: log.debug("Fetch chart [" + uuid + "] from cache"); tim@335: CacheFactory cacheFactory = CacheFactory.getInstance(); tim@335: if (cacheFactory.isInitialized()) { ingo@610: String key = "chart_" + getHash(); tim@335: net.sf.ehcache.Element object = cacheFactory.getCache().get(key); tim@335: tim@335: if (object != null) { tim@335: return object.getObjectValue(); tim@335: } tim@335: } tim@335: return null; tim@335: } tim@335: tim@335: protected Collection getODVResult(String uuid) { tim@335: log.debug("OutputStateBase.getODVResult"); tim@335: // TODO add Caching? I think it's not nessessary tim@335: Collection returnValue = null; tim@335: if (this.queryODVID != null){ tim@335: returnValue = this.getData(this.queryODVID); tim@335: }else{ tim@335: log.warn("No Query for ODV Data is defined."); tim@335: } tim@335: return returnValue; tim@335: } tim@335: tim@335: /** tim@335: * @param returnValue tim@335: * @return tim@335: */ tim@616: protected Collection getData(String queryID) { tim@335: log.debug("OutputStateBase.getData"); tim@335: Collection returnValue = null; tim@335: try { tim@335: String[] filterValues = this.generateFilterValuesFromInputData(); tim@335: try { tim@335: QueryExecutor queryExecutor = QueryExecutorFactory tim@335: .getInstance() tim@335: .getQueryExecutor(); tim@335: returnValue = queryExecutor.executeQuery(queryID,filterValues); tim@335: } catch (RuntimeException e) { tim@335: log.error(e, e); tim@335: } tim@335: } catch (QueryException e) { tim@335: log.error(e, e); tim@335: } tim@335: return returnValue; tim@335: } tim@335: tim@335: protected void removeChartResult(String uuid) { tim@335: log.debug("OutputStateBase.getChartResult"); tim@335: if (CacheFactory.getInstance().isInitialized()) { ingo@610: String key = "chart_" + getHash(); tim@335: log.debug("Hash for Queryelements: " + key); tim@335: net.sf.ehcache.Element value = CacheFactory.getInstance().getCache().get(key); tim@335: if (value != null) { tim@335: CacheFactory.getInstance().getCache().remove(key); tim@335: } tim@335: } tim@335: } tim@335: tim@335: protected void removeChart(String uuid) { tim@335: log.debug("OutputStateBase.removeChart from cache"); tim@335: tim@335: CacheFactory cacheFactory = CacheFactory.getInstance(); tim@335: if (cacheFactory.isInitialized()) { ingo@610: String key = "chart_" + getHash(); tim@335: net.sf.ehcache.Element object = cacheFactory.getCache().get(key); tim@335: if (object != null) tim@335: cacheFactory.getCache().remove(key); tim@335: } tim@335: } tim@335: tim@335: protected void purifyChart(Object chart, String uuid) { tim@335: log.debug("Prufify chart [" + uuid + "]"); tim@335: CacheFactory cacheFactory = CacheFactory.getInstance(); tim@335: if (cacheFactory.isInitialized()) { ingo@610: String key = "chart_" + getHash(); tim@335: cacheFactory.getCache().put(new net.sf.ehcache.Element(key, chart)); tim@335: } tim@335: } tim@335: ingo@610: ingo@610: @Override ingo@610: public void feed(Collection inputData, String uuid) ingo@610: throws StateException ingo@610: { ingo@610: putInputData(inputData, uuid); ingo@610: } ingo@610: tim@335: /** tim@335: * @see de.intevation.gnv.state.StateBase#putInputData(java.util.Collection, java.lang.String) tim@335: */ tim@335: @Override tim@335: public void putInputData(Collection inputData, tim@335: String uuid) tim@335: throws StateException { tim@335: log.debug("OutputStateBase.putInputData"); tim@335: this.removeChartResult(uuid); tim@335: this.removeChart(uuid); ingo@610: ingo@610: if (inputData != null) { ingo@610: Iterator it = inputData.iterator(); ingo@610: InputValidator iv = new InputValidator(); ingo@610: while (it.hasNext()) { ingo@610: InputData tmpItem = it.next(); ingo@610: Object tmpObj = tmpItem.getObject(); ingo@610: InputValue inputValue = this.inputValues.get(tmpItem.getName()); ingo@610: if (inputValue != null) { ingo@610: if (this.inputData == null) { ingo@610: this.inputData = new HashMap( ingo@610: inputData.size()); ingo@610: } ingo@610: ingo@610: boolean valid = iv.isInputValid(tmpItem.getValue(), ingo@610: inputValue.getType()); ingo@610: if (valid) { ingo@610: if (tmpItem.getName().equals(MINVALUEFIELDNAME)){ ingo@610: String minValue = tmpItem.getValue(); ingo@610: String maxValue = getInputValue4ID(inputData, MAXVALUEFIELDNAME); ingo@610: valid = iv.isInputValid(maxValue,inputValue.getType()); ingo@610: if (!valid){ ingo@610: String errMsg = "Wrong input for " + tmpItem.getValue() ingo@610: + " is not an " + inputValue.getType() ingo@610: + " Value."; ingo@610: log.warn(errMsg); ingo@610: throw new StateException(errMsg); ingo@610: } ingo@610: ingo@610: valid = iv.isInputValid(minValue, ingo@610: maxValue, ingo@610: inputValue.getType()); ingo@610: if (!valid){ ingo@610: String errMsg = "MaxValue-Input is less than MinValue-Input "; ingo@610: log.warn(errMsg); ingo@610: throw new StateException(errMsg); ingo@610: } ingo@610: }else if (tmpItem.getName().equals(MAXVALUEFIELDNAME)){ ingo@610: String minValue = getInputValue4ID(inputData, MINVALUEFIELDNAME); ingo@610: String maxValue = tmpItem.getValue(); ingo@610: valid = iv.isInputValid(minValue,inputValue.getType()); ingo@610: if (!valid){ ingo@610: String errMsg = "Wrong input for " + tmpItem.getValue() ingo@610: + " is not an " + inputValue.getType() ingo@610: + " Value."; ingo@610: log.warn(errMsg); ingo@610: throw new StateException(errMsg); ingo@610: } ingo@610: ingo@610: valid = iv.isInputValid(minValue, ingo@610: maxValue, ingo@610: inputValue.getType()); ingo@610: if (!valid){ ingo@610: String errMsg = "MaxValue-Input is less than MinValue-Input "; ingo@610: log.warn(errMsg); ingo@610: throw new StateException(errMsg); ingo@610: } ingo@610: } ingo@610: this.inputData.put(tmpItem.getName(), tmpItem); ingo@610: } else { ingo@610: String errMsg = "Wrong input for " + tmpItem.getValue() ingo@610: + " is not an " + inputValue.getType() ingo@610: + " Value."; ingo@610: log.warn(errMsg); ingo@610: throw new StateException(errMsg); ingo@610: } ingo@610: ingo@610: } ingo@610: else if (tmpObj != null && tmpObj instanceof MinMaxDescribeData) { ingo@610: MinMaxDescribeData data = (MinMaxDescribeData) tmpObj; ingo@610: if (this.inputData == null) { ingo@610: this.inputData = new HashMap(inputData.size()); ingo@610: } ingo@610: this.inputData.put(tmpItem.getName(), tmpItem); ingo@610: this.inputData.put("minvalue", new DefaultInputData("minvalue", (String) data.getMinValue())); ingo@610: this.inputData.put("maxvalue", new DefaultInputData("maxvalue", (String) data.getMaxValue())); ingo@610: } ingo@610: else { ingo@610: ingo@610: String errMsg = "No Inputvalue given for Inputdata " ingo@610: + tmpItem.getName(); ingo@610: log.warn(errMsg + "Value will be ignored"); ingo@610: ingo@610: } ingo@610: } ingo@610: } else { ingo@610: log.warn("No Inputdata given"); ingo@610: } tim@335: } tim@335: tim@335: public void out(String outputMode, Collection inputData, tim@335: OutputStream outputStream, String uuid, CallMeta callMeta) tim@335: throws StateException { tim@335: } tim@335: tim@335: tim@335: protected String getMessage(Locale locale, String key, String value) { tim@335: return RessourceFactory.getInstance().getRessource( tim@335: locale, tim@335: key, tim@335: value tim@335: ); tim@335: } tim@335: } ingo@626: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8: