001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2004-2006, Geotools Project Managment Committee (PMC)
005: * (C) 2004, TOPP - www.openplans.org
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: */
017: package org.geotools.validation.xml;
018:
019: import java.io.File;
020: import java.io.FileReader;
021: import java.io.IOException;
022: import java.io.Reader;
023: import java.util.HashMap;
024: import java.util.Map;
025:
026: import javax.xml.parsers.ParserConfigurationException;
027:
028: import org.geotools.validation.dto.ArgumentDTO;
029: import org.geotools.validation.dto.PlugInDTO;
030: import org.geotools.validation.dto.TestDTO;
031: import org.geotools.validation.dto.TestSuiteDTO;
032: import org.w3c.dom.Element;
033: import org.w3c.dom.Node;
034: import org.w3c.dom.NodeList;
035: import org.xml.sax.SAXException;
036:
037: /**
038: * Load validation configuration from XML.
039: *
040: * @author dzwiers, Refractions Research, Inc.
041: * @author $Author: jive $ (last modification)
042: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/extension/validation/src/main/java/org/geotools/validation/xml/XMLReader.java $
043: * @version $Id: XMLReader.java 22754 2006-11-16 03:03:20Z jgarnett $
044: */
045: public class XMLReader {
046: /**
047: * XMLReader constructor.
048: *
049: * <p>
050: * Should never be used.
051: * </p>
052: */
053: private XMLReader() {
054: }
055:
056: /**
057: * readPlugIn purpose.
058: *
059: * <p>
060: * This method is intended to read an XML PlugIn (pluginSchema.xsd) into a
061: * PlugInDTO object.
062: * </p>
063: *
064: * @param inputSource A features which contains a copy of a valid PlugIn
065: * desciption.
066: *
067: * @return the resulting dto based on the input provided.
068: *
069: * @throws ValidationException DOCUMENT ME!
070: */
071: public static PlugInDTO readPlugIn(Reader inputSource)
072: throws ValidationException {
073: PlugInDTO dto = new PlugInDTO();
074:
075: try {
076: Element elem = null;
077:
078: try {
079: elem = ReaderUtils.loadConfig(inputSource);
080: } catch (ParserConfigurationException pce) {
081: throw new ValidationException(
082: "Cannot parse the inputSource: Cannot configure the parser.",
083: pce);
084: } catch (SAXException se) {
085: throw new ValidationException(
086: "Cannot parse the inputSource: Cannot configure the parser.",
087: se);
088: }
089:
090: try {
091: dto.setName(ReaderUtils.getElementText(ReaderUtils
092: .getChildElement(elem, "name", true), true));
093: } catch (SAXException e) {
094: throw new ValidationException(
095: "Error parsing name for this plugin", e);
096: }
097:
098: try {
099: dto.setDescription(ReaderUtils.getElementText(
100: ReaderUtils.getChildElement(elem,
101: "description", true), true));
102: } catch (SAXException e) {
103: throw new ValidationException(
104: "Error parsing description for the "
105: + dto.getName() + " plugin", e);
106: }
107:
108: try {
109: dto.setClassName(ReaderUtils.getElementText(ReaderUtils
110: .getChildElement(elem, "class", true), true));
111: } catch (SAXException e) {
112: throw new ValidationException(
113: "Error parsing class for the " + dto.getName()
114: + " plugin", e);
115: }
116:
117: NodeList nl = elem.getElementsByTagName("argument");
118:
119: if (nl != null) {
120: Map m = new HashMap();
121: dto.setArgs(m);
122:
123: for (int i = 0; i < nl.getLength(); i++) {
124: elem = (Element) nl.item(i);
125:
126: ArgumentDTO adto = null;
127:
128: try {
129: adto = loadArg(elem, dto);
130: } catch (ValidationException e) {
131: e.printStackTrace();
132:
133: // error
134: }
135:
136: m.put(adto.getName(), adto);
137: }
138: }
139: } catch (IOException ioe) {
140: throw new ValidationException(
141: "Cannot parse the inputSource: Cannot configure the parser.",
142: ioe);
143: }
144:
145: return dto;
146: }
147:
148: /**
149: * readTestSuiteDTO purpose.
150: *
151: * <p>
152: * This method is intended to read an XML Test (testSuiteSchema.xsd) into a
153: * TestSuiteDTO object.
154: * </p>
155: *
156: * @param inputSource A features which contains a copy of a valid TestSuite
157: * desciption.
158: * @param plugIns A name of plugin names to valid plugin DTOs
159: *
160: * @return the resulting dto based on the input provided.
161: *
162: * @throws ValidationException DOCUMENT ME!
163: */
164: public static TestSuiteDTO readTestSuite(String name,
165: Reader inputSource, Map plugIns) throws ValidationException {
166: TestSuiteDTO dto = new TestSuiteDTO();
167: try {
168: Element elem = null;
169: try {
170: elem = ReaderUtils.loadConfig(inputSource);
171: } catch (ParserConfigurationException e) {
172: throw new ValidationException("Problem parsing " + name
173: + ":" + e.getMessage(), e);
174: } catch (SAXException e) {
175: throw new ValidationException("XML problem with "
176: + name + ":" + e.getMessage(), e);
177: }
178:
179: try {
180: dto.setName(ReaderUtils
181: .getChildText(elem, "name", true));
182: } catch (SAXException e) {
183: throw new ValidationException(
184: "Error loading test suite name", e);
185: }
186:
187: try {
188: dto.setDescription(ReaderUtils.getChildText(elem,
189: "description", true));
190: } catch (SAXException e) {
191: throw new ValidationException(
192: "Error loading test suite description", e);
193: }
194:
195: Map l = new HashMap();
196: dto.setTests(l);
197:
198: NodeList nl = elem.getElementsByTagName("test");
199:
200: if ((nl == null) || (nl.getLength() == 0)) {
201: throw new ValidationException(
202: "The test suite loader has detected an error: no tests provided.");
203: } else {
204: for (int i = 0; i < nl.getLength(); i++) {
205: try {
206: TestDTO t = loadTestDTO((Element) nl.item(i),
207: plugIns);
208: l.put(t.getName(), t);
209: } catch (ValidationException e) {
210: throw new ValidationException(
211: "An error occured loading a test in "
212: + dto.getName()
213: + " test suite.", e);
214: } catch (Throwable t) {
215: throw new ValidationException(
216: "Could not load test suite "
217: + dto.getName() + ":"
218: + t.getMessage(), t);
219: }
220: }
221: }
222: } catch (IOException e) {
223: throw new ValidationException(
224: "An error occured loading the " + dto.getName()
225: + "test suite", e);
226: }
227:
228: return dto;
229: }
230:
231: /**
232: * loadTestDTO purpose.
233: *
234: * <p>
235: * Helper method used by readTestDTO and readTestSuiteDTO
236: * </p>
237: *
238: * @param elem The head element of a test
239: * @param plugIns DOCUMENT ME!
240: *
241: * @return a TestDTO representing elem, null if elem is not corretly
242: * defined.
243: *
244: * @throws ValidationException DOCUMENT ME!
245: */
246: private static TestDTO loadTestDTO(Element elem, Map plugIns)
247: throws ValidationException {
248: TestDTO dto = new TestDTO();
249:
250: try {
251: dto.setName(ReaderUtils.getChildText(elem, "name", true));
252: } catch (SAXException e) {
253: throw new ValidationException(
254: "Error reading the name for this test case.", e);
255: }
256:
257: try {
258: dto.setDescription(ReaderUtils.getChildText(elem,
259: "description", false));
260: } catch (SAXException e) {
261: throw new ValidationException(
262: "Error reading the description for the "
263: + dto.getName() + " test case.", e);
264: }
265:
266: try {
267: String pluginName = ReaderUtils.getChildText(elem,
268: "plugin", true);
269: dto.setPlugIn((PlugInDTO) plugIns.get(pluginName));
270:
271: if (dto.getPlugIn() == null) {
272: throw new NullPointerException(
273: "Error - should have a plugin at " + elem);
274: }
275: } catch (SAXException e) {
276: throw new ValidationException(
277: "Error reading the plugin for the " + dto.getName()
278: + " test case.", e);
279: }
280:
281: NodeList nl = elem.getElementsByTagName("argument");
282:
283: if (nl != null) {
284: Map m = new HashMap();
285: dto.setArgs(m);
286:
287: for (int i = 0; i < nl.getLength(); i++) {
288: elem = (Element) nl.item(i);
289:
290: ArgumentDTO adto = null;
291:
292: try {
293: adto = loadArg(elem, dto.getPlugIn());
294: } catch (ValidationException e) {
295: e.printStackTrace();
296:
297: // error
298: }
299:
300: if ((adto == null) || !adto.isFinal()) {
301: m.put(adto.getName(), adto);
302: }
303: }
304: }
305:
306: return dto;
307: }
308:
309: private static ArgumentDTO loadArg(Element elem, PlugInDTO dto)
310: throws ValidationException {
311: String key = "";
312: boolean _fixed = false;
313:
314: try {
315: _fixed = ReaderUtils.getBooleanAttribute(elem, "final",
316: false);
317: key = ReaderUtils.getChildText(elem, "name", true);
318: } catch (SAXException e) {
319: throw new ValidationException("Error reading argument for "
320: + dto.getName() + " :name required");
321: }
322:
323: NodeList nl2 = elem.getChildNodes();
324: Element value = null;
325:
326: for (int j = 0; j < nl2.getLength(); j++) {
327: if (nl2.item(j).getNodeType() == Node.ELEMENT_NODE) {
328: elem = (Element) nl2.item(j);
329:
330: if (elem.getTagName().trim().equals("name")) {
331: value = elem;
332: } else {
333: value = elem;
334: }
335: }
336: }
337:
338: if (value == null) {
339: throw new ValidationException("Invalid Argument \""
340: + dto.getName() + "\" for argument \"" + key + "\"");
341: }
342:
343: ArgumentDTO adto = (ArgumentDTO) dto.getArgs().get(key);
344:
345: // elem whould have the value now
346: Object val = ArgHelper.getArgumentInstance(value.getTagName()
347: .trim(), value);
348:
349: if (val == null) {
350: throw new ValidationException(
351: "Didn't find a real value for argument " + key);
352: }
353:
354: if (adto == null) {
355: adto = new ArgumentDTO();
356: } else {
357: adto = (ArgumentDTO) adto.clone();
358: }
359:
360: adto.setName(key);
361: adto.setValue(val);
362: adto.setFinal(_fixed);
363:
364: return adto;
365: }
366:
367: /**
368: * loadPlugIns purpose.
369: *
370: * <p>
371: * Loads all the plugins in the directory
372: * </p>
373: *
374: * @param plugInDir
375: *
376: *
377: * @throws ValidationException DOCUMENT ME!
378: */
379: public static Map loadPlugIns(File plugInDir)
380: throws ValidationException {
381: Map r = null;
382:
383: try {
384: plugInDir = ReaderUtils.initFile(plugInDir, true);
385:
386: File[] fileList = plugInDir.listFiles();
387: r = new HashMap();
388:
389: for (int i = 0; i < fileList.length; i++) {
390: if (fileList[i].canWrite() && fileList[i].isFile()) {
391: FileReader fr = new FileReader(fileList[i]);
392: PlugInDTO dto = XMLReader.readPlugIn(fr);
393: r.put(dto.getName(), dto);
394: fr.close();
395: }
396: }
397: } catch (IOException e) {
398: throw new ValidationException(
399: "An io error occured while loading the plugin's", e);
400: }
401:
402: return r;
403: }
404:
405: /**
406: * Loads all the test suites in the validations directory
407: * </p>
408: *
409: * @param validationDir
410: * @param plugInDTOs Already loaded list of plug-ins to link.
411: *
412: *
413: * @throws ValidationException DOCUMENT ME!
414: */
415: public static Map loadValidations(File validationDir, Map plugInDTOs)
416: throws ValidationException {
417: Map r = null;
418:
419: try {
420: validationDir = ReaderUtils.initFile(validationDir, true);
421: } catch (IOException dirException) {
422: throw new ValidationException("Problem opening "
423: + validationDir.getName(), dirException);
424: }
425: File[] fileList = validationDir.listFiles();
426: r = new HashMap();
427:
428: for (int i = 0; i < fileList.length; i++) {
429: try {
430: if (fileList[i].canWrite() && fileList[i].isFile()) {
431: FileReader fr = new FileReader(fileList[i]);
432: try {
433: TestSuiteDTO dto = XMLReader.readTestSuite(
434: fileList[i].getName(), fr, plugInDTOs);
435: r.put(dto.getName(), dto);
436: } finally {
437: fr.close();
438: }
439: }
440: } catch (IOException open) {
441: throw new ValidationException("Could not open "
442: + fileList[i].getName(), open);
443: }
444: }
445: return r;
446: }
447: }
|