raimund@3296: package de.intevation.flys.exports.sq; raimund@3296: raimund@3296: import java.awt.image.BufferedImage; raimund@3296: import java.io.IOException; raimund@3296: import java.io.OutputStream; raimund@3296: import java.util.ArrayList; raimund@3296: import java.util.HashMap; raimund@3296: import java.util.List; raimund@3296: import java.util.Map; raimund@3296: raimund@3296: import javax.imageio.ImageIO; raimund@3296: import javax.xml.xpath.XPathConstants; raimund@3296: raimund@3296: import org.apache.log4j.Logger; raimund@3296: import org.jfree.chart.ChartRenderingInfo; raimund@3296: import org.jfree.chart.JFreeChart; raimund@3296: import org.w3c.dom.Document; raimund@3296: import org.w3c.dom.Element; raimund@3296: import org.w3c.dom.Node; raimund@3296: raimund@3296: import de.intevation.artifactdatabase.state.ArtifactAndFacet; raimund@3296: import de.intevation.artifactdatabase.state.Settings; raimund@3296: import de.intevation.artifacts.Artifact; raimund@3296: import de.intevation.artifacts.ArtifactDatabaseException; raimund@3296: import de.intevation.artifacts.CallContext; raimund@3296: import de.intevation.artifacts.common.ArtifactNamespaceContext; raimund@3296: import de.intevation.artifacts.common.utils.XMLUtils; raimund@3296: import de.intevation.flys.artifacts.context.FLYSContext; raimund@3296: import de.intevation.flys.collections.AttributeParser; raimund@3296: import de.intevation.flys.collections.CollectionAttribute; raimund@3296: import de.intevation.flys.exports.ChartGenerator; raimund@3296: import de.intevation.flys.exports.OutGenerator; raimund@3296: import de.intevation.flys.exports.OutputHelper; raimund@3296: raimund@3296: public class SQOverviewGenerator raimund@3296: implements OutGenerator raimund@3296: { raimund@3296: private static Logger logger = Logger.getLogger(SQOverviewGenerator.class); raimund@3296: raimund@3296: public static final String XPATH_CHART_SIZE = raimund@3296: "/art:action/art:attributes/art:size"; raimund@3296: raimund@3296: protected Artifact master; raimund@3296: raimund@3296: protected Settings settings; raimund@3296: raimund@3296: protected Document request; raimund@3296: raimund@3296: protected OutputStream out; raimund@3296: raimund@3296: protected CallContext context; raimund@3296: raimund@3296: protected List charts; raimund@3296: raimund@3296: /** raimund@3296: * Produce output. raimund@3296: * @param artifactAndFacet current facet and artifact. raimund@3296: * @param attr theme for facet raimund@3296: */ raimund@3296: public void doOut( raimund@3296: ArtifactAndFacet artifactAndFacet, raimund@3296: Document attr, raimund@3296: boolean visible raimund@3296: ) { raimund@3296: logger.debug("doOut()"); raimund@3296: raimund@3296: logger.debug(XMLUtils.toString(attr)); raimund@3296: String name = artifactAndFacet.getData(context).toString(); raimund@3296: if(name != null) { raimund@3296: logger.debug("name: " + name); raimund@3296: ChartGenerator g = raimund@3296: (ChartGenerator)FLYSContext.getOutGenerator( raimund@3296: context, raimund@3296: name, raimund@3296: null); raimund@3296: if (g == null) { raimund@3296: logger.debug("generator is null."); raimund@3296: return; raimund@3296: } raimund@3296: logger.debug(XMLUtils.toString(attr)); raimund@3296: OutputHelper helper = new OutputHelper(master.identifier()); raimund@3296: try { raimund@3296: AttributeParser parser = new AttributeParser(request); raimund@3296: CollectionAttribute cAttr = parser.getCollectionAttribute(); raimund@3296: raimund@3296: g.init(request, out, context); raimund@3296: Document chartAttr = getAttribute(context, cAttr, name); raimund@3296: logger.debug(XMLUtils.toString(chartAttr)); raimund@3296: helper.doOut(g, name, name, request, context); raimund@3296: charts.add(g.generateChart()); raimund@3296: } catch (IOException e) { raimund@3296: logger.warn(e); raimund@3296: } catch (ArtifactDatabaseException e) { raimund@3296: // TODO Auto-generated catch block raimund@3296: logger.warn(e); raimund@3296: } raimund@3296: } raimund@3296: } raimund@3296: raimund@3296: public void init(Document request, OutputStream out, CallContext context) { raimund@3296: this.request = request; raimund@3296: this.out = out; raimund@3296: this.context = context; raimund@3296: charts = new ArrayList(); raimund@3296: } raimund@3296: raimund@3296: public void setMasterArtifact(Artifact master) { raimund@3296: this.master = master; raimund@3296: } raimund@3296: raimund@3296: public void generate() throws IOException { raimund@3296: logger.debug("SQOverviewGenerator.generate"); raimund@3296: raimund@3296: int[] size = getSize(); raimund@3296: raimund@3296: if (size == null) { raimund@3296: size = new int[] {400, 600}; raimund@3296: } raimund@3296: BufferedImage result = raimund@3296: new BufferedImage(size[0], size[1], BufferedImage.TYPE_INT_RGB); raimund@3296: for (int i = 0; i < charts.size(); i++) { raimund@3296: logger.debug("index: " + i); raimund@3296: JFreeChart chart = charts.get(i); raimund@3296: ChartRenderingInfo info = new ChartRenderingInfo(); raimund@3296: BufferedImage img = raimund@3296: chart.createBufferedImage(size[0]/2, size[1]/3, info); raimund@3296: int horPos = 0; raimund@3296: int vertPos = 0; raimund@3296: if (i % 2 == 1) { raimund@3296: horPos = size[0]/2; raimund@3296: } raimund@3296: if (i > 1) { raimund@3296: vertPos = (size[1] / 3) * (i / 2); raimund@3296: } raimund@3296: result.createGraphics().drawImage(img, horPos, vertPos, null); raimund@3296: } raimund@3296: ImageIO.write(result, "png", out); raimund@3296: } raimund@3296: raimund@3296: public void setSettings(Settings settings) { raimund@3296: this.settings = settings; raimund@3296: } raimund@3296: raimund@3296: public Settings getSettings() { raimund@3296: return this.settings; raimund@3296: } raimund@3296: raimund@3296: raimund@3296: /** raimund@3296: * Returns the "attribute" (part of description document) for a specific raimund@3296: * output type. raimund@3296: * raimund@3296: * @param context The CallContext object. raimund@3296: * @param cAttr The CollectionAttribute. raimund@3296: * @param output The name of the desired output type. raimund@3296: * raimund@3296: * @return the attribute for the desired output type. raimund@3296: */ raimund@3296: protected Document getAttribute( raimund@3296: CallContext context, raimund@3296: CollectionAttribute cAttr, raimund@3296: String output) raimund@3296: throws ArtifactDatabaseException raimund@3296: { raimund@3296: Document attr = cAttr.toXML(); raimund@3296: raimund@3296: Map vars = new HashMap(); raimund@3296: vars.put("output", output); raimund@3296: raimund@3296: Node out = (Node) XMLUtils.xpath( raimund@3296: attr, raimund@3296: "art:attribute/art:outputs/art:output[@name=$output]", raimund@3296: XPathConstants.NODE, raimund@3296: ArtifactNamespaceContext.INSTANCE, raimund@3296: vars); raimund@3296: raimund@3296: raimund@3296: if (out != null) { raimund@3296: Document o = XMLUtils.newDocument(); raimund@3296: raimund@3296: o.appendChild(o.importNode(out, true)); raimund@3296: raimund@3296: return o; raimund@3296: } raimund@3296: raimund@3296: return null; raimund@3296: } raimund@3296: raimund@3296: raimund@3296: /** raimund@3296: * Returns the size of a chart export as array which has been specified by raimund@3296: * the incoming request document. raimund@3296: * raimund@3296: * @return the size of a chart as [width, height] or null if no width or raimund@3296: * height are given in the request document. raimund@3296: */ raimund@3296: protected int[] getSize() { raimund@3296: int[] size = new int[2]; raimund@3296: raimund@3296: Element sizeEl = (Element)XMLUtils.xpath( raimund@3296: request, raimund@3296: XPATH_CHART_SIZE, raimund@3296: XPathConstants.NODE, raimund@3296: ArtifactNamespaceContext.INSTANCE); raimund@3296: raimund@3296: if (sizeEl != null) { raimund@3296: String uri = ArtifactNamespaceContext.NAMESPACE_URI; raimund@3296: raimund@3296: String w = sizeEl.getAttributeNS(uri, "width"); raimund@3296: String h = sizeEl.getAttributeNS(uri, "height"); raimund@3296: raimund@3296: if (w.length() > 0 && h.length() > 0) { raimund@3296: try { raimund@3296: size[0] = Integer.parseInt(w); raimund@3296: size[1] = Integer.parseInt(h); raimund@3296: } raimund@3296: catch (NumberFormatException nfe) { raimund@3296: logger.warn("Wrong values for chart width/height."); raimund@3296: } raimund@3296: } raimund@3296: } raimund@3296: raimund@3296: return size[0] > 0 && size[1] > 0 ? size : null; raimund@3296: } raimund@3296: }