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