comparison gnv-artifacts/src/main/java/de/intevation/gnv/utils/MapfileGenerator.java @ 657:af3f56758f59

merged gnv-artifacts/0.5
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:13:53 +0200
parents 40ead2d2a08d
children 9ba6bb85d6dd
comparison
equal deleted inserted replaced
590:5f5f273c8566 657:af3f56758f59
1 package de.intevation.gnv.utils;
2
3 import de.intevation.artifactdatabase.Config;
4 import de.intevation.artifactdatabase.XMLUtils;
5 import de.intevation.artifacts.ArtifactNamespaceContext;
6 import de.intevation.gnv.wms.LayerInfo;
7
8 import java.io.File;
9 import java.io.FileNotFoundException;
10 import java.io.FileWriter;
11 import java.io.IOException;
12 import java.io.StringWriter;
13 import java.io.Writer;
14 import java.util.ArrayList;
15 import java.util.Date;
16 import java.util.List;
17
18 import javax.xml.xpath.XPathConstants;
19
20 import org.apache.log4j.Logger;
21
22 import org.apache.velocity.Template;
23 import org.apache.velocity.VelocityContext;
24 import org.apache.velocity.app.VelocityEngine;
25
26 import org.w3c.dom.Document;
27 import org.w3c.dom.Node;
28 import org.w3c.dom.NodeList;
29
30
31 /**
32 * @author Ingo Weinzierl (ingo.weinzierl@intevation.de)
33 */
34 public class MapfileGenerator
35 extends Thread
36 {
37 public static final String TEMPLATE_PATH =
38 "/artifact-database/gnv/map-generator/templates/path/text()";
39
40 public static final String TEMPLATE_MAPFILE =
41 "/artifact-database/gnv/map-generator/templates/maptemplate/text()";
42
43 public static final String MAPFILE_PATH =
44 "/artifact-database/gnv/map-generator/mapfile/@path";
45
46 public static final String SHAPEFILE_BASE_DIR =
47 "/artifact-database/gnv/shapefile-directory/@path";
48
49 public static final String VELOCITY_LOGFILE =
50 "/artifact-database/velocity/logfile/@path";
51
52 public static final String META_FILE_NAME = "meta.xml";
53
54 public static final String XPATH_LAYER = "/art:meta/art:layer";
55 public static final String XPATH_LAYER_NAME = "art:name";
56 public static final String XPATH_LAYER_TYPE = "art:type";
57 public static final String XPATH_LAYER_DATA = "art:data";
58 public static final String XPATH_LAYER_STATUS = "art:status";
59 public static final String XPATH_LAYER_MODEL = "art:model";
60
61 protected static final long SLEEPTIME = 10 * 1000L; // 10 seconds
62
63 private static Logger logger = Logger.getLogger(MapfileGenerator.class);
64
65 private static MapfileGenerator instance;
66
67 private File mapfile;
68 private String shapefileDirectory;
69 private String templatePath;
70 private String velocityLogfile;
71
72 private VelocityEngine velocityEngine;
73 private boolean lock[];
74
75
76
77 private MapfileGenerator() {
78 lock = new boolean[1];
79 }
80
81
82 public static void main(String[] args) {
83 // TODO IMPLEMENT ME
84 }
85
86
87 public static synchronized MapfileGenerator getInstance() {
88 if (instance == null) {
89 instance = new MapfileGenerator();
90 instance.setDaemon(true);
91 instance.start();
92 }
93
94 return instance;
95 }
96
97
98 public void update() {
99 synchronized (lock) {
100 logger.debug("update");
101 lock[0] = true;
102 lock.notify();
103 }
104 }
105
106
107 public void run() {
108 logger.debug("Start MapfileGenerator thread...");
109 try {
110 for (;;) {
111 synchronized (lock) {
112 while (!lock[0]) {
113 lock.wait(SLEEPTIME);
114 }
115 lock[0] = false;
116 }
117
118 logger.debug("Start sync process now...");
119 generate();
120 }
121 }
122 catch (InterruptedException ie) {
123 logger.debug("MapfileGenerator thread got an interrupt.");
124 }
125 finally {
126 logger.debug("THREAD END");
127 }
128 }
129
130
131 protected void generate() {
132 File basedir = new File(getShapefileBaseDir());
133 List layers = new ArrayList();
134 searchMetaInformation(basedir, layers);
135 writeMapfile(layers);
136 }
137
138
139 protected VelocityEngine getVelocityEngine() {
140 if (velocityEngine == null) {
141 velocityEngine = new VelocityEngine();
142 try {
143 setupVelocity(velocityEngine);
144 }
145 catch (Exception e) {
146 logger.error(e, e);
147 return null;
148 }
149 }
150 return velocityEngine;
151 }
152
153
154 protected void setupVelocity(VelocityEngine engine)
155 throws Exception
156 {
157 engine.setProperty(
158 "input.encoding",
159 "UTF-8");
160
161 engine.setProperty(
162 VelocityEngine.RUNTIME_LOG,
163 getVelocityLogfile());
164
165 engine.setProperty(
166 "resource.loader",
167 "file");
168
169 engine.setProperty(
170 "file.resource.loader.path",
171 getTemplateBaseDir());
172
173 engine.init();
174 }
175
176
177 protected String getVelocityLogfile() {
178 if (velocityLogfile == null)
179 velocityLogfile = Config.getStringXPath(VELOCITY_LOGFILE);
180
181 return velocityLogfile;
182 }
183
184
185 protected String getTemplateBaseDir() {
186 if (templatePath == null) {
187 templatePath = Config.getStringXPath(TEMPLATE_PATH);
188 templatePath = Config.replaceConfigDir(templatePath);
189 }
190
191 return templatePath;
192 }
193
194
195 protected Template getTemplateByName(String model) {
196 if (model.indexOf(".vm") < 0) {
197 model = model.concat(".vm");
198 }
199
200 try {
201 VelocityEngine engine = getVelocityEngine();
202 if (engine == null) {
203 logger.error("Error while fetching VelocityEngine.");
204 return null;
205 }
206
207 return engine.getTemplate(model);
208 }
209 catch (Exception e) {
210 logger.warn(e, e);
211 }
212
213 return null;
214 }
215
216
217 protected Template getMapfileTemplate()
218 throws Exception
219 {
220 String mapfileName = Config.getStringXPath(TEMPLATE_MAPFILE);
221 return getTemplateByName(mapfileName);
222 }
223
224
225 protected String getShapefileBaseDir() {
226 if (shapefileDirectory == null) {
227 shapefileDirectory = Config.getStringXPath(SHAPEFILE_BASE_DIR);
228 shapefileDirectory = Config.replaceConfigDir(shapefileDirectory);
229 }
230
231 return shapefileDirectory;
232 }
233
234
235 protected File getMapfile() {
236 if (mapfile == null) {
237 String tmp = Config.getStringXPath(MAPFILE_PATH);
238 tmp = Config.replaceConfigDir(tmp);
239 mapfile = new File(tmp);
240 }
241
242 return mapfile;
243 }
244
245
246 protected void searchMetaInformation(File file, List store) {
247 if (file.isDirectory()) {
248 File[] files = file.listFiles();
249
250 if (files != null && files.length != 0) {
251 int size = files.length;
252 for (File tmp: files) {
253 searchMetaInformation(tmp, store);
254 }
255 }
256 }
257 else if (file.getName().equals(META_FILE_NAME)) {
258 LayerInfo[] info = parseMeta(file);
259
260 int infoSize = info.length;
261 for (int j = 0; j < infoSize; j++) {
262 if (info[j] != null) {
263 store.add(info[j]);
264 }
265 }
266 }
267 }
268
269
270 protected LayerInfo[] parseMeta(File file) {
271 Document meta = XMLUtils.parseDocument(file);
272 List layers = new ArrayList();
273
274 NodeList layerset = (NodeList) XMLUtils.xpath(
275 meta,
276 XPATH_LAYER,
277 XPathConstants.NODESET,
278 ArtifactNamespaceContext.INSTANCE);
279
280 int size = layerset.getLength();
281 for (int i = 0; i < size; i++) {
282 LayerInfo info = parseLayer(layerset.item(i));
283
284 if (info != null && !info.isEmpty() && !info.isBroken()) {
285 layers.add(info);
286 }
287 else {
288 logger.warn("Found broken LayerInfo object.");
289 }
290 }
291
292 return (LayerInfo[]) layers.toArray(new LayerInfo[layers.size()]);
293 }
294
295
296 protected LayerInfo parseLayer(Node layer) {
297 LayerInfo info = new LayerInfo();
298
299 String name = parseLayerAttr(layer, XPATH_LAYER_NAME);
300 if (name != null && !name.equals("")) {
301 info.setName(name);
302 }
303
304 String model = parseLayerAttr(layer, XPATH_LAYER_MODEL);
305 if (model != null && !model.equals("")) {
306 info.setModel(model);
307 }
308
309 String type = parseLayerAttr(layer, XPATH_LAYER_TYPE);
310 if (type != null && !type.equals("")) {
311 info.setType(type);
312 }
313
314 String data = parseLayerAttr(layer, XPATH_LAYER_DATA);
315 if (data != null && !data.equals("")) {
316 info.setData(data);
317 }
318
319 String status = parseLayerAttr(layer, XPATH_LAYER_STATUS);
320 if (status != null && !status.equals("")) {
321 info.setStatus(status);
322 }
323
324 return info;
325 }
326
327
328 protected String parseLayerAttr(Node node, String xpath) {
329 return (String) XMLUtils.xpath(
330 node,
331 xpath,
332 XPathConstants.STRING,
333 ArtifactNamespaceContext.INSTANCE);
334 }
335
336
337 protected void writeMapfile(List layers) {
338 String tmpMapName = "mapfile" + new Date().getTime();
339
340 int layersize = layers.size();
341 StringBuilder sb = new StringBuilder();
342 StringWriter sw = null;
343 LayerInfo info = null;
344
345 for (int i = 0; i < layersize; i++) {
346 sw = new StringWriter();
347 info = (LayerInfo) layers.get(i);
348
349 Template layerTemplate = getTemplateByName(info.getModel());
350 VelocityContext context = new VelocityContext();
351 context.put("info", info);
352
353 try {
354 layerTemplate.merge(context, sw);
355 sb.append(sw.toString());
356 }
357 catch (IOException ioe) {
358 logger.warn("Error while filling layer template.");
359 logger.warn(ioe, ioe);
360 }
361 }
362
363 File map = getMapfile();
364 Writer writer = null;
365 File tmp = null;
366
367 try {
368 tmp = new File(map.getParent(), tmpMapName);
369
370 tmp.createNewFile();
371 writer = new FileWriter(tmp);
372
373 VelocityContext context = new VelocityContext();
374 context.put("LAYERS", sb.toString());
375
376 Template mapTemplate = getMapfileTemplate();
377 if (mapTemplate == null) {
378 logger.warn("No mapfile template found.");
379 return;
380 }
381
382 mapTemplate.merge(context, writer);
383
384 // we need to create a temporary mapfile first und rename it into
385 // real mapfile because we don't run into race conditions on this
386 // way. (iw)
387 tmp.renameTo(map);
388 }
389 catch (FileNotFoundException fnfe) {
390 logger.error(fnfe, fnfe);
391 }
392 catch (IOException ioe) {
393 logger.error(ioe, ioe);
394 }
395 catch (Exception e) {
396 logger.error(e, e);
397 }
398 finally {
399 try {
400 // close file writer
401 if (writer != null) {
402 writer.close();
403 }
404
405 // remove temporary mapfile if an error occured and it still
406 // exists
407 if (tmp.exists()) {
408 tmp.delete();
409 }
410 }
411 catch (IOException ioe) {
412 logger.debug(ioe, ioe);
413 }
414 }
415 }
416 }
417 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:

http://dive4elements.wald.intevation.org