org.geotools.data.mongodb.MongoDataStore.java Source code

Java tutorial

Introduction

Here is the source code for org.geotools.data.mongodb.MongoDataStore.java

Source

package org.geotools.data.mongodb;

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

import org.bson.types.BasicBSONList;
import org.geotools.data.DataStore;
import org.geotools.data.DefaultServiceInfo;
import org.geotools.data.EmptyFeatureWriter;
import org.geotools.data.FeatureListener;
import org.geotools.data.FeatureListenerManager;
import org.geotools.data.FeatureReader;
import org.geotools.data.FeatureSource;
import org.geotools.data.FeatureWriter;
import org.geotools.data.LockingManager;
import org.geotools.data.Query;
import org.geotools.data.ServiceInfo;
import org.geotools.data.Transaction;
import org.geotools.data.mongodb.MongoLayer.GeometryType;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.feature.NameImpl;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.Name;
import org.opengis.filter.Filter;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.Mongo;
import com.mongodb.MongoException;

/**
 * Represents a mongoDB-backed GeoServer Data Store; manages layers representing mongoDB collections
 * containing GeoJSON-encoded geospatial data
 * 
 * @author Gerald Gay, Data Tactics Corp.
 * @author Alan Mangan, Data Tactics Corp.
 * @source $URL$
 * 
 *         (C) 2011, Open Source Geospatial Foundation (OSGeo)
 * 
 * @see The GNU Lesser General Public License (LGPL)
 */
/* 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; either version
 * 2.1 of the License, or (at your option) any later version.
 * 
 * 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.
 * 
 * You should have received a copy of the GNU Lesser General Public License along with this library;
 * if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301 USA */
public class MongoDataStore implements DataStore {

    /** List of mongo layers for this mongo store */
    private ArrayList<MongoLayer> layers = null;
    private CoordinateReferenceSystem crs = null;
    /** Config for this mongo plugin */
    private MongoPluginConfig config = null;
    private FeatureListenerManager lsnMgr = null;

    /** Package logger */
    private final static Logger log = MongoPluginConfig.getLog();

    public MongoDataStore(MongoPluginConfig config) {
        this.config = config;
        lsnMgr = new FeatureListenerManager();
        layers = new ArrayList<MongoLayer>();
        log.info("MongoDataStore; layers=" + layers);
        try {
            crs = CRS.decode("EPSG:4326");
        } catch (Throwable t) {
            crs = DefaultGeographicCRS.WGS84;
        }
        // TODO when to look for and detect changes to layers
        if (layers.size() == 0) {
            getLayers();
        }
    }

    /**
     * Get list of valid layers for this mongo DB; those containing at least one valid, non-null
     * GeoJSON geometry
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    private void getLayers() {
        Mongo mongo = null;
        try {
            // Get the list of collections from Mongo...
            mongo = new Mongo(config.getHost(), config.getPort());
            DB db = mongo.getDB(config.getDB()); // TODO add authentication
            Set<String> colls = db.getCollectionNames();
            for (String s : colls) {
                DBCollection dbc = db.getCollection(s);
                log.info("getLayers; collection=" + dbc);
                // find distinct non-null geometry to determine if valid layer
                // TODO branch point for separate geometry-specific layers per collection
                List geoList = dbc.distinct("geometry.type");
                // distinct returns single BSON List, may barf if results large, > max doc. size
                // trap exception on props distinct and assume it's valid since there's obviously
                // something there (http://www.mongodb.org/display/DOCS/Aggregation)
                List propList = null;
                try {
                    propList = dbc.distinct("properties");
                } catch (IllegalArgumentException ex) {
                    propList = new BasicBSONList();
                    propList.add("ex nihilo");
                } catch (MongoException ex) {
                    propList = new BasicBSONList();
                    propList.add("ex nihilo");
                }
                // check that layer has valid geometry and some properties defined
                if (geoList != null && propList != null && propList.size() > 0) {
                    boolean hasValidGeo = false;
                    for (GeometryType type : GeometryType.values()) {
                        if (geoList.contains(type.toString())) {
                            hasValidGeo = true;
                            break;
                        }
                    }
                    if (hasValidGeo) {
                        layers.add(new MongoLayer(dbc, config));
                    }
                }
            }
        } catch (Throwable t) {
            log.severe("getLayers error; " + t.getLocalizedMessage());
        }
        if (mongo != null) {
            mongo.close();
        }
    }

    public CoordinateReferenceSystem getCRS() {
        return crs;
    }

    public MongoPluginConfig getConfig() {
        return config;
    }

    public void addListener(FeatureSource<?, ?> src, FeatureListener listener) {
        lsnMgr.addFeatureListener(src, listener);
    }

    public void removeListener(FeatureSource<?, ?> src, FeatureListener listener) {
        lsnMgr.removeFeatureListener(src, listener);
    }

    public Set<String> getKeywords(String typeName) {
        Set<String> result = null;

        for (MongoLayer ml : layers) {
            if (ml.getName().equals(typeName)) {
                result = ml.getKeywords();
                break;
            }
        }

        return result;
    }

    public LockingManager getLockingManager() {
        // returning null as per DataStore.getLockingManager() contract
        return null;
    }

    public FeatureWriter<SimpleFeatureType, SimpleFeature> getFeatureWriterAppend(final String typeName,
            final Transaction transaction) {
        return new EmptyFeatureWriter(new SimpleFeatureTypeBuilder().buildFeatureType());
    }

    public FeatureWriter<SimpleFeatureType, SimpleFeature> getFeatureWriter(final String typeName,
            final Transaction transaction) {
        return new EmptyFeatureWriter(new SimpleFeatureTypeBuilder().buildFeatureType());
    }

    public FeatureWriter<SimpleFeatureType, SimpleFeature> getFeatureWriter(final String typeName,
            final Filter filter, final Transaction transaction) {
        return new EmptyFeatureWriter(new SimpleFeatureTypeBuilder().buildFeatureType());
    }

    public FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader(final Query query,
            final Transaction transaction) {
        FilterToMongoQuery f2m = new FilterToMongoQuery();
        Filter filter = query.getFilter();
        BasicDBObject dbo = (BasicDBObject) filter.accept(f2m, null);
        MongoLayer layer = getMongoLayer(query.getTypeName());
        MongoResultSet rs = new MongoResultSet(layer, dbo);
        return new MongoFeatureReader(rs);
    }

    public SimpleFeatureSource getFeatureSource(final String typeName) throws IOException {
        MongoLayer layer = getMongoLayer(typeName);
        return new MongoFeatureSource(this, layer);
    }

    public FeatureSource<SimpleFeatureType, SimpleFeature> getView(final Query query) {
        FilterToMongoQuery f2m = new FilterToMongoQuery();
        Filter filter = query.getFilter();
        BasicDBObject dbo = (BasicDBObject) filter.accept(f2m, null);
        MongoLayer layer = getMongoLayer(query.getTypeName());
        return new MongoFeatureSource(this, layer, dbo);
    }

    public SimpleFeatureType getSchema(final String typeName) {
        SimpleFeatureType sft = null;

        for (MongoLayer ml : layers) {
            if (ml.getName().equals(typeName)) {
                sft = ml.getSchema();
            }
        }

        return sft;
    }

    public String[] getTypeNames() {
        String[] names = new String[layers.size()];
        int idx = 0;
        for (MongoLayer ml : layers) {
            names[idx++] = ml.getName();
        }
        return names;
    }

    public void updateSchema(final String typeName, final SimpleFeatureType featureType) throws IOException {
        throw new UnsupportedOperationException("Schema modification not supported");
    }

    public void dispose() {

    }

    public SimpleFeatureSource getFeatureSource(Name name) throws IOException {
        return getFeatureSource(name.getLocalPart());
    }

    public SimpleFeatureType getSchema(Name name) throws IOException {
        return getSchema(name.getLocalPart());
    }

    public List<Name> getNames() throws IOException {
        List<Name> names = new ArrayList<Name>(layers.size());
        for (MongoLayer ml : layers) {
            names.add(new NameImpl(ml.getName()));
        }
        return names;
    }

    public void updateSchema(Name typeName, SimpleFeatureType featureType) throws IOException {
        updateSchema(typeName.getLocalPart(), featureType);
    }

    public void createSchema(final SimpleFeatureType featureType) throws IOException, IllegalArgumentException {

    }

    public ServiceInfo getInfo() {
        DefaultServiceInfo info = new DefaultServiceInfo();
        info.setTitle("MongoDB Data Store");
        info.setDescription("Features from MongoDB");
        try {
            info.setSchema(new URI(config.getNamespace()));
        } catch (Throwable t) {
        }
        return info;
    }

    public MongoLayer getMongoLayer(String typeName) {
        MongoLayer layer = null;
        for (MongoLayer ml : layers) {
            if (ml.getName().equals(typeName)) {
                layer = ml;
                break;
            }
        }
        return layer;
    }

}