Package org.locationtech.geogig.geotools.plumbing

Source Code of org.locationtech.geogig.geotools.plumbing.FeatureTypeAdapterFeatureSource$FeatureTypeConverterIterator

/* Copyright (c) 2014 Boundless and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/edl-v10.html
*
* Contributors:
* Victor Olaya (Boundless) - initial implementation
*/
package org.locationtech.geogig.geotools.plumbing;

import static com.google.common.base.Preconditions.checkNotNull;

import java.io.IOException;

import org.geotools.data.FeatureSource;
import org.geotools.data.Query;
import org.geotools.data.QueryCapabilities;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.locationtech.geogig.api.data.ForwardingFeatureCollection;
import org.locationtech.geogig.api.data.ForwardingFeatureIterator;
import org.locationtech.geogig.api.data.ForwardingFeatureSource;
import org.opengis.feature.Feature;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.FeatureType;
import org.opengis.feature.type.GeometryDescriptor;
import org.opengis.feature.type.Name;
import org.opengis.filter.sort.SortBy;

class FeatureTypeAdapterFeatureSource<T extends FeatureType, F extends Feature> extends
        ForwardingFeatureSource<T, F> {

    private T featureType;

    private boolean forbidSorting;

    public FeatureTypeAdapterFeatureSource(final FeatureSource<T, F> source, final T featureType) {
        super(source);
        this.featureType = featureType;
    }

    @Override
    public T getSchema() {
        return featureType;
    }

    /**
     * @param forbidSorting flag for {@link #getQueryCapabilities()} to return false on
     *        isOffsetSupported() to work around malfunctioning geotools datastores from
     */
    public void setForbidSorting(boolean forbidSorting) {
        this.forbidSorting = forbidSorting;
    }

    @Override
    public QueryCapabilities getQueryCapabilities() {
        final QueryCapabilities capabilities = super.getQueryCapabilities();
        if (!forbidSorting) {
            return capabilities;
        }
        return new QueryCapabilities() {
            @Override
            public boolean isOffsetSupported() {
                return false;
            }

            @Override
            public boolean supportsSorting(SortBy[] sortAttributes) {
                return false;
            }

            @Override
            public boolean isReliableFIDSupported() {
                return capabilities.isReliableFIDSupported();
            }

            @Override
            public boolean isUseProvidedFIDSupported() {
                return capabilities.isUseProvidedFIDSupported();
            }
        };
    }

    @Override
    public FeatureCollection<T, F> getFeatures(Query query) throws IOException {

        final FeatureCollection<T, F> features = super.getFeatures(query);
        return new ForwardingFeatureCollection<T, F>(features) {

            @Override
            public FeatureIterator<F> features() {
                if (delegate.getSchema().getDescriptors().size() != featureType.getDescriptors()
                        .size()) {
                    throw new GeoToolsOpException(
                            GeoToolsOpException.StatusCode.INCOMPATIBLE_FEATURE_TYPE);
                }
                GeometryDescriptor geomDescriptorOrg = delegate.getSchema().getGeometryDescriptor();
                GeometryDescriptor geomDescriptorDest = featureType.getGeometryDescriptor();
                if (!geomDescriptorOrg.getType().getBinding()
                        .equals(geomDescriptorDest.getType().getBinding())
                        || !geomDescriptorOrg
                                .getType()
                                .getCoordinateReferenceSystem()
                                .equals(geomDescriptorDest.getType().getCoordinateReferenceSystem())) {
                    throw new GeoToolsOpException(
                            GeoToolsOpException.StatusCode.INCOMPATIBLE_FEATURE_TYPE);
                }
                FeatureIterator<F> iterator = delegate.features();
                SimpleFeatureBuilder builder = new SimpleFeatureBuilder(
                        (SimpleFeatureType) featureType);

                return new FeatureTypeConverterIterator<F>(iterator, (SimpleFeatureBuilder) builder);
            }

            @Override
            public T getSchema() {
                return featureType;
            }
        };
    }

    private static class FeatureTypeConverterIterator<F extends Feature> extends
            ForwardingFeatureIterator<F> {

        private SimpleFeatureBuilder builder;

        public FeatureTypeConverterIterator(final FeatureIterator<F> iterator,
                SimpleFeatureBuilder builder) {
            super(iterator);
            checkNotNull(builder);
            this.builder = builder;
        }

        @SuppressWarnings("unchecked")
        @Override
        public F next() {
            F next = super.next();
            String fid = ((SimpleFeature) next).getID();
            Name geometryAttributeName = builder.getFeatureType().getGeometryDescriptor().getName();
            builder.set(geometryAttributeName, next.getDefaultGeometryProperty().getValue());
            for (AttributeDescriptor attribute : builder.getFeatureType().getAttributeDescriptors()) {
                Name name = attribute.getName();
                if (!name.equals(geometryAttributeName)) {
                    Property property = next.getProperty(name);
                    if (property == null) {
                        throw new GeoToolsOpException(
                                GeoToolsOpException.StatusCode.INCOMPATIBLE_FEATURE_TYPE);
                    }
                    builder.set(name, next.getProperty(name).getValue());
                }
            }
            return (F) builder.buildFeature(fid);
        }
    }

}
TOP

Related Classes of org.locationtech.geogig.geotools.plumbing.FeatureTypeAdapterFeatureSource$FeatureTypeConverterIterator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.