/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.importer.format; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import javax.xml.namespace.QName; import org.geotools.kml.v22.KML; import org.geotools.kml.v22.KMLConfiguration; import org.geotools.xml.PullParser; import org.opengis.feature.simple.SimpleFeatureType; public class KMLRawReader implements Iterable<Object>, Iterator<Object> { private final PullParser parser; private Object next; public static enum ReadType { FEATURES, SCHEMA_AND_FEATURES } public KMLRawReader(InputStream inputStream) { this(inputStream, KMLRawReader.ReadType.FEATURES, null); } public KMLRawReader(InputStream inputStream, KMLRawReader.ReadType readType) { this(inputStream, readType, null); } public KMLRawReader(InputStream inputStream, KMLRawReader.ReadType readType, SimpleFeatureType featureType) { if (KMLRawReader.ReadType.SCHEMA_AND_FEATURES.equals(readType)) { if (featureType == null) { parser = new PullParser(new KMLConfiguration(), inputStream, KML.Placemark, KML.Schema); } else { parser = new PullParser(new KMLConfiguration(), inputStream, pullParserArgs( featureTypeSchemaNames(featureType), KML.Placemark, KML.Schema)); } } else if (KMLRawReader.ReadType.FEATURES.equals(readType)) { if (featureType == null) { parser = new PullParser(new KMLConfiguration(), inputStream, KML.Placemark); } else { parser = new PullParser(new KMLConfiguration(), inputStream, pullParserArgs( featureTypeSchemaNames(featureType), KML.Placemark)); } } else { throw new IllegalArgumentException("Unknown parse read type: " + readType.toString()); } next = null; } private Object[] pullParserArgs(List<QName> featureTypeSchemaNames, Object... args) { Object[] parserArgs = new Object[featureTypeSchemaNames.size() + args.length]; System.arraycopy(args, 0, parserArgs, 0, args.length); System.arraycopy(featureTypeSchemaNames.toArray(), 0, parserArgs, args.length, featureTypeSchemaNames.size()); return parserArgs; } @SuppressWarnings("unchecked") private List<QName> featureTypeSchemaNames(SimpleFeatureType featureType) { Map<Object, Object> userData = featureType.getUserData(); if (userData.containsKey("schemanames")) { List<String> names = (List<String>) userData.get("schemanames"); List<QName> qnames = new ArrayList<QName>(names.size()); for (String name : names) { qnames.add(new QName(name)); } return qnames; } return Collections.emptyList(); } private Object read() throws IOException { Object parsedObject; try { parsedObject = parser.parse(); } catch (Exception e) { e.printStackTrace(); throw new IOException(e); } return parsedObject; } @Override public boolean hasNext() { if (next != null) { return true; } try { next = read(); } catch (IOException e) { next = null; } return next != null; } @Override public Object next() { if (next != null) { Object result = next; next = null; return result; } Object feature; try { feature = read(); } catch (IOException e) { feature = null; } if (feature == null) { throw new NoSuchElementException(); } return feature; } @Override public Iterator<Object> iterator() { return this; } @Override public void remove() { throw new UnsupportedOperationException(); } }