/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2004-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.validation.xml; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.util.HashMap; import java.util.Map; import javax.xml.parsers.ParserConfigurationException; import org.geotools.validation.dto.ArgumentDTO; import org.geotools.validation.dto.PlugInDTO; import org.geotools.validation.dto.TestDTO; import org.geotools.validation.dto.TestSuiteDTO; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** * Load validation configuration from XML. * * @author dzwiers, Refractions Research, Inc. * @author $Author: jive $ (last modification) * @source $URL$ * @version $Id$ */ public class XMLReader { /** * XMLReader constructor. * * <p> * Should never be used. * </p> */ private XMLReader() { } /** * readPlugIn purpose. * * <p> * This method is intended to read an XML PlugIn (pluginSchema.xsd) into a * PlugInDTO object. * </p> * * @param inputSource A features which contains a copy of a valid PlugIn * desciption. * * @return the resulting dto based on the input provided. * * @throws ValidationException DOCUMENT ME! */ public static PlugInDTO readPlugIn(Reader inputSource) throws ValidationException { PlugInDTO dto = new PlugInDTO(); try { Element elem = null; try { elem = ReaderUtils.loadConfig(inputSource); } catch (ParserConfigurationException pce) { throw new ValidationException("Cannot parse the inputSource: Cannot configure the parser.", pce); } catch (SAXException se) { throw new ValidationException("Cannot parse the inputSource: Cannot configure the parser.", se); } try { dto.setName(ReaderUtils.getElementText( ReaderUtils.getChildElement(elem, "name", true), true)); } catch (SAXException e) { throw new ValidationException("Error parsing name for this plugin", e); } try { dto.setDescription(ReaderUtils.getElementText( ReaderUtils.getChildElement(elem, "description", true), true)); } catch (SAXException e) { throw new ValidationException( "Error parsing description for the " + dto.getName() + " plugin", e); } try { dto.setClassName(ReaderUtils.getElementText( ReaderUtils.getChildElement(elem, "class", true), true)); } catch (SAXException e) { throw new ValidationException("Error parsing class for the " + dto.getName() + " plugin", e); } NodeList nl = elem.getElementsByTagName("argument"); if (nl != null) { Map m = new HashMap(); dto.setArgs(m); for (int i = 0; i < nl.getLength(); i++) { elem = (Element) nl.item(i); ArgumentDTO adto = null; try { adto = loadArg(elem, dto); } catch (ValidationException e) { e.printStackTrace(); // error } m.put(adto.getName(), adto); } } } catch (IOException ioe) { throw new ValidationException("Cannot parse the inputSource: Cannot configure the parser.", ioe); } return dto; } /** * readTestSuiteDTO purpose. * * <p> * This method is intended to read an XML Test (testSuiteSchema.xsd) into a * TestSuiteDTO object. * </p> * * @param inputSource A features which contains a copy of a valid TestSuite * desciption. * @param plugIns A name of plugin names to valid plugin DTOs * * @return the resulting dto based on the input provided. * * @throws ValidationException DOCUMENT ME! */ public static TestSuiteDTO readTestSuite(String name, Reader inputSource, Map plugIns) throws ValidationException { TestSuiteDTO dto = new TestSuiteDTO(); try { Element elem = null; try { elem = ReaderUtils.loadConfig(inputSource); } catch (ParserConfigurationException e) { throw new ValidationException( "Problem parsing "+name+":"+e.getMessage(), e); } catch (SAXException e) { throw new ValidationException( "XML problem with "+name+":"+e.getMessage(),e); } try { dto.setName(ReaderUtils.getChildText(elem, "name", true)); } catch (SAXException e) { throw new ValidationException("Error loading test suite name", e); } try { dto.setDescription(ReaderUtils.getChildText(elem, "description", true)); } catch (SAXException e) { throw new ValidationException("Error loading test suite description", e); } Map l = new HashMap(); dto.setTests(l); NodeList nl = elem.getElementsByTagName("test"); if ((nl == null) || (nl.getLength() == 0)) { throw new ValidationException( "The test suite loader has detected an error: no tests provided."); } else { for (int i = 0; i < nl.getLength(); i++) { try { TestDTO t = loadTestDTO((Element) nl.item(i), plugIns); l.put(t.getName(), t); } catch (ValidationException e) { throw new ValidationException( "An error occured loading a test in " + dto.getName() + " test suite.", e); } catch (Throwable t) { throw new ValidationException( "Could not load test suite " + dto.getName() + ":"+ t.getMessage(), t); } } } } catch (IOException e) { throw new ValidationException("An error occured loading the " + dto.getName() + "test suite", e); } return dto; } /** * loadTestDTO purpose. * * <p> * Helper method used by readTestDTO and readTestSuiteDTO * </p> * * @param elem The head element of a test * @param plugIns DOCUMENT ME! * * @return a TestDTO representing elem, null if elem is not corretly * defined. * * @throws ValidationException DOCUMENT ME! */ private static TestDTO loadTestDTO(Element elem, Map plugIns) throws ValidationException { TestDTO dto = new TestDTO(); try { dto.setName(ReaderUtils.getChildText(elem, "name", true)); } catch (SAXException e) { throw new ValidationException("Error reading the name for this test case.", e); } try { dto.setDescription(ReaderUtils.getChildText(elem, "description", false)); } catch (SAXException e) { throw new ValidationException( "Error reading the description for the " + dto.getName() + " test case.", e); } try { String pluginName = ReaderUtils.getChildText(elem, "plugin", true); dto.setPlugIn((PlugInDTO) plugIns.get(pluginName)); if (dto.getPlugIn() == null) { throw new NullPointerException( "Error - should have a plugin at "+elem); } } catch (SAXException e) { throw new ValidationException("Error reading the plugin for the " + dto.getName() + " test case.", e); } NodeList nl = elem.getElementsByTagName("argument"); if (nl != null) { Map m = new HashMap(); dto.setArgs(m); for (int i = 0; i < nl.getLength(); i++) { elem = (Element) nl.item(i); ArgumentDTO adto = null; try { adto = loadArg(elem, dto.getPlugIn()); } catch (ValidationException e) { e.printStackTrace(); // error } if ((adto == null) || !adto.isFinal()) { m.put(adto.getName(), adto); } } } return dto; } private static ArgumentDTO loadArg(Element elem, PlugInDTO dto) throws ValidationException { String key = ""; boolean _fixed = false; try { _fixed = ReaderUtils.getBooleanAttribute(elem, "final", false); key = ReaderUtils.getChildText(elem, "name", true); } catch (SAXException e) { throw new ValidationException("Error reading argument for " + dto.getName() + " :name required"); } NodeList nl2 = elem.getChildNodes(); Element value = null; for (int j = 0; j < nl2.getLength(); j++) { if (nl2.item(j).getNodeType() == Node.ELEMENT_NODE) { elem = (Element) nl2.item(j); if (elem.getTagName().trim().equals("name")) { value = elem; } else { value = elem; } } } if (value == null) { throw new ValidationException("Invalid Argument \"" + dto.getName() + "\" for argument \"" + key + "\""); } ArgumentDTO adto = (ArgumentDTO) dto.getArgs().get(key); // elem whould have the value now Object val = ArgHelper.getArgumentInstance(value.getTagName().trim(), value); if (val == null) { throw new ValidationException( "Didn't find a real value for argument " + key); } if (adto == null) { adto = new ArgumentDTO(); } else { adto = (ArgumentDTO) adto.clone(); } adto.setName(key); adto.setValue(val); adto.setFinal(_fixed); return adto; } /** * loadPlugIns purpose. * * <p> * Loads all the plugins in the directory * </p> * * @param plugInDir * * * @throws ValidationException DOCUMENT ME! */ public static Map loadPlugIns(File plugInDir) throws ValidationException { Map r = null; try { plugInDir = ReaderUtils.initFile(plugInDir, true); File[] fileList = plugInDir.listFiles(); r = new HashMap(); for (int i = 0; i < fileList.length; i++) { if (fileList[i].canWrite() && fileList[i].isFile()) { FileReader fr = new FileReader(fileList[i]); PlugInDTO dto = XMLReader.readPlugIn(fr); r.put(dto.getName(), dto); fr.close(); } } } catch (IOException e) { throw new ValidationException("An io error occured while loading the plugin's", e); } return r; } /** * Loads all the test suites in the validations directory * </p> * * @param validationDir * @param plugInDTOs Already loaded list of plug-ins to link. * * * @throws ValidationException DOCUMENT ME! */ public static Map loadValidations(File validationDir, Map plugInDTOs) throws ValidationException { Map r = null; try { validationDir = ReaderUtils.initFile(validationDir, true); } catch( IOException dirException ){ throw new ValidationException("Problem opening "+validationDir.getName(), dirException); } File[] fileList = validationDir.listFiles(); r = new HashMap(); for (int i = 0; i < fileList.length; i++) { try { if (fileList[i].canWrite() && fileList[i].isFile()) { FileReader fr = new FileReader(fileList[i]); try { TestSuiteDTO dto = XMLReader.readTestSuite( fileList[i].getName(), fr, plugInDTOs); r.put(dto.getName(), dto); } finally { fr.close(); } } } catch (IOException open) { throw new ValidationException("Could not open "+fileList[i].getName(), open); } } return r; } }