/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-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.data.gen.info; import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URL; import java.net.URLDecoder; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** * @author Christian Mueller * * The default implementation for GeneralizationInfosProvider, reading the info from an XML file. * * The xml schema file is "/geninfos_1.0.xsd" * * * * * @source $URL$ */ public class GeneralizationInfosProviderImpl implements GeneralizationInfosProvider { protected final static String GENERALIZATION_INFOS_TAG = "GeneralizationInfos"; protected final static String GENERALIZATION_INFO_TAG = "GeneralizationInfo"; protected final static String GENERALIZATION_TAG = "Generalization"; protected final static String FEATURE_NAME_ATTR = "featureName"; protected final static String BASE_FEATURE_NAME_ATTR = "baseFeatureName"; protected final static String GEOM_PROPERTY_NAME_ATTR = "geomPropertyName"; protected final static String DISTANCE_ATTR = "distance"; protected final static String DATASOURCE_NAME_ATTR = "dataSourceName"; protected final static String DATASOURCE_NAMESPACE_NAME_ATTR = "dataSourceNameSpace"; protected final static String VERSION_ATTR = "version"; protected static Validator VALIDATOR; static { SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); URL url = GeneralizationInfosProviderImpl.class.getResource("/geninfos_1.0.xsd"); Schema schema = null; try { schema = factory.newSchema(url); } catch (SAXException e) { // should not happen throw new RuntimeException(e); } VALIDATOR = schema.newValidator(); } public GeneralizationInfos getGeneralizationInfos(Object source) throws IOException { URL inputURL = deriveURLFromSourceObject(source); GeneralizationInfos infos = parseXML(inputURL); infos.validate(); return infos; } protected URL deriveURLFromSourceObject(Object source) throws IOException { if (source == null) throw new IOException("Cannot read from null"); if (source instanceof URL) return (URL) source; if (source instanceof String) { URL url = null; File f = new File((String) source); if (f.exists()) url = f.toURI().toURL(); else url = new URL((String) source); url = new URL(URLDecoder.decode(url.toExternalForm(), "UTF8")); return url; } if (source instanceof URI) return ((URI) source).toURL(); return null; } protected GeneralizationInfos parseXML(URL url) throws IOException { Document doc = null; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setIgnoringComments(true); factory.setNamespaceAware(true); factory.setIgnoringElementContentWhitespace(true); try { DocumentBuilder db = factory.newDocumentBuilder(); doc = db.parse(url.openStream()); VALIDATOR.validate(new DOMSource(doc)); } catch (Exception e) { throw new IOException(e.getMessage()); } NodeList nl = doc.getElementsByTagName(GENERALIZATION_INFOS_TAG); GeneralizationInfos gInfos = new GeneralizationInfos(); Node gInfosNode = nl.item(0); checkVersion(gInfosNode); NamedNodeMap attrMap = gInfosNode.getAttributes(); if (attrMap.getNamedItem(DATASOURCE_NAME_ATTR) != null) gInfos.setDataSourceName(attrMap.getNamedItem(DATASOURCE_NAME_ATTR).getTextContent()); if (attrMap.getNamedItem(DATASOURCE_NAMESPACE_NAME_ATTR) != null) gInfos.setDataSourceNameSpace(attrMap.getNamedItem(DATASOURCE_NAMESPACE_NAME_ATTR) .getTextContent()); parseGeneralizationInfoNodes(gInfosNode, gInfos); return gInfos; } protected void parseGeneralizationInfoNodes(Node parentNode, GeneralizationInfos gInfos) { NodeList nl = parentNode.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node generalisationInfoNode = nl.item(i); if (GENERALIZATION_INFO_TAG.equals(generalisationInfoNode.getNodeName()) == false) continue; NamedNodeMap attrMap = generalisationInfoNode.getAttributes(); String baseFeatureName = attrMap.getNamedItem(BASE_FEATURE_NAME_ATTR).getTextContent(); String featureName = attrMap.getNamedItem(FEATURE_NAME_ATTR).getTextContent(); String geomPropertyName = null; if (attrMap.getNamedItem(GEOM_PROPERTY_NAME_ATTR) != null) geomPropertyName = attrMap.getNamedItem(GEOM_PROPERTY_NAME_ATTR).getTextContent(); GeneralizationInfo gi = new GeneralizationInfo(baseFeatureName, featureName, geomPropertyName, gInfos); if (attrMap.getNamedItem(DATASOURCE_NAME_ATTR) != null) gi.setDataSourceName(attrMap.getNamedItem(DATASOURCE_NAME_ATTR).getTextContent()); if (attrMap.getNamedItem(DATASOURCE_NAMESPACE_NAME_ATTR) != null) gi.setDataSourceNameSpace(attrMap.getNamedItem(DATASOURCE_NAMESPACE_NAME_ATTR) .getTextContent()); parseDistanceInfoNodes(generalisationInfoNode, gi); gInfos.addGeneralizationInfo(gi); } } protected void parseDistanceInfoNodes(Node parentNode, GeneralizationInfo gInfo) { NodeList nl = parentNode.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node distanceInfoNode = nl.item(i); if (GENERALIZATION_TAG.equals(distanceInfoNode.getNodeName()) == false) continue; NamedNodeMap attrMap = distanceInfoNode.getAttributes(); Double distance = new Double(attrMap.getNamedItem(DISTANCE_ATTR).getTextContent()); String featureName = attrMap.getNamedItem(FEATURE_NAME_ATTR).getTextContent(); String geomPropertyName = null; if (attrMap.getNamedItem(GEOM_PROPERTY_NAME_ATTR) != null) geomPropertyName = attrMap.getNamedItem(GEOM_PROPERTY_NAME_ATTR).getTextContent(); Generalization di = new Generalization(distance, featureName, geomPropertyName, gInfo); if (attrMap.getNamedItem(DATASOURCE_NAME_ATTR) != null) di.setDataSourceName(attrMap.getNamedItem(DATASOURCE_NAME_ATTR).getTextContent()); if (attrMap.getNamedItem(DATASOURCE_NAMESPACE_NAME_ATTR) != null) di.setDataSourceNameSpace(attrMap.getNamedItem(DATASOURCE_NAMESPACE_NAME_ATTR) .getTextContent()); gInfo.getGeneralizations().add(di); } } protected void checkVersion(Node gInfos) throws IOException { String version = gInfos.getAttributes().getNamedItem(VERSION_ATTR).getTextContent(); if ("1.0".equals(version) == false) { throw new IOException(gInfos.getLocalName() + " " + version + " is not supported"); } } }