ingo@105: package de.intevation.flys.artifacts; ingo@105: ingo@153: import java.io.IOException; ingo@153: import java.io.OutputStream; ingo@153: import java.util.ArrayList; ingo@109: import java.util.List; ingo@153: import java.util.Map; ingo@134: import java.util.Vector; ingo@109: ingo@105: import org.w3c.dom.Document; ingo@110: import org.w3c.dom.Element; ingo@124: import org.w3c.dom.Node; ingo@105: ingo@105: import org.apache.log4j.Logger; ingo@105: ingo@153: import org.jfree.data.xy.DefaultXYDataset; ingo@153: ingo@153: import org.jfree.chart.ChartFactory; ingo@153: import org.jfree.chart.JFreeChart; ingo@153: import org.jfree.chart.plot.PlotOrientation; ingo@153: ingo@110: import de.intevation.artifacts.ArtifactNamespaceContext; ingo@105: import de.intevation.artifacts.CallContext; ingo@105: ingo@110: import de.intevation.artifactdatabase.ProtocolUtils; ingo@144: import de.intevation.artifactdatabase.state.Output; ingo@110: import de.intevation.artifactdatabase.state.State; ingo@110: import de.intevation.artifactdatabase.state.StateEngine; ingo@112: import de.intevation.artifactdatabase.transition.TransitionEngine; ingo@110: ingo@109: import de.intevation.artifacts.common.utils.XMLUtils; ingo@109: ingo@153: import de.intevation.flys.model.Gauge; ingo@153: ingo@153: import de.intevation.flys.artifacts.model.DischargeTables; ingo@153: import de.intevation.flys.artifacts.model.GaugesFactory; ingo@134: import de.intevation.flys.artifacts.states.DefaultState; ingo@109: import de.intevation.flys.artifacts.context.FLYSContext; ingo@153: import de.intevation.flys.exports.ChartExportHelper; ingo@105: ingo@105: ingo@105: /** ingo@105: * The default WINFO artifact. ingo@105: * ingo@105: * @author Ingo Weinzierl ingo@105: */ ingo@119: public class WINFOArtifact extends FLYSArtifact { ingo@105: ingo@105: /** The logger for this class */ ingo@105: private static Logger logger = Logger.getLogger(WINFOArtifact.class); ingo@105: ingo@105: ingo@121: /** The name of the artifact.*/ ingo@121: public static final String ARTIFACT_NAME = "winfo"; ingo@121: ingo@124: /** XPath */ ingo@124: public static final String XPATH_STATIC_UI ="/art:result/art:ui/art:static"; ingo@124: ingo@121: ingo@105: /** ingo@105: * The default constructor. ingo@105: */ ingo@105: public WINFOArtifact() { ingo@105: } ingo@105: ingo@105: ingo@105: /** ingo@105: * This method returns a description of this artifact. ingo@105: * ingo@105: * @param data Some data. ingo@128: * @param context The CallContext. ingo@105: * ingo@105: * @return the description of this artifact. ingo@105: */ ingo@105: public Document describe(Document data, CallContext context) { ingo@119: logger.debug("Describe: the current state is: " + getCurrentStateId()); ingo@105: ingo@112: FLYSContext flysContext = null; ingo@112: if (context instanceof FLYSContext) { ingo@112: flysContext = (FLYSContext) context; ingo@112: } ingo@112: else { ingo@112: flysContext = (FLYSContext) context.globalContext(); ingo@112: } ingo@110: ingo@112: StateEngine stateEngine = (StateEngine) flysContext.get( ingo@112: FLYSContext.STATE_ENGINE_KEY); ingo@112: ingo@112: TransitionEngine transitionEngine = (TransitionEngine) flysContext.get( ingo@112: FLYSContext.TRANSITION_ENGINE_KEY); ingo@112: ingo@112: List reachable = transitionEngine.getReachableStates( ingo@119: getCurrentState(context), stateEngine); ingo@112: ingo@112: Document description = XMLUtils.newDocument(); ingo@110: XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( ingo@110: description, ingo@110: ArtifactNamespaceContext.NAMESPACE_URI, ingo@110: ArtifactNamespaceContext.NAMESPACE_PREFIX); ingo@110: ingo@110: Element root = ProtocolUtils.createRootNode(creator); ingo@115: description.appendChild(root); ingo@115: ingo@119: State current = getCurrentState(context); ingo@119: ingo@110: ProtocolUtils.appendDescribeHeader(creator, root, identifier(), hash()); ingo@119: ProtocolUtils.appendState(creator, root, current); ingo@112: ProtocolUtils.appendReachableStates(creator, root, reachable); ingo@110: ingo@127: Element ui = ProtocolUtils.createArtNode( ingo@127: creator, "ui", null, null); ingo@110: ingo@127: Element staticUI = ProtocolUtils.createArtNode( ingo@127: creator, "static", null, null); ingo@127: ingo@144: Element outs = ProtocolUtils.createArtNode( ingo@144: creator, "outputmodes", null, null); ingo@144: appendOutputModes(description, outs, context, identifier()); ingo@144: ingo@134: appendStaticUI(description, staticUI, context, identifier()); ingo@128: ingo@127: Element dynamic = current.describe( ingo@124: description, ingo@127: root, ingo@127: context, ingo@127: identifier()); ingo@127: ingo@144: if (dynamic != null) { ingo@144: ui.appendChild(dynamic); ingo@144: } ingo@144: ingo@128: ui.appendChild(staticUI); ingo@144: ingo@127: root.appendChild(ui); ingo@144: root.appendChild(outs); ingo@124: ingo@110: return description; ingo@105: } ingo@121: ingo@121: ingo@153: @Override ingo@153: public void out( ingo@153: Document format, ingo@153: OutputStream out, ingo@153: CallContext context) ingo@153: throws IOException ingo@153: { ingo@153: logger.info("WINFOArtifact.out"); ingo@153: String river = (String) getData("river").getValue(); ingo@153: String from = (String) getData("ld_from").getValue(); ingo@153: String to = (String) getData("ld_to").getValue(); ingo@153: ingo@153: double f = Double.parseDouble(from); ingo@153: double t = Double.parseDouble(to); ingo@153: ingo@153: List ranges = new ArrayList(); ingo@153: ranges.add(new double [] { f, t }); ingo@153: ingo@153: List gauges = GaugesFactory.getGauges(river); ingo@153: List filtered = GaugesFactory.filterRanges(gauges, ranges); ingo@153: ingo@153: if (logger.isDebugEnabled()) { ingo@153: int numGauges = gauges != null ? gauges.size() : 0; ingo@153: int numFiltered = filtered != null ? filtered.size() : 0; ingo@153: ingo@153: logger.debug("++++++++++++++++++++"); ingo@153: logger.debug("Search gauges for river: " + river); ingo@153: logger.debug("-> ... from range: " + from); ingo@153: logger.debug("-> ... to range: " + to); ingo@153: logger.debug("-> Found " + numGauges + " gauges in total."); ingo@153: logger.debug("-> Found " + numFiltered + " gauges after filtering."); ingo@153: logger.debug("++++++++++++++++++++"); ingo@153: } ingo@153: ingo@153: String[] gaugeNames = new String[filtered.size()]; ingo@153: int idx = 0; ingo@153: for (Gauge gauge: filtered) { ingo@153: gaugeNames[idx++] = gauge.getName(); ingo@153: } ingo@153: ingo@153: DischargeTables dt = new DischargeTables(river, gaugeNames); ingo@153: Map gaugeValues = dt.getValues(100d); ingo@153: ingo@153: DefaultXYDataset dataset = new DefaultXYDataset(); ingo@153: ingo@153: for (String gauge: gaugeNames) { ingo@153: double[][] values = gaugeValues.get(gauge); ingo@153: dataset.addSeries(gauge, values); ingo@153: } ingo@153: ingo@153: JFreeChart chart = ChartFactory.createXYLineChart( ingo@153: "Abflusskurven (" + river + ")", ingo@153: "Q", "W", ingo@153: dataset, ingo@153: PlotOrientation.VERTICAL, ingo@153: true, ingo@153: false, ingo@153: false); ingo@153: ingo@153: ChartExportHelper.exportImage( ingo@153: out, ingo@153: chart, ingo@153: "png", ingo@153: 600, 400); ingo@153: } ingo@153: ingo@153: ingo@121: /** ingo@121: * Returns the name of the concrete artifact. ingo@121: * ingo@121: * @return the name of the concrete artifact. ingo@121: */ ingo@121: public String getName() { ingo@121: return ARTIFACT_NAME; ingo@121: } ingo@124: ingo@124: ingo@144: protected void appendOutputModes( ingo@144: Document doc, ingo@144: Element outs, ingo@144: CallContext context, ingo@144: String uuid) ingo@144: { ingo@144: Vector stateIds = getPreviousStateIds(); ingo@144: ingo@144: XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( ingo@144: doc, ingo@144: ArtifactNamespaceContext.NAMESPACE_URI, ingo@144: ArtifactNamespaceContext.NAMESPACE_PREFIX); ingo@144: ingo@144: FLYSContext flysContext = getFlysContext(context); ingo@144: StateEngine engine = (StateEngine) flysContext.get( ingo@144: FLYSContext.STATE_ENGINE_KEY); ingo@144: ingo@144: for (String stateId: stateIds) { ingo@144: logger.debug("Append output modes for state: " + stateId); ingo@144: State state = engine.getState(stateId); ingo@144: ingo@144: List list = state.getOutputs(); ingo@144: if (list == null || list.size() == 0) { ingo@144: continue; ingo@144: } ingo@144: ingo@144: ProtocolUtils.appendOutputModes(creator, outs, list); ingo@144: } ingo@144: ingo@144: // TODO If the current state is already filled with data, the output is ingo@144: // available as well! So we need some code to append the outputs of the ingo@144: // current already filled state. ingo@144: } ingo@144: ingo@144: ingo@124: /** ingo@124: * This method appends the static data - that has already been inserted by ingo@124: * the user - to the static node of the DESCRIBE document. ingo@124: * ingo@134: * @param doc The document. ingo@134: * @param ui The root node. ingo@134: * @param context The CallContext. ingo@134: * @param uuid The identifier of the artifact. ingo@124: */ ingo@128: protected void appendStaticUI( ingo@134: Document doc, ingo@134: Node ui, ingo@134: CallContext context, ingo@134: String uuid) ingo@128: { ingo@134: Vector stateIds = getPreviousStateIds(); ingo@124: ingo@134: FLYSContext flysContext = getFlysContext(context); ingo@134: StateEngine engine = (StateEngine) flysContext.get( ingo@134: FLYSContext.STATE_ENGINE_KEY); ingo@124: ingo@134: for (String stateId: stateIds) { ingo@134: logger.debug("Append static data for state: " + stateId); ingo@134: DefaultState state = (DefaultState) engine.getState(stateId); ingo@134: ui.appendChild(state.describeStatic(doc, ui, context, uuid)); ingo@134: } ingo@124: ingo@124: } ingo@105: } ingo@105: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :