comparison flys-artifacts/src/main/java/org/dive4elements/river/exports/AbstractExporter.java @ 5831:bd047b71ab37

Repaired internal references
author Sascha L. Teichmann <teichmann@intevation.de>
date Thu, 25 Apr 2013 12:06:39 +0200
parents flys-artifacts/src/main/java/de/intevation/flys/exports/AbstractExporter.java@8e52b4829cd1
children
comparison
equal deleted inserted replaced
5830:160f53ee0870 5831:bd047b71ab37
1 package org.dive4elements.river.exports;
2
3 import java.io.IOException;
4 import java.io.OutputStream;
5 import java.io.OutputStreamWriter;
6
7 import java.text.NumberFormat;
8
9 import org.w3c.dom.Document;
10
11 import org.apache.log4j.Logger;
12
13 import au.com.bytecode.opencsv.CSVWriter;
14
15 import org.dive4elements.artifacts.Artifact;
16 import org.dive4elements.artifacts.CallContext;
17
18 import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
19 import org.dive4elements.artifactdatabase.state.Settings;
20
21 import org.dive4elements.artifacts.common.ArtifactNamespaceContext;
22 import org.dive4elements.artifacts.common.utils.XMLUtils;
23
24 import org.dive4elements.river.artifacts.resources.Resources;
25 import org.dive4elements.river.collections.FLYSArtifactCollection;
26
27 import org.dive4elements.river.utils.Formatter;
28
29
30 /**
31 * An abstract exporter that implements some basic methods for exporting data of
32 * artifacts.
33 *
34 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
35 */
36 public abstract class AbstractExporter implements OutGenerator {
37
38 /** The logger used in this exporter.*/
39 private static Logger logger = Logger.getLogger(AbstractExporter.class);
40
41 /* XXX: Why does AbstractExporter do not implement FacetTypes? */
42 public static String FIX_PARAMETERS = "fix_parameters";
43
44 /** The name of the CSV facet which triggers the CSV creation. */
45 public static final String FACET_CSV = "csv";
46
47 /** The name of the PDF facet which triggers the PDF creation. */
48 public static final String FACET_PDF = "pdf";
49
50 /** The default charset for the CSV export. */
51 public static final String DEFAULT_CSV_CHARSET = "UTF-8";
52
53 /** The default separator for the CSV export. */
54 public static final char DEFAULT_CSV_SEPARATOR = ',';
55
56 /** XPath that points to the desired export facet. */
57 public static final String XPATH_FACET = "/art:action/@art:type";
58
59 /** The document of the incoming out() request. */
60 protected Document request;
61
62 /** The output stream where the data should be written to. */
63 protected OutputStream out;
64
65 /** The CallContext object. */
66 protected CallContext context;
67
68 /** The selected facet. */
69 protected String facet;
70
71 /** The collection.*/
72 protected FLYSArtifactCollection collection;
73
74 /** The master artifact. */
75 protected Artifact master;
76
77 private NumberFormat kmFormat;
78
79 private NumberFormat wFormat;
80
81 private NumberFormat qFormat;
82
83
84 /**
85 * Concrete subclasses need to use this method to write their special data
86 * objects into the CSV document.
87 *
88 * @param writer The CSVWriter.
89 */
90 protected abstract void writeCSVData(CSVWriter writer) throws IOException;
91
92
93 /**
94 * Concrete subclasses need to use this method to write their special data
95 * objects into the PDF document.
96 */
97 protected abstract void writePDF(OutputStream out);
98
99
100 /**
101 * This method enables concrete subclasses to collected its own special
102 * data.
103 *
104 * @param data The artifact that stores the data that has to be
105 * exported.
106 */
107 protected abstract void addData(Object data);
108
109
110 @Override
111 public void init(Document request, OutputStream out, CallContext context) {
112 logger.debug("AbstractExporter.init");
113
114 this.request = request;
115 this.out = out;
116 this.context = context;
117 }
118
119
120 @Override
121 public void setMasterArtifact(Artifact master) {
122 this.master = master;
123 }
124
125 /** Get the callcontext that this exporter has been initialized
126 * with. */
127 public CallContext getCallContext() {
128 return this.context;
129 }
130
131
132 @Override
133 public void setCollection(FLYSArtifactCollection collection) {
134 this.collection = collection;
135 }
136
137
138 /**
139 * This doOut() just collects the data of multiple artifacts. Therefore, it
140 * makes use of the addData() method which enables concrete subclasses to
141 * store its data on its own. The real output creation takes place in the
142 * concrete generate() methods.
143 *
144 * @param artifactFacet The artifact and facet.
145 * The facet to add - NOTE: the facet needs to fit to the first
146 * facet inserted into this exporter. Otherwise this artifact/facet is
147 * skipped.
148 * @param attr The attr document.
149 */
150 @Override
151 public void doOut(
152 ArtifactAndFacet artifactFacet,
153 Document attr,
154 boolean visible
155 ) {
156 String name = artifactFacet.getFacetName();
157
158 logger.debug("AbstractExporter.doOut: " + name);
159
160 if (!isFacetValid(name)) {
161 logger.warn("Facet '" + name + "' not valid. No output created!");
162 return;
163 }
164
165 addData(artifactFacet.getData(context));
166 }
167
168
169 /**
170 * Generates an export based on a specified facet.
171 */
172 @Override
173 public void generate()
174 throws IOException
175 {
176 logger.debug("AbstractExporter.generate");
177
178 if (facet == null) {
179 throw new IOException("invalid (null) facet for exporter");
180 }
181
182 if (facet.equals(FACET_CSV)) {
183 generateCSV();
184 }
185 else if (facet.equals(FACET_PDF)) {
186 generatePDF();
187 }
188 else {
189 throw new IOException(
190 "invalid facet for exporter: '" + facet + "'");
191 }
192 }
193
194
195 /**
196 * Determines if the desired facet is valid for this exporter. If no facet
197 * is currently set, <i>facet</i> is set.
198 *
199 * @param facet The desired facet.
200 *
201 * @return true, if <i>facet</i> is valid, otherwise false.
202 */
203 protected boolean isFacetValid(String facet) {
204 logger.debug("AbstractExporter.isFacetValid : " + facet + " (" + getFacet() + ")" );
205
206 String thisFacet = getFacet();
207
208 if (thisFacet == null || thisFacet.length() == 0) {
209 return false;
210 }
211 else if (facet == null || facet.length() == 0) {
212 return false;
213 }
214 else {
215 return thisFacet.equals(facet);
216 }
217 }
218
219
220 /**
221 * Returns the name of the desired facet.
222 *
223 * @return the name of the desired facet.
224 */
225 protected String getFacet() {
226 if (facet == null) {
227 facet = getFacetFromRequest();
228 }
229
230 return facet;
231 }
232
233
234 /**
235 * Extracts the name of the requested facet from request document.
236 *
237 * @return the name of the requested facet.
238 */
239 protected String getFacetFromRequest() {
240 return XMLUtils.xpathString(
241 request, XPATH_FACET, ArtifactNamespaceContext.INSTANCE);
242 }
243
244
245 protected String msg(String key, String def) {
246 return Resources.getMsg(context.getMeta(), key, def);
247 }
248
249 protected String msg(String key, String def, Object[] args) {
250 return Resources.getMsg(context.getMeta(), key, def, args);
251 }
252
253
254 /**
255 * This method starts CSV creation. It makes use of writeCSVData() which has
256 * to be implemented by concrete subclasses.
257 */
258 protected void generateCSV()
259 throws IOException
260 {
261 logger.info("AbstractExporter.generateCSV");
262
263 char quote = '"';
264 char escape = '\\';
265
266 CSVWriter writer = new CSVWriter(
267 new OutputStreamWriter(
268 out,
269 DEFAULT_CSV_CHARSET),
270 DEFAULT_CSV_SEPARATOR, quote, escape, "\r\n");
271
272 writeCSVData(writer);
273
274 writer.close();
275 }
276
277
278 /**
279 * This method starts PDF creation.
280 */
281 protected void generatePDF()
282 throws IOException
283 {
284 logger.info("AbstractExporter.generatePDF");
285 writePDF(this.out);
286 }
287
288
289 /**
290 * Returns an instance of <i>EmptySettings</i> currently!
291 *
292 * @return an instance of <i>EmptySettings</i>.
293 */
294 public Settings getSettings() {
295 return new EmptySettings();
296 }
297
298
299 /**
300 * This method is not implemented. Override it in subclasses if those need a
301 * <i>Settings</i> object.
302 */
303 public void setSettings(Settings settings) {
304 // do nothing
305 }
306
307
308 /**
309 * Returns the number formatter for kilometer values.
310 *
311 * @return the number formatter for kilometer values.
312 */
313 protected NumberFormat getKmFormatter() {
314 if (kmFormat == null) {
315 kmFormat = Formatter.getWaterlevelKM(context);
316 }
317 return kmFormat;
318 }
319
320
321 /**
322 * Returns the number formatter for W values.
323 *
324 * @return the number formatter for W values.
325 */
326 protected NumberFormat getWFormatter() {
327 if (wFormat == null) {
328 wFormat = Formatter.getWaterlevelW(context);
329 }
330 return wFormat;
331 }
332
333
334 /**
335 * Returns the number formatter for Q values.
336 *
337 * @return the number formatter for Q values.
338 */
339 protected NumberFormat getQFormatter() {
340 if (qFormat == null) {
341 qFormat = Formatter.getWaterlevelQ(context);
342 }
343 return qFormat;
344 }
345 }
346 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org