ingo@391: package de.intevation.flys.exports; ingo@391: ingo@391: import java.io.IOException; ingo@391: import java.io.OutputStream; ingo@391: import java.io.OutputStreamWriter; ingo@391: ingo@391: import org.w3c.dom.Document; ingo@391: ingo@391: import org.apache.log4j.Logger; ingo@391: ingo@391: import au.com.bytecode.opencsv.CSVWriter; ingo@391: ingo@391: import de.intevation.artifacts.Artifact; ingo@391: import de.intevation.artifacts.CallContext; ingo@391: ingo@416: import de.intevation.flys.artifacts.resources.Resources; ingo@416: ingo@391: ingo@391: /** ingo@391: * An abstract exporter that implements some basic methods for exporting data of ingo@391: * artifacts. ingo@391: * ingo@391: * @author Ingo Weinzierl ingo@391: */ ingo@391: public abstract class AbstractExporter implements OutGenerator { ingo@391: ingo@391: /** The logger used in this exporter.*/ ingo@391: private static Logger logger = Logger.getLogger(AbstractExporter.class); ingo@391: ingo@391: ingo@391: /** The name of the CSV facet which triggers the CSV creation.*/ ingo@391: public static final String FACET_CSV = "csv"; ingo@391: ingo@391: /** The default charset for the CSV export.*/ ingo@391: public static final String DEFAULT_CSV_CHARSET = "UTF-8"; ingo@391: ingo@391: /** The default separator for the CSV export.*/ ingo@391: public static final char DEFAULT_CSV_SEPARATOR = ','; ingo@391: ingo@391: ingo@391: /** The document of the incoming out() request.*/ ingo@391: protected Document request; ingo@391: ingo@391: /** The output stream where the data should be written to.*/ ingo@391: protected OutputStream out; ingo@391: ingo@391: /** The CallContext object.*/ ingo@391: protected CallContext context; ingo@391: ingo@391: /** The selected facet.*/ ingo@391: protected String facet; ingo@391: ingo@412: /** The master artifact.*/ ingo@412: protected Artifact master; ingo@412: ingo@391: ingo@391: /** ingo@391: * Concrete subclasses need to use this method to write their special data ingo@391: * objects into the CSV document. ingo@391: * ingo@391: * @param writer The CSVWriter. ingo@391: */ ingo@391: protected abstract void writeCSVData(CSVWriter writer); ingo@391: ingo@391: ingo@391: /** ingo@391: * This method enables concrete subclasses to collected its own special ingo@391: * data. ingo@391: * ingo@391: * @param artifacts The artifact that stores the data that has to be ingo@391: * exported. ingo@391: */ ingo@391: protected abstract void addData(Artifact artifact); ingo@391: ingo@391: ingo@391: public void init(Document request, OutputStream out, CallContext context) { ingo@391: logger.debug("AbstractExporter.init"); ingo@391: ingo@391: this.request = request; ingo@391: this.out = out; ingo@391: this.context = context; ingo@391: } ingo@391: ingo@391: ingo@412: public void setMasterArtifact(Artifact master) { ingo@412: this.master = master; ingo@412: } ingo@412: ingo@412: ingo@391: /** ingo@391: * This doOut() just collects the data of multiple artifacts. Therefore, it ingo@391: * makes use of the addData() method which enables concrete subclasses to ingo@391: * store its data on its own. The real output creation takes place in the ingo@391: * concrete generate() methods. ingo@391: * ingo@391: * @param artifact The artifact. ingo@391: * @param facet The facet to add - NOTE: the facet needs to fit to the first ingo@391: * facet inserted into this exporter. Otherwise this artifact/facet is ingo@391: * skipped. ingo@391: * @param attr The attr document. ingo@391: */ ingo@391: public void doOut(Artifact artifact, String facet, Document attr) { ingo@391: logger.debug("AbstractExporter.doOut: " + facet); ingo@391: ingo@391: if (!isFacetValid(facet)) { ingo@391: logger.warn("Facet '" + facet + "' not valid. No output created!"); ingo@391: return; ingo@391: } ingo@391: ingo@391: addData(artifact); ingo@391: } ingo@391: ingo@391: ingo@391: /** ingo@391: * Generates an export based on a specified facet. ingo@391: */ ingo@391: public void generate() ingo@391: throws IOException ingo@391: { ingo@391: logger.debug("AbstractExporter.generate"); ingo@391: ingo@391: if (facet != null && facet.equals(FACET_CSV)) { ingo@391: generateCSV(); ingo@391: } ingo@391: else { ingo@391: throw new IOException("invalid facet for exporter."); ingo@391: } ingo@391: } ingo@391: ingo@391: ingo@391: /** ingo@391: * Determines if the desired facet is valid for this exporter. If no facet ingo@391: * is currently set, facet is set. ingo@391: * ingo@391: * @param facet The desired facet. ingo@391: * ingo@391: * @return true, if facet is valid, otherwise false. ingo@391: */ ingo@391: protected boolean isFacetValid(String facet) { ingo@391: logger.debug("AbstractExporter.isFacetValid"); ingo@391: ingo@391: if (facet == null || facet.length() == 0) { ingo@391: return false; ingo@391: } ingo@391: else if (this.facet == null || this.facet.length() == 0) { ingo@391: logger.debug("Set the facet of this export: " + facet); ingo@391: this.facet = facet; ingo@391: ingo@391: return true; ingo@391: } ingo@391: else { ingo@391: return this.facet.equals(facet); ingo@391: } ingo@391: } ingo@391: ingo@391: ingo@416: ingo@416: protected String msg(String key, String def) { ingo@416: return Resources.getMsg(context.getMeta(), key, def); ingo@416: } ingo@416: ingo@416: ingo@391: /** ingo@391: * This method starts CSV creation. It makes use of writeCSVData() which has ingo@391: * to be implemented by concrete subclasses. ingo@391: */ ingo@391: protected void generateCSV() ingo@391: throws IOException ingo@391: { ingo@391: logger.info("AbstractExporter.generateCSV"); ingo@391: ingo@391: CSVWriter writer = new CSVWriter( ingo@391: new OutputStreamWriter( ingo@391: out, ingo@391: DEFAULT_CSV_CHARSET), ingo@391: DEFAULT_CSV_SEPARATOR); ingo@391: ingo@391: writeCSVData(writer); ingo@391: ingo@391: writer.close(); ingo@391: } ingo@391: } ingo@391: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :