/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2015, Open Source Geospatial Foundation (OSGeo) * (C) 2014-2015, Boundless * * 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.mongodb; import com.mongodb.BasicDBList; import com.mongodb.BasicDBObject; import com.mongodb.DBCollection; import com.mongodb.DBObject; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; /** * * @author tkunicki@boundlessgeo.com */ public class MongoUtil { public static Object getDBOValue(DBObject dbo, String path) { return getDBOValue(dbo, Arrays.asList(path.split("\\.")).iterator()); } public static Object getDBOValue(DBObject dbo, Iterator<String> path) { return getDBOValueInternal(path, dbo); } private static Object getDBOValueInternal(Iterator<String> path, Object current) { if (path.hasNext()) { if (current instanceof DBObject) { String key = path.next(); //If we are in an array, key must be an int if (current instanceof BasicDBList) { try { Integer.parseInt(key); } catch (NumberFormatException e) { return null; } } Object value = ((DBObject)current).get(key); return getDBOValueInternal(path, value); } return null; } else { return current; } } public static void setDBOValue(DBObject dbo, String path, Object value) { setDBOValue(dbo, Arrays.asList(path.split("\\.")).iterator(), value); } public static void setDBOValue(DBObject dbo, Iterator<String> path, Object value) { setDBOValueInternal(dbo, path, value); } private static void setDBOValueInternal(DBObject currentDBO, Iterator<String> path, Object value) { String key = path.next(); if (path.hasNext()) { Object next = currentDBO.get(key); DBObject nextDBO; if (next instanceof DBObject) { nextDBO = (DBObject)next; } else { currentDBO.put(key, nextDBO = new BasicDBObject()); } setDBOValueInternal(nextDBO, path, value); } else { currentDBO.put(key, value); } } public static Set<String> findIndexedGeometries(DBCollection dbc) { return findIndexedFields(dbc, "2dsphere"); } public static Set<String> findIndexedFields(DBCollection dbc) { return findIndexedFields(dbc, null); } public static Set<String> findIndexedFields(DBCollection dbc, String type) { Set<String> fields = new LinkedHashSet<String>(); List<DBObject> indices = dbc.getIndexInfo(); for (DBObject index : indices) { Object key = index.get("key"); if (key instanceof DBObject) { for (Map.Entry<?,?> entry : ((Map<?,?>)((DBObject)key).toMap()).entrySet()) { if (type == null || type.equals(entry.getValue())) { fields.add(entry.getKey().toString()); } } } } fields.remove("_id"); return fields; } public static Map<String, Class<?>> findMappableFields(DBCollection dbc) { return findMappableFields(dbc.findOne()); } public static Map<String, Class<?>> findMappableFields(DBObject dbo) { if (dbo == null) { return Collections.emptyMap(); } Map<String, Class<?>> map = doFindMappableFields(dbo); map.remove("_id"); return map; } private static Map<String, Class<?>> doFindMappableFields(DBObject dbo) { if (dbo == null) { return Collections.emptyMap(); } Map<String, Class<?>> map = new LinkedHashMap<String, Class<?>>(); for (Map.Entry<?,?> e : ((Map<?,?>)dbo.toMap()).entrySet()) { Object k = e.getKey(); if (k instanceof String) { String field = (String)k; Object v = e.getValue(); if (v instanceof DBObject) { if (v instanceof BasicDBList) { //No list support } else { for (Map.Entry<String, Class<?>> childEntry : doFindMappableFields((DBObject)v).entrySet()) { map.put(field + "." + childEntry.getKey(), childEntry.getValue()); } } } else if (v instanceof List) { // this is here as documentation/placeholder. no array/list support yet. } else { Class<?> binding = mapBSONObjectToJavaType(v); if (binding != null) { map.put(field, binding); } } } } return map; } public static Class<?> mapBSONObjectToJavaType(Object o) { if (o instanceof String || o instanceof Double || o instanceof Long || o instanceof Integer || o instanceof Boolean || o instanceof Date) { return o.getClass(); } return null; } }