package org.geotools.data.efeature; import java.io.IOException; import java.util.Collections; import java.util.Map; import java.util.NoSuchElementException; import java.util.WeakHashMap; import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EcoreUtil; import org.geotools.data.AttributeReader; import org.geotools.data.Query; import org.geotools.data.efeature.query.EFeatureEncoderException; import org.geotools.data.efeature.query.EFeatureQuery; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.AttributeDescriptor; /** * * @author kengu * */ public class EFeatureAttributeReader implements AttributeReader { private final SimpleFeatureType type; private final EFeatureFolderInfo eFolderInfo; private final EFeatureInfo eFeatureInfo; private EFeatureQuery eQuery; private EObject eNext; private EFeatureIterator eIterator; private Map<String, EAttribute> eAttributes = Collections .synchronizedMap(new WeakHashMap<String, EAttribute>()); // ----------------------------------------------------- // Constructors // ----------------------------------------------------- /** * The {@link EFeatureAttributeReader} constructor * * @param eDataStore - {@link EFeatureDataStore} instance * @param query - GeoTools {@link Query} instance * @throws IOException */ public EFeatureAttributeReader(EFeatureDataStore eDataStore, Query query) throws IOException { // // Initialize reader // String eType = query.getTypeName(); String eFolder = EFeatureUtils.toFolderName(eType); String eFeature = EFeatureUtils.toFeatureName(eType); eFolderInfo = eDataStore.ePackageInfo.eGetFolderInfo(eFolder); eFeatureInfo = eFolderInfo.eGetFeatureInfo(eFeature); this.type = eFeatureInfo.getFeatureType(); // // Get attribute names from query // String[] eNames = (query == null ? new String[0] : query.getPropertyNames()); // // Get all attributes as defined by EFeatureInfo? // if (eNames == null || eNames.length == 0) { // // Get subset of attributes from EClass as defined by EFeatureInfo only // this.eAttributes.putAll(eFeatureInfo.eGetAttributeMap(true)); } else { // // Get subset of attributes as defined by EFeatureInfo AND GeoTools Query // this.eAttributes.putAll(eFeatureInfo.eGetAttributeMap(eNames,true)); } // // Get objects as tree iterator (enables lazy loading) // TreeIterator<EObject> eObjects = eDataStore.eResource().getAllContents(); // // Convert GeoTools query to EFeatureQuery statement // try { eQuery = EFeatureUtils.toEFeatureQuery(eFeatureInfo, eObjects, query.getFilter()); } catch (EFeatureEncoderException ex) { throw (IOException) new IOException("Failed to create EFeatureQuery").initCause(ex); } } // ----------------------------------------------------- // EFeatureAttributeReader methods // ----------------------------------------------------- /** * Get {@link SimpleFeatureType} instance. * * @return a {@link SimpleFeatureType} instance. */ public SimpleFeatureType getFeatureType() { return type; } @Override public int getAttributeCount() { return type.getAttributeCount(); } @Override public AttributeDescriptor getAttributeType(int index) throws ArrayIndexOutOfBoundsException { return type.getDescriptor(index); } public void reset() { this.eNext = null; this.eIterator = null; } @Override public void close() throws IOException { this.eNext = null; this.eIterator = null; this.eQuery.dispose(); this.eQuery = null; this.eAttributes.clear(); } @Override public boolean hasNext() throws IOException { if (eNext != null) { return true; } if (eIterator == null) { // Get EFeature iterator // eIterator = eQuery.iterator(); } if(eIterator.hasNext()) { eNext = eIterator.next(); } return eNext != null; } @Override public void next() throws IOException { if (hasNext()) { eNext = null; } else { throw new NoSuchElementException(); } } public EObject get() { return eNext; } @Override public Object read(int index) throws IOException, ArrayIndexOutOfBoundsException { if (eNext == null) { throw new IOException("No content available - did you remeber to call next?"); } EAttribute eAttribute = eAttributes.get(getAttributeName(index)); return (eAttribute != null ? eNext.eGet(eAttribute) : null); } /** * Get {@link EFeature} attribute name at given index * * @param index - given index * @return a {@link EFeature} attribute name if found. * @see {@link AttributeDescriptor#getLocalName()} */ public String getAttributeName(int index) { return getAttributeType(index).getLocalName(); } // ----------------------------------------------------- // Helper methods // ----------------------------------------------------- /** * Get current {@link EFeature} id * * @return a {@link EFeature} id. * @see {@link EcoreUtil#getID(EObject)} */ protected String getFeatureID() { if (eNext == null) { return null; } return EcoreUtil.getID(eNext); } }