bhl.pages.database.MongoConnection.java Source code

Java tutorial

Introduction

Here is the source code for bhl.pages.database.MongoConnection.java

Source

/*
 * This file is part of BHLPages.
 *
 *  BHLPages is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  BHLPages 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with BHLPages.  If not, see <http://www.gnu.org/licenses/>.
 *  (c) copyright Biodiversity Heritage Library 2015 
 *  http://www.biodiversitylibrary.org/
 */

package bhl.pages.database;

import bhl.pages.constants.Database;
import bhl.pages.exception.*;
import bhl.pages.constants.JSONKeys;
import java.util.Iterator;
import com.mongodb.MongoClient;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.DBCursor;
import java.util.List;
import org.bson.types.ObjectId;
import org.json.simple.JSONObject;

/**
 * Database interface for MongoDB
 * @author desmond
 */
public class MongoConnection extends Connection {
    MongoClient client;
    static int MONGO_PORT = 27017;
    /** connection to database */
    DB db;

    public MongoConnection(String user, String password, String host, String dbName, int dbPort, int wsPort) {
        super(user, password, host, dbName, dbPort, wsPort);
    }

    /**
     * Connect to the database
     * @throws Exception 
     */
    private void connect() throws Exception {
        if (db == null) {
            MongoClient mongoClient = new MongoClient(host, MONGO_PORT);
            db = mongoClient.getDB(this.databaseName);
            //boolean auth = db.authenticate( user, password.toCharArray() );
            //if ( !auth )
            //    throw new DbException( "MongoDB authentication failed");
        }
    }

    /**
     * Get the Mongo db collection object from its name
     * @param collName the collection name
     * @return a DBCollection object
     * @throws DbException 
     */
    private DBCollection getCollectionFromName(String collName) throws DbException {
        DBCollection coll = db.getCollection(collName);
        if (coll == null)
            coll = db.createCollection(collName, null);
        if (coll != null)
            return coll;
        else
            throw new DbException("Unknown collection " + collName);
    }

    /**
     * List all the documents in a Mongo collection
     * @param collName the name of the collection
     * @param key the document key to retrieve by
     * @return a String array of document keys
     * @throws DbException 
     */
    @Override
    public String[] listCollectionByKey(String collName, String key) throws DbException {
        try {
            connect();
        } catch (Exception e) {
            throw new DbException(e);
        }
        DBCollection coll = getCollectionFromName(collName);
        BasicDBObject keys = new BasicDBObject();
        keys.put(key, 1);
        DBCursor cursor = coll.find(new BasicDBObject(), keys);
        if (cursor.length() > 0) {
            String[] docs = new String[cursor.length()];
            Iterator<DBObject> iter = cursor.iterator();
            int i = 0;
            while (iter.hasNext()) {
                Object obj = iter.next().get(key);
                docs[i++] = obj.toString();
            }
            return docs;
        } else
            throw new DbException("no docs in collection " + collName);
    }

    /**
     * Fetch a resource from the server via a given field value
     * @param collName the collection or database name
     * @param value the value of the field
     * @param field the field name
     * @return the response as a string or null if not found
     */
    @Override
    public String getFromDbByIntField(String collName, int value, String field) throws DbException {
        try {
            connect();
            DBCollection coll = getCollectionFromName(collName);
            DBObject query = new BasicDBObject(field, value);
            DBObject obj = coll.findOne(query);
            if (obj != null)
                return obj.toString();
            else
                return null;
        } catch (Exception e) {
            throw new DbException(e);
        }
    }

    /**
     * Make a subset of the documents by a given subkey and value, 
     * then retrieve all the values of the field
     * @param collection the collection to search
     * @param subKey the subKey to make the initial choice
     * @param subValue the value of the subKey to search for
     * @param fields the field names to retrieve
     * @return and array of field values as JSON object strings
     * @throws DbException 
     */
    @Override
    public String[] listCollectionBySubKey(String collection, String subKey, String subValue, String[] fields)
            throws DbException {
        try {
            connect();
            DBCollection coll = getCollectionFromName(collection);
            DBObject query = new BasicDBObject(subKey, subValue);
            BasicDBObject keys = new BasicDBObject();
            for (int i = 0; i < fields.length; i++)
                keys.put(fields[i], 1);
            DBCursor cursor = coll.find(query, keys);
            if (cursor.length() > 0) {
                String[] array = new String[cursor.length()];
                Iterator iter = cursor.iterator();
                int i = 0;
                while (iter.hasNext()) {
                    DBObject bson = (DBObject) iter.next();
                    JSONObject jobj = new JSONObject();
                    for (int j = 0; j < fields.length; j++)
                        jobj.put(fields[j], bson.get(fields[j]));
                    array[i++] = jobj.toJSONString();
                }
                return array;
            } else
                return new String[0];
        } catch (Exception e) {
            throw new DbException(e);
        }
    }

    /**
     * Get the content of the given page and document
     * @param docid the document identifier (an integer in BHL)
     * @param pageid the page identifier (NOT page_sequence) also an int
     * @return the textual content as a String
     * @throws Exception 
     */
    public String getPageContent(String docid, String pageid) throws DbException {
        try {
            if (docid != null && pageid != null) {
                connect();
                DBCollection coll = db.getCollection(Database.PAGES);
                BasicDBObject ref = new BasicDBObject();
                ref.put(JSONKeys.IA_IDENTIFIER, docid);
                ref.put(JSONKeys.BHL_PAGE_ID, Integer.parseInt(pageid));
                BasicDBObject key = new BasicDBObject();
                key.put(JSONKeys.PAGE_SEQUENCE, 1);
                DBObject obj = coll.findOne(ref, key);
                if (obj != null) {
                    Object pobj = obj.get(JSONKeys.PAGE_SEQUENCE);
                    int pageNo = ((Number) pobj).intValue();
                    DBCollection coll2 = db.getCollection(Database.DOCUMENTS);
                    BasicDBObject ref2 = new BasicDBObject();
                    ref2.put(JSONKeys.IA_IDENTIFIER, docid);
                    ref2.put(JSONKeys.PAGE_SEQUENCE, pageNo);
                    BasicDBObject key2 = new BasicDBObject();
                    key2.put(JSONKeys.CONTENT, 1);
                    Object obj2 = coll2.findOne(ref2, key2);
                    if (obj2 != null)
                        return (String) ((DBObject) obj2).get(JSONKeys.CONTENT);
                    else
                        throw new Exception("could not find content for docid=" + docid + ", pageid=" + pageid);
                } else
                    throw new Exception("could not find docid=" + docid + ", pageid=" + pageid);
            } else
                throw new Exception("Missing docid or pageid");
        } catch (Exception e) {
            throw new DbException(e);
        }
    }

    /**
     * Get the set of distinct keys for a collection
     * @param collection the collection name
     * @param field the field name for distinct values
     * @return and array of field values
     * @throws Exception 
     */
    @Override
    public String[] getDistinctKeys(String collection, String field) throws DbException {
        try {
            connect();
            DBCollection coll = db.getCollection(Database.PAGES);
            List keys = coll.distinct(field);
            String[] list = new String[keys.size()];
            keys.toArray(list);
            return list;
        } catch (Exception e) {
            throw new DbException(e);
        }
    }

    /**
     * Fetch a resource from the server via a given field value
     * @param collName the collection or database name
     * @param value the value of the field
     * @param field the field name
     * @return the response as a string or null if not found
     */
    @Override
    public String getFromDbByField(String collName, String value, String field) throws DbException {
        try {
            connect();
            DBCollection coll = getCollectionFromName(collName);
            DBObject query;
            if (field.equals(JSONKeys._ID)) {
                ObjectId objId = new ObjectId(value);
                query = new BasicDBObject(field, objId);
            } else
                query = new BasicDBObject(field, value);
            DBObject obj = coll.findOne(query);
            if (obj != null)
                return obj.toString();
            else
                return null;
        } catch (Exception e) {
            throw new DbException(e);
        }
    }
}