comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/FloodMapState.java @ 1190:f514894ec2fd

merged flys-artifacts/2.5
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:14:17 +0200
parents be8b5c06a1f8
children f45bbc80bd3d
comparison
equal deleted inserted replaced
917:b48c36076e17 1190:f514894ec2fd
1 package de.intevation.flys.artifacts.states;
2
3 import java.io.File;
4 import java.io.FileNotFoundException;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7 import java.util.ArrayList;
8 import java.util.List;
9
10 import com.vividsolutions.jts.geom.Coordinate;
11 import com.vividsolutions.jts.geom.Geometry;
12 import com.vividsolutions.jts.geom.LineString;
13 import com.vividsolutions.jts.geom.MultiPolygon;
14 import com.vividsolutions.jts.geom.Polygon;
15
16 import org.apache.log4j.Logger;
17
18 import org.opengis.feature.simple.SimpleFeature;
19 import org.opengis.feature.simple.SimpleFeatureType;
20
21 import org.geotools.feature.FeatureCollection;
22 import org.geotools.feature.FeatureCollections;
23 import org.geotools.feature.simple.SimpleFeatureBuilder;
24
25 import de.intevation.artifacts.Artifact;
26 import de.intevation.artifacts.CallContext;
27
28 import de.intevation.artifacts.common.utils.FileTools;
29
30 import de.intevation.artifactdatabase.state.Facet;
31
32 import de.intevation.flys.model.CrossSectionTrack;
33 import de.intevation.flys.model.DGM;
34 import de.intevation.flys.model.Floodplain;
35 import de.intevation.flys.model.RiverAxis;
36
37 import de.intevation.flys.artifacts.FLYSArtifact;
38 import de.intevation.flys.artifacts.model.CalculationMessage;
39 import de.intevation.flys.artifacts.model.CalculationResult;
40 import de.intevation.flys.artifacts.model.FacetTypes;
41 import de.intevation.flys.artifacts.model.WQKms;
42 import de.intevation.flys.artifacts.model.WMSLayerFacet;
43 import de.intevation.flys.artifacts.model.WSPLGENCalculation;
44 import de.intevation.flys.artifacts.model.WSPLGENJob;
45 import de.intevation.flys.artifacts.model.WSPLGENReportFacet;
46 import de.intevation.flys.artifacts.resources.Resources;
47 import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
48 import de.intevation.flys.exports.WstWriter;
49 import de.intevation.flys.utils.FLYSUtils;
50 import de.intevation.flys.utils.GeometryUtils;
51 import de.intevation.flys.utils.MapfileGenerator;
52 import de.intevation.flys.wsplgen.JobObserver;
53 import de.intevation.flys.wsplgen.Scheduler;
54
55
56 public class FloodMapState
57 extends DefaultState
58 implements FacetTypes
59 {
60 /** The logger that is used in this state. */
61 private static Logger logger = Logger.getLogger(FloodMapState.class);
62
63
64 public static final String KEEP_ARTIFACT_DIR =
65 System.getProperty("flys.uesk.keep.artifactsdir", "false");
66
67
68 public static final String WSP_ARTIFACT = "wsp";
69
70 public static final String WINFO_WSP_STATE_ID = "state.winfo.waterlevel";
71
72 public static final String WSPLGEN_PARAMETER_FILE = "wsplgen.par";
73 public static final String WSPLGEN_BARRIERS_LINES = "barrier_lines.shp";
74 public static final String WSPLGEN_BARRIERS_POLY = "barrier_polygons.shp";
75 public static final String WSPLGEN_AXIS = "axis.shp";
76 public static final String WSPLGEN_QPS = "qps.shp";
77 public static final String WSPLGEN_FLOODPLAIN = "talaue.shp";
78 public static final String WSPLGEN_WSP_FILE = "waterlevel.wst";
79 public static final String WSPLGEN_OUTPUT_FILE = "wsplgen.shp";
80
81 public static final int WSPLGEN_DEFAULT_OUTPUT = 0;
82
83
84
85 /**
86 * Inner class that is used to create facets. An instance of this class is
87 * used while packaging the data for the WSPLGEN calculation.
88 */
89 private static class FacetCreator {
90 protected FLYSArtifact artifact;
91 protected List<Facet> facets;
92 protected String url;
93 protected String hash;
94 protected String stateId;
95
96 public FacetCreator(FLYSArtifact artifact, String hash, String sId) {
97 this.facets = new ArrayList<Facet>(2);
98 this.artifact = artifact;
99 this.hash = hash;
100 this.stateId = sId;
101 }
102
103 protected String getRiver() {
104 return artifact.getDataAsString("river");
105 }
106
107 protected String getUrl() {
108 String url = FLYSUtils.getXPathString(FLYSUtils.XPATH_MAPSERVER_URL);
109 url = url + "user-wms";
110 return url;
111 }
112
113 protected String getSrid() {
114 return FLYSUtils.getRiverSrid(artifact);
115 }
116
117 protected String getBounds() {
118 return GeometryUtils.getRiverBounds(getRiver());
119 }
120
121 public List<Facet> getFacets() {
122 return facets;
123 }
124
125 public void createWSPLGENFacet() {
126 WMSLayerFacet wsplgen = new WMSLayerFacet(
127 0,
128 FLOODMAP_WSPLGEN,
129 "Ergebnis der WSPLGEN Berechnung",
130 ComputeType.ADVANCE,
131 stateId,
132 hash,
133 getUrl());
134
135 wsplgen.addLayer(
136 artifact.identifier() + MapfileGenerator.MS_WSPLGEN_POSTFIX);
137 wsplgen.setSrid(getSrid());
138 wsplgen.setExtent(getBounds());
139
140 facets.add(wsplgen);
141 }
142
143 public void createBarrierFacet() {
144 WMSLayerFacet barriers = new WMSLayerFacet(
145 1,
146 FLOODMAP_WSPLGEN,
147 "Rohre/Graeben/Daemme",
148 ComputeType.ADVANCE,
149 stateId,
150 hash,
151 getUrl());
152
153 barriers.addLayer(
154 artifact.identifier() + MapfileGenerator.MS_BARRIERS_POSTFIX);
155 barriers.setSrid(getSrid());
156 barriers.setExtent(getBounds());
157
158 facets.add(barriers);
159 }
160 } // end of FacetCreator
161
162
163
164 @Override
165 public Object computeAdvance(
166 FLYSArtifact artifact,
167 String hash,
168 CallContext context,
169 List<Facet> facets,
170 Object old
171 ) {
172 logger.debug("FloodMapState.computeAdvance");
173
174 File artifactDir = getDirectory(artifact);
175
176 if (artifactDir == null) {
177 logger.error("Could not create directory for WSPLGEN results!");
178 return null;
179 }
180
181 WSPLGENCalculation calculation = new WSPLGENCalculation();
182
183 FacetCreator facetCreator = new FacetCreator(artifact, hash, getID());
184
185 WSPLGENJob job = prepareWSPLGENJob(
186 artifact,
187 facetCreator,
188 artifactDir,
189 context,
190 calculation);
191
192 CalculationResult res = new CalculationResult(null, calculation);
193 WSPLGENReportFacet report= new WSPLGENReportFacet(
194 ComputeType.ADVANCE, hash, getID(), res);
195
196 facets.add(report);
197
198 if (job == null) {
199 if (KEEP_ARTIFACT_DIR.equals("false")) {
200 removeDirectory(artifact);
201 }
202
203 calculation.addError(-1, Resources.getMsg(
204 context.getMeta(),
205 "wsplgen.job.error",
206 "wsplgen.job.error"));
207
208 logger.error("No WSPLGEN processing has been started!");
209
210 return null;
211 }
212
213 Scheduler scheduler = Scheduler.getInstance();
214 scheduler.addJob(job);
215
216 facetCreator.createWSPLGENFacet();
217
218 facets.addAll(facetCreator.getFacets());
219
220 context.afterCall(CallContext.BACKGROUND);
221 context.addBackgroundMessage(new CalculationMessage(
222 JobObserver.STEPS.length,
223 0,
224 Resources.getMsg(
225 context.getMeta(),
226 "wsplgen.job.queued",
227 "wsplgen.job.queued")
228 ));
229
230 return null;
231 }
232
233
234 /**
235 * Returns (and creates if not existing) the directory for storing WSPLEN
236 * data for the owner artifact.
237 *
238 * @param artifact The owner Artifact.
239 *
240 * @return the directory for WSPLEN data.
241 */
242 protected File getDirectory(FLYSArtifact artifact) {
243 String shapePath = FLYSUtils.getXPathString(
244 FLYSUtils.XPATH_SHAPEFILE_DIR);
245
246 File artifactDir = FileTools.getDirectory(
247 shapePath, artifact.identifier());
248
249 return artifactDir;
250 }
251
252
253 /**
254 * Removes the directory and all its content where the required data and the
255 * results of WSPLGEN are stored. Should be called in endOfLife().
256 */
257 protected void removeDirectory(FLYSArtifact artifact) {
258 String shapePath = FLYSUtils.getXPathString(
259 FLYSUtils.XPATH_SHAPEFILE_DIR);
260
261 File artifactDir = new File(shapePath, artifact.identifier());
262
263 if (artifactDir.exists()) {
264 logger.info("Delete directory: " + artifactDir.getAbsolutePath());
265 boolean success = FileTools.deleteRecursive(artifactDir);
266 }
267 else {
268 logger.debug("There is no directory to remove.");
269 }
270 }
271
272
273 @Override
274 public void endOfLife(Artifact artifact, Object callContext) {
275 logger.info("FloodMapState.endOfLife: " + artifact.identifier());
276
277 FLYSArtifact flys = (FLYSArtifact) artifact;
278 removeDirectory(flys);
279 }
280
281
282 protected WSPLGENJob prepareWSPLGENJob(
283 FLYSArtifact artifact,
284 FacetCreator facetCreator,
285 File artifactDir,
286 CallContext context,
287 WSPLGENCalculation calculation
288 ) {
289 logger.debug("FloodMapState.prepareWSPLGENJob");
290
291 WSPLGENJob job = new WSPLGENJob(
292 artifact,
293 artifactDir,
294 context,
295 calculation);
296
297 File paraFile = new File(artifactDir, WSPLGEN_PARAMETER_FILE);
298
299 setOut(artifact, job);
300 setRange(artifact, job);
301 setDelta(artifact, job);
302 setGel(artifact, job);
303 setDist(artifact, job);
304 setLine(artifact, facetCreator, artifactDir, job);
305 setAxis(artifact, artifactDir, job);
306 setPro(artifact, artifactDir, job);
307 setDgm(artifact, job);
308 setArea(artifact, artifactDir, job);
309 setOutFile(artifact, job);
310 setWsp(artifact, context, artifactDir, job); // WSP
311
312 // TODO
313 // setWspTag(artifact, job);
314
315 try {
316 job.toFile(paraFile);
317
318 return job;
319 }
320 catch (IOException ioe) {
321 logger.warn("Cannot write PAR file: " + ioe.getMessage());
322 }
323 catch (IllegalArgumentException iae) {
324 logger.warn("Cannot write PAR file: " + iae.getMessage());
325 }
326
327 return null;
328 }
329
330
331 protected void setOut(FLYSArtifact artifact, WSPLGENJob job) {
332 job.setOut(WSPLGEN_DEFAULT_OUTPUT);
333 }
334
335
336 protected void setRange(FLYSArtifact artifact, WSPLGENJob job) {
337 double[] range = FLYSUtils.getKmRange(artifact);
338
339 job.setStart(range[0]);
340 job.setEnd(range[1]);
341 }
342
343
344 protected void setDelta(FLYSArtifact artifact, WSPLGENJob job) {
345 String from = artifact.getDataAsString("diff_from");
346 String to = artifact.getDataAsString("diff_to");
347 String diff = artifact.getDataAsString("diff_diff");
348
349 try {
350 job.setFrom(Double.parseDouble(from));
351 }
352 catch (NumberFormatException nfe) {
353 }
354
355 try {
356 job.setTo(Double.parseDouble(to));
357 }
358 catch (NumberFormatException nfe) {
359 }
360
361 try {
362 job.setDiff(Double.parseDouble(diff));
363 }
364 catch (NumberFormatException nfe) {
365 }
366 }
367
368
369 protected void setGel(FLYSArtifact artifact, WSPLGENJob job) {
370 String gel = artifact.getDataAsString("use_floodplain");
371
372 if (gel != null && gel.length() > 0) {
373 boolean use = Boolean.parseBoolean(gel);
374
375 if (use) {
376 job.setGel(WSPLGENJob.GEL_SPERRE);
377 }
378 else {
379 job.setGel(WSPLGENJob.GEL_NOSPERRE);
380 }
381 }
382 }
383
384
385 protected void setDist(FLYSArtifact artifact, WSPLGENJob job) {
386 String dist = artifact.getDataAsString("profile_distance");
387
388 try {
389 job.setDist(Double.parseDouble(dist));
390 }
391 catch (NumberFormatException nfe) {
392 // nothing to do here
393 }
394 }
395
396
397 protected void setLine(
398 FLYSArtifact artifact,
399 FacetCreator facetCreator,
400 File dir,
401 WSPLGENJob job
402 ) {
403 String geoJSON = artifact.getDataAsString("uesk.barriers");
404 String srid = FLYSUtils.getRiverSrid(artifact);
405 String srs = "EPSG:" + srid;
406
407 if (geoJSON == null || geoJSON.length() == 0) {
408 logger.debug("No barrier features in parameterization existing.");
409 return;
410 }
411
412 SimpleFeatureType ft = getBarriersFeatureType(
413 "barriers", srs, Geometry.class);
414
415 List<SimpleFeature> features = GeometryUtils.parseGeoJSON(geoJSON, ft);
416 if (features == null || features.size() == 0) {
417 logger.debug("No barrier features extracted.");
418 return;
419 }
420
421 FeatureCollection[] fcs = splitLinesAndPolygons(features);
422
423 File shapeLines = new File(dir, WSPLGEN_BARRIERS_LINES);
424 File shapePolys = new File(dir, WSPLGEN_BARRIERS_POLY);
425
426 Object[][] obj = new Object[][] {
427 new Object[] { "typ", String.class }
428 };
429
430 boolean l = GeometryUtils.writeShapefile(
431 shapeLines,
432 GeometryUtils.buildFeatureType("lines", srs, LineString.class, obj),
433 fcs[0]);
434
435 if (l) {
436 logger.debug(
437 "Successfully created barrier line shapefile. " +
438 "Write shapefile path into WSPLGEN job.");
439 job.addLin(shapeLines.getAbsolutePath());
440 }
441
442 boolean p = GeometryUtils.writeShapefile(
443 shapePolys,
444 GeometryUtils.buildFeatureType("polygons", srs, Polygon.class, obj),
445 fcs[1]);
446
447 if (p) {
448 logger.debug(
449 "Successfully created barrier polygon shapefile. " +
450 "Write shapefile path into WSPLGEN job.");
451 job.addLin(shapePolys.getAbsolutePath());
452 }
453
454 if (p || l) {
455 facetCreator.createBarrierFacet();
456 }
457 }
458
459
460 protected SimpleFeatureType getBarriersFeatureType(
461 String name,
462 String srs,
463 Class type
464 ) {
465 Object[][] attrs = new Object[2][];
466 attrs[0] = new Object[] { "typ", String.class };
467 attrs[1] = new Object[] { "elevation", Double.class };
468
469 return GeometryUtils.buildFeatureType(name, srs, type, attrs);
470 }
471
472
473 protected FeatureCollection[] splitLinesAndPolygons(List<SimpleFeature> f) {
474 FeatureCollection lines = FeatureCollections.newCollection();
475 FeatureCollection polygons = FeatureCollections.newCollection();
476
477 for (SimpleFeature feature: f) {
478 Geometry geom = (Geometry) feature.getDefaultGeometry();
479
480
481 if (geom instanceof LineString) {
482 geom = applyElevationAttribute(feature, (LineString) geom);
483 lines.add(feature);
484 }
485 else if (geom instanceof Polygon) {
486 geom = applyElevationAttribute(feature, (Polygon) geom);
487 polygons.add(feature);
488 }
489 else {
490 logger.warn("Feature not supported: " + geom.getClass());
491 }
492 }
493
494 logger.debug("Found " + lines.size() + " barrier lines.");
495 logger.debug("Found " + polygons.size() + " barrier polygons.");
496
497 return new FeatureCollection[] { lines, polygons };
498 }
499
500
501 protected static Geometry applyElevationAttribute(
502 SimpleFeature feature,
503 Geometry geom
504 ) {
505 logger.debug("Apply elevations for: " + geom.getClass());
506
507 List<Double> elevations = extractElevations(feature);
508 int numPoints = geom.getNumPoints();
509 int numElevation = elevations.size();
510
511 String typ = (String) feature.getAttribute("typ");
512
513 if (numPoints > numElevation) {
514 logger.warn("More vertices in Geometry than elevations given.");
515 }
516
517 Coordinate[] c = geom.getCoordinates();
518 for (int i = 0; i < numPoints; i++) {
519 if (i < numElevation) {
520 c[i].z = elevations.get(i);
521 }
522 else if (typ != null && typ.equals("Graben")) {
523 c[i].z = -9999d;
524 }
525 else {
526 c[i].z = 9999d;
527 }
528 }
529
530 return geom;
531 }
532
533
534 protected static List<Double> extractElevations(SimpleFeature feature) {
535 String tmp = (String) feature.getAttribute("elevation");
536 String typ = (String) feature.getAttribute("typ");
537
538 String[] elevations = tmp == null ? null : tmp.split(" ");
539
540 int num = elevations != null ? elevations.length : 0;
541
542 List<Double> list = new ArrayList<Double>(num);
543
544 for (int i = 0; i < num; i++) {
545 try {
546 list.add(Double.parseDouble(elevations[i]));
547 }
548 catch (NumberFormatException nfe) {
549 logger.warn("Error while parsing elevation at pos: " + i);
550 if (typ != null && typ.equals("Graben")) {
551 list.add(new Double(-9999.0));
552 }
553 else {
554 list.add(new Double(9999.0));
555 }
556 }
557 }
558
559 return list;
560 }
561
562
563 protected void setAxis(FLYSArtifact artifact, File dir, WSPLGENJob job) {
564 String river = artifact.getDataAsString("river");
565 String srid = FLYSUtils.getRiverSrid(artifact);
566 String srs = "EPSG:" + srid;
567
568 RiverAxis axis = RiverAxis.getRiverAxis(river);
569 if (axis == null) {
570 logger.warn("Could not find river axis for: '" + river + "'");
571 return;
572 }
573
574 Geometry geom = axis.getGeom();
575
576 SimpleFeatureType ft = GeometryUtils.buildFeatureType(
577 "axis", srs, LineString.class);
578
579 SimpleFeatureBuilder builder = new SimpleFeatureBuilder(ft);
580 builder.add(geom);
581
582 FeatureCollection collection = FeatureCollections.newCollection();
583 collection.add(builder.buildFeature("0"));
584
585 File axisShape = new File(dir, WSPLGEN_AXIS);
586
587 boolean a = GeometryUtils.writeShapefile(
588 axisShape,
589 GeometryUtils.buildFeatureType("axis", srs, LineString.class),
590 collection);
591
592 if (a) {
593 job.setAxis(axisShape.getAbsolutePath());
594 }
595 }
596
597
598 protected void setPro(FLYSArtifact artifact, File dir, WSPLGENJob job) {
599 String river = artifact.getDataAsString("river");
600 String srid = FLYSUtils.getRiverSrid(artifact);
601 String srs = "EPSG:" + srid;
602
603 List<CrossSectionTrack> cst =
604 CrossSectionTrack.getCrossSectionTrack(river);
605
606 logger.debug("Found " + cst.size() + " CrossSectionTracks.");
607
608 Object[][] attrs = new Object[2][];
609 attrs[0] = new Object[] { "ELEVATION", Double.class };
610 attrs[1] = new Object[] { "KILOMETER", Double.class };
611
612 SimpleFeatureType ft = GeometryUtils.buildFeatureType(
613 "qps", srs, LineString.class, attrs);
614
615 SimpleFeatureBuilder builder = new SimpleFeatureBuilder(ft);
616 FeatureCollection collection = FeatureCollections.newCollection();
617
618 int i = 0;
619 for (CrossSectionTrack track: cst) {
620 builder.reset();
621 builder.add(track.getGeom());
622 builder.add(track.getZ().doubleValue());
623 builder.add(track.getKm().doubleValue());
624
625 collection.add(builder.buildFeature(String.valueOf(i++)));
626 }
627
628 File qpsShape = new File(dir, WSPLGEN_QPS);
629
630 boolean q = GeometryUtils.writeShapefile(
631 qpsShape,
632 GeometryUtils.buildFeatureType("qps", srs, LineString.class, attrs),
633 collection);
634
635 if (q) {
636 job.setPro(qpsShape.getAbsolutePath());
637 }
638 }
639
640
641 protected void setDgm(FLYSArtifact artifact, WSPLGENJob job) {
642 String dgm_id = artifact.getDataAsString("dgm");
643
644 int id = -1;
645 try {
646 id = Integer.parseInt(dgm_id);
647 }
648 catch (NumberFormatException nfe) { /* do nothing */ }
649
650 DGM dgm = DGM.getDGM(id);
651
652 if (dgm == null) {
653 logger.warn("Could not find specified DGM.");
654
655 return;
656 }
657
658 job.setDgm(dgm.getPath());
659 }
660
661
662 protected void setArea(FLYSArtifact artifact, File dir, WSPLGENJob job) {
663 String river = artifact.getDataAsString("river");
664 String srid = FLYSUtils.getRiverSrid(artifact);
665 String srs = "EPSG:" + srid;
666
667 Floodplain plain = Floodplain.getFloodplain(river);
668
669 SimpleFeatureType ft = GeometryUtils.buildFeatureType(
670 "talaue", srs, MultiPolygon.class);
671
672 SimpleFeatureBuilder builder = new SimpleFeatureBuilder(ft);
673 builder.add(plain.getGeom());
674
675 FeatureCollection collection = FeatureCollections.newCollection();
676 collection.add(builder.buildFeature("0"));
677
678 File talaueShape = new File(dir, WSPLGEN_FLOODPLAIN);
679
680 boolean t = GeometryUtils.writeShapefile(
681 talaueShape,
682 GeometryUtils.buildFeatureType("talaue", srs, MultiPolygon.class),
683 collection);
684
685 if (t) {
686 job.setArea(talaueShape.getAbsolutePath());
687 }
688 }
689
690
691 protected void setOutFile(FLYSArtifact artifact, WSPLGENJob job) {
692 job.setOutFile(WSPLGEN_OUTPUT_FILE);
693 }
694
695
696 protected WQKms getWQKms(FLYSArtifact flys, CallContext cc) {
697 String wspString = flys.getDataAsString(WSP_ARTIFACT);
698 String[] parts = wspString.split(";");
699
700 String otherArtifact = parts[0];
701
702 int idx = -1;
703 try {
704 idx = Integer.parseInt(parts[2]);
705 }
706 catch (NumberFormatException nfe) { /* do nothing */ }
707
708 FLYSArtifact src = otherArtifact != null
709 ? FLYSUtils.getArtifact(otherArtifact, cc)
710 : flys;
711
712 logger.debug("Use waterlevel provided by Artifact: " + src.identifier());
713
714 CalculationResult rawData = (CalculationResult) src.compute(
715 cc,
716 null,
717 WINFO_WSP_STATE_ID,
718 ComputeType.ADVANCE,
719 false);
720
721 WQKms[] wqkms = (WQKms[]) rawData.getData();
722
723 return wqkms == null || idx == -1 || idx >= wqkms.length
724 ? null
725 : wqkms[idx];
726 }
727
728
729 protected void setWsp(
730 FLYSArtifact artifact,
731 CallContext context,
732 File dir,
733 WSPLGENJob job)
734 {
735 logger.debug("FloodMapState.setWsp");
736
737 WQKms data = getWQKms(artifact, context);
738
739 if (data == null) {
740 logger.warn("No WST data found!");
741 return;
742 }
743
744 WstWriter writer = new WstWriter(1);
745
746 // TODO REMOVE job.setWspTag(...) This is only used until the user is
747 // able to select the WSP column himself!
748 boolean writeWspTag = true;
749
750 double[] buf = new double[4];
751 logger.debug("Add WST column: " + data.getName());
752 writer.addColumn(data.getName());
753
754 if (writeWspTag) {
755 job.setWspTag(data.getName());
756 writeWspTag = false;
757 }
758
759 for (int i = 0, num = data.size(); i < num; i++) {
760 data.get(i, buf);
761 writer.add(buf);
762 }
763
764 FileOutputStream fout = null;
765
766 try {
767 File wspFile = new File(dir, WSPLGEN_WSP_FILE);
768 fout = new FileOutputStream(wspFile);
769
770 writer.write(fout);
771
772 job.setWsp(wspFile.getAbsolutePath());
773 }
774 catch (FileNotFoundException fnfe) {
775 logger.warn("Error while writing wsp file: " + fnfe.getMessage());
776 }
777 finally {
778 if (fout != null) {
779 try {
780 fout.close();
781 }
782 catch (IOException ioe) { /* do nothing */ }
783 }
784 }
785 }
786 }
787 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org