/* * 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.attributes; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import javax.xml.parsers.DocumentBuilderFactory; import org.geotools.validation.DefaultFeatureValidation; import org.geotools.validation.ValidationResults; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; /** * GazetteerNameValidation purpose. * * <p> * Description of GazetteerNameValidation ... * </p> * * <p> * Capabilities: * </p> * * <ul> * <li> * Feature: description * </li> * </ul> * * <p> * Example Use: * </p> * <pre><code> * GazetteerNameValidation x = new GazetteerNameValidation(...); * </code></pre> * * @author dzwiers, Refractions Research, Inc. * @author $Author: dmzwiers $ (last modification) * * @source $URL$ * @version $Id$ */ public class GazetteerNameValidation extends DefaultFeatureValidation { /** used to store the gazetteer url */ private URL gazetteer; /** used to store the Feature Attribute name to test for existance */ private String attributeName; /** * GazetteerNameValidation constructor. * * <p> * Does nothing * </p> */ public GazetteerNameValidation() { super(); try { gazetteer = new URL( "http://cgdi-dev.geoconnections.org/cgi-bin/prototypes/cgdigaz/cgdigaz.cgi?version=1.0&request=GetPlacenameGeometry&wildcards=false&geomtype=bbox"); } catch (MalformedURLException e) { } } /** * Implementation of validate. * * @param feature * @param type * @param results * * * @see org.geotools.validation.FeatureValidation#validate(org.geotools.feature.Feature, * org.geotools.feature.FeatureType, * org.geotools.validation.ValidationResults) */ public boolean validate(SimpleFeature feature, SimpleFeatureType type, ValidationResults results) { // throws Exception { String place = (String) feature.getAttribute(attributeName); URL gazetteerURL = null; try { gazetteerURL = new URL(gazetteer.toString() + "&placename=" + place); } catch (MalformedURLException e) { results.error(feature, e.toString()); return false; } InputStream gazetteerInputStream = null; try { HttpURLConnection gazetteerConnection = (HttpURLConnection) gazetteerURL .openConnection(); if (!("OK".equals(gazetteerConnection.getResponseMessage()))) { results.error(feature, "An error occured creating the connection to the Gazetteer."); } gazetteerInputStream = gazetteerConnection.getInputStream(); } catch (IOException e) { results.error(feature, e.toString()); return false; } InputStreamReader gazetteerInputStreamReader = new InputStreamReader(gazetteerInputStream); BufferedReader gazetteerBufferedReader = new BufferedReader(gazetteerInputStreamReader); InputSource gazetteerInputSource = new InputSource(gazetteerBufferedReader); DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); dfactory.setNamespaceAware(true); // TODO turn on validation dfactory.setValidating(false); dfactory.setIgnoringComments(true); dfactory.setCoalescing(true); dfactory.setIgnoringElementContentWhitespace(true); Document serviceDoc = null; try { serviceDoc = dfactory.newDocumentBuilder().parse(gazetteerInputSource); } catch (Exception e) { results.error(feature, e.toString()); } Element elem = serviceDoc.getDocumentElement(); // elem == SimpleFeatureCollection at this point elem = getChildElement(elem, "queryInfo"); if (elem == null) { results.error(feature, "Invalid DOM tree returned by gazetteer."); } // this number is the number of instances found. int number = Integer.parseInt(getChildText(elem, "numberOfResults")); return number > 0; } /** * Implementation of getPriority. * * * @see org.geotools.validation.Validation#getPriority() */ public int getPriority() { return 5; } /** * Access attributeName property. * * @return Returns the attributeName. */ public String getAttributeName() { return attributeName; } /** * Set attributeName to attributeName. * * @param attrName The attributeName to set. */ public void setAttributeName(String attrName) { this.attributeName = attrName; } /** * Access gazetteer property. * * @return Returns the gazetteer. */ public URL getGazetteer() { return gazetteer; } /** * Set gazetteer to gazetteer. * * @param gazetteer The gazetteer to set. */ public void setGazetteer(URL gazetteer) { this.gazetteer = gazetteer; } /** * getChildElement purpose. * * <p> * Used to help with XML manipulations. Returns the first child element of * the specified name. * </p> * * @param root The root element to look for children in. * @param name The name of the child element to look for. * * @return The child element found, null if not found. * * @see getChildElement(Element,String,boolean) */ private static Element getChildElement(Element root, String name) { Node child = root.getFirstChild(); while (child != null) { if (child.getNodeType() == Node.ELEMENT_NODE) { if (name.equals(child.getNodeName())) { return (Element) child; } } child = child.getNextSibling(); } return null; } /** * getChildText purpose. * * <p> * Used to help with XML manipulations. Returns the first child text value * of the specified element name. * </p> * * @param root The root element to look for children in. * @param childName The name of the attribute to look for. * * @return The value if the child was found, the null otherwise. */ private static String getChildText(Element root, String childName) { Element elem = getChildElement(root, childName); if (elem != null) { Node child; NodeList childs = elem.getChildNodes(); int nChilds = childs.getLength(); for (int i = 0; i < nChilds; i++) { child = childs.item(i); if (child.getNodeType() == Node.TEXT_NODE) { return child.getNodeValue(); } } } return null; } }