001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2004-2006, Geotools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * Created on Jan 21, 2004
017: */
018: package org.geotools.validation.attributes;
019:
020: import java.io.BufferedReader;
021: import java.io.IOException;
022: import java.io.InputStream;
023: import java.io.InputStreamReader;
024: import java.net.HttpURLConnection;
025: import java.net.MalformedURLException;
026: import java.net.URL;
027:
028: import javax.xml.parsers.DocumentBuilderFactory;
029:
030: import org.geotools.feature.Feature;
031: import org.geotools.feature.FeatureType;
032: import org.geotools.validation.DefaultFeatureValidation;
033: import org.geotools.validation.ValidationResults;
034: import org.w3c.dom.Document;
035: import org.w3c.dom.Element;
036: import org.w3c.dom.Node;
037: import org.w3c.dom.NodeList;
038: import org.xml.sax.InputSource;
039:
040: /**
041: * GazetteerNameValidation purpose.
042: *
043: * <p>
044: * Description of GazetteerNameValidation ...
045: * </p>
046: *
047: * <p>
048: * Capabilities:
049: * </p>
050: *
051: * <ul>
052: * <li>
053: * Feature: description
054: * </li>
055: * </ul>
056: *
057: * <p>
058: * Example Use:
059: * </p>
060: * <pre><code>
061: * GazetteerNameValidation x = new GazetteerNameValidation(...);
062: * </code></pre>
063: *
064: * @author dzwiers, Refractions Research, Inc.
065: * @author $Author: dmzwiers $ (last modification)
066: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/extension/validation/src/main/java/org/geotools/validation/attributes/GazetteerNameValidation.java $
067: * @version $Id: GazetteerNameValidation.java 22266 2006-10-19 11:30:55Z acuster $
068: */
069: public class GazetteerNameValidation extends DefaultFeatureValidation {
070: /** used to store the gazetteer url */
071: private URL gazetteer;
072:
073: /** used to store the Feature Attribute name to test for existance */
074: private String attributeName;
075:
076: /**
077: * GazetteerNameValidation constructor.
078: *
079: * <p>
080: * Does nothing
081: * </p>
082: */
083: public GazetteerNameValidation() {
084: super ();
085:
086: try {
087: gazetteer = new URL(
088: "http://cgdi-dev.geoconnections.org/cgi-bin/prototypes/cgdigaz/cgdigaz.cgi?version=1.0&request=GetPlacenameGeometry&wildcards=false&geomtype=bbox");
089: } catch (MalformedURLException e) {
090: }
091: }
092:
093: /**
094: * Implementation of validate.
095: *
096: * @param feature
097: * @param type
098: * @param results
099: *
100: *
101: * @see org.geotools.validation.FeatureValidation#validate(org.geotools.feature.Feature,
102: * org.geotools.feature.FeatureType,
103: * org.geotools.validation.ValidationResults)
104: */
105: public boolean validate(Feature feature, FeatureType type,
106: ValidationResults results) { // throws Exception {
107:
108: String place = (String) feature.getAttribute(attributeName);
109: URL gazetteerURL = null;
110:
111: try {
112: gazetteerURL = new URL(gazetteer.toString() + "&placename="
113: + place);
114: } catch (MalformedURLException e) {
115: results.error(feature, e.toString());
116:
117: return false;
118: }
119:
120: InputStream gazetteerInputStream = null;
121:
122: try {
123: HttpURLConnection gazetteerConnection = (HttpURLConnection) gazetteerURL
124: .openConnection();
125:
126: if (!("OK".equals(gazetteerConnection.getResponseMessage()))) {
127: results
128: .error(feature,
129: "An error occured creating the connection to the Gazetteer.");
130: }
131:
132: gazetteerInputStream = gazetteerConnection.getInputStream();
133: } catch (IOException e) {
134: results.error(feature, e.toString());
135:
136: return false;
137: }
138:
139: InputStreamReader gazetteerInputStreamReader = new InputStreamReader(
140: gazetteerInputStream);
141: BufferedReader gazetteerBufferedReader = new BufferedReader(
142: gazetteerInputStreamReader);
143:
144: InputSource gazetteerInputSource = new InputSource(
145: gazetteerBufferedReader);
146: DocumentBuilderFactory dfactory = DocumentBuilderFactory
147: .newInstance();
148: dfactory.setNamespaceAware(true);
149:
150: // TODO turn on validation
151: dfactory.setValidating(false);
152: dfactory.setIgnoringComments(true);
153: dfactory.setCoalescing(true);
154: dfactory.setIgnoringElementContentWhitespace(true);
155:
156: Document serviceDoc = null;
157:
158: try {
159: serviceDoc = dfactory.newDocumentBuilder().parse(
160: gazetteerInputSource);
161: } catch (Exception e) {
162: results.error(feature, e.toString());
163: }
164:
165: Element elem = serviceDoc.getDocumentElement();
166:
167: // elem == featureCollection at this point
168: elem = getChildElement(elem, "queryInfo");
169:
170: if (elem == null) {
171: results.error(feature,
172: "Invalid DOM tree returned by gazetteer.");
173: }
174:
175: // this number is the number of instances found.
176: int number = Integer.parseInt(getChildText(elem,
177: "numberOfResults"));
178:
179: return number > 0;
180: }
181:
182: /**
183: * Implementation of getPriority.
184: *
185: *
186: * @see org.geotools.validation.Validation#getPriority()
187: */
188: public int getPriority() {
189: return 5;
190: }
191:
192: /**
193: * Access attributeName property.
194: *
195: * @return Returns the attributeName.
196: */
197: public String getAttributeName() {
198: return attributeName;
199: }
200:
201: /**
202: * Set attributeName to attributeName.
203: *
204: * @param attrName The attributeName to set.
205: */
206: public void setAttributeName(String attrName) {
207: this .attributeName = attrName;
208: }
209:
210: /**
211: * Access gazetteer property.
212: *
213: * @return Returns the gazetteer.
214: */
215: public URL getGazetteer() {
216: return gazetteer;
217: }
218:
219: /**
220: * Set gazetteer to gazetteer.
221: *
222: * @param gazetteer The gazetteer to set.
223: */
224: public void setGazetteer(URL gazetteer) {
225: this .gazetteer = gazetteer;
226: }
227:
228: /**
229: * getChildElement purpose.
230: *
231: * <p>
232: * Used to help with XML manipulations. Returns the first child element of
233: * the specified name.
234: * </p>
235: *
236: * @param root The root element to look for children in.
237: * @param name The name of the child element to look for.
238: *
239: * @return The child element found, null if not found.
240: *
241: * @see getChildElement(Element,String,boolean)
242: */
243: private static Element getChildElement(Element root, String name) {
244: Node child = root.getFirstChild();
245:
246: while (child != null) {
247: if (child.getNodeType() == Node.ELEMENT_NODE) {
248: if (name.equals(child.getNodeName())) {
249: return (Element) child;
250: }
251: }
252:
253: child = child.getNextSibling();
254: }
255:
256: return null;
257: }
258:
259: /**
260: * getChildText purpose.
261: *
262: * <p>
263: * Used to help with XML manipulations. Returns the first child text value
264: * of the specified element name.
265: * </p>
266: *
267: * @param root The root element to look for children in.
268: * @param childName The name of the attribute to look for.
269: *
270: * @return The value if the child was found, the null otherwise.
271: */
272: private static String getChildText(Element root, String childName) {
273: Element elem = getChildElement(root, childName);
274:
275: if (elem != null) {
276: Node child;
277: NodeList childs = elem.getChildNodes();
278: int nChilds = childs.getLength();
279:
280: for (int i = 0; i < nChilds; i++) {
281: child = childs.item(i);
282:
283: if (child.getNodeType() == Node.TEXT_NODE) {
284: return child.getNodeValue();
285: }
286: }
287: }
288:
289: return null;
290: }
291: }
|