org.openmhealth.reference.data.mongodb.MongoUserBin.java Source code

Java tutorial

Introduction

Here is the source code for org.openmhealth.reference.data.mongodb.MongoUserBin.java

Source

/*******************************************************************************
 * Copyright 2013 Open mHealth
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package org.openmhealth.reference.data.mongodb;

import org.mongojack.DBCursor;
import org.mongojack.DBQuery;
import org.mongojack.DBQuery.Query;
import org.mongojack.JacksonDBCollection;
import org.mongojack.internal.MongoJackModule;
import org.openmhealth.reference.data.UserBin;
import org.openmhealth.reference.domain.Schema;
import org.openmhealth.reference.domain.User;
import org.openmhealth.reference.domain.mongodb.MongoUser;
import org.openmhealth.reference.exception.OmhException;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.MongoException;
import com.mongodb.QueryBuilder;

/**
 * <p>
 * The MongoDB implementation of the interface to the database-backed
 * collection of users.
 * </p>
 *
 * @author John Jenkins
 */
public class MongoUserBin extends UserBin {
    /**
     * The object mapper that should be used to parse {@link Schema}s.
     */
    private static final ObjectMapper JSON_MAPPER;
    static {
        // Create the object mapper.
        ObjectMapper mapper = new ObjectMapper();

        // Create the FilterProvider.
        SimpleFilterProvider filterProvider = new SimpleFilterProvider();
        filterProvider.setFailOnUnknownId(false);
        mapper.setFilters(filterProvider);

        // Finally, we must configure the mapper to work with the MongoJack
        // configuration.
        JSON_MAPPER = MongoJackModule.configure(mapper);
    }

    /**
     * Default constructor that creates any tables and indexes if necessary.
     */
    protected MongoUserBin() {
        // Get the collection to add indexes to.
        DBCollection collection = MongoDao.getInstance().getDb().getCollection(DB_NAME);

        // Ensure that there is an index on the username.
        collection.ensureIndex(new BasicDBObject(User.JSON_KEY_USERNAME, 1),
                DB_NAME + "_" + User.JSON_KEY_USERNAME + "_unique", true);

        // Ensure that there is an index on the username.
        collection.ensureIndex(new BasicDBObject(User.JSON_KEY_REGISTRATION_KEY, 1),
                DB_NAME + "_" + User.JSON_KEY_REGISTRATION_KEY, false);
    }

    /*
     * (non-Javadoc)
     * @see org.openmhealth.reference.data.UserBin#createUser(org.openmhealth.reference.domain.User)
     */
    @Override
    public void createUser(final User user) throws OmhException {
        // Validate the input.
        if (user == null) {
            throw new OmhException("The user is null.");
        }

        // Get the user collection.
        JacksonDBCollection<User, Object> collection = JacksonDBCollection
                .wrap(MongoDao.getInstance().getDb().getCollection(DB_NAME), User.class, Object.class, JSON_MAPPER);

        // Save the user.
        try {
            collection.insert(user);
        } catch (MongoException.DuplicateKey e) {
            throw new OmhException("A user with that username already exists.", e);
        }
    }

    /*
     * (non-Javadoc)
     * @see org.openmhealth.reference.data.UserBin#getUser(java.lang.String)
     */
    @Override
    public User getUser(final String username) throws OmhException {
        // Validate the parameter.
        if (username == null) {
            throw new OmhException("The username is null.");
        }

        // Get the authentication token collection.
        JacksonDBCollection<MongoUser, Object> collection = JacksonDBCollection.wrap(
                MongoDao.getInstance().getDb().getCollection(DB_NAME), MongoUser.class, Object.class, JSON_MAPPER);

        // Build the query.
        QueryBuilder queryBuilder = QueryBuilder.start();

        // Add the authentication token to the query
        queryBuilder.and(MongoUser.JSON_KEY_USERNAME).is(username);

        // Execute query.
        DBCursor<MongoUser> result = collection.find(queryBuilder.get());

        // If multiple authentication tokens were returned, that is a violation
        // of the system.
        if (result.count() > 1) {
            throw new OmhException("Multiple users exist with the same username: " + username);
        }

        // If no tokens were returned, then return null.
        if (result.count() == 0) {
            return null;
        } else {
            return result.next();
        }
    }

    /*
     * (non-Javadoc)
     * @see org.openmhealth.reference.data.UserBin#getUserFormRegistration(java.lang.String)
     */
    @Override
    public User getUserFromRegistrationId(final String registrationId) throws OmhException {

        // Validate the parameter.
        if (registrationId == null) {
            throw new OmhException("The registration ID is null.");
        }

        // Get the authentication token collection.
        JacksonDBCollection<MongoUser, Object> collection = JacksonDBCollection.wrap(
                MongoDao.getInstance().getDb().getCollection(DB_NAME), MongoUser.class, Object.class, JSON_MAPPER);

        // Build the query.
        QueryBuilder queryBuilder = QueryBuilder.start();

        // Add the authentication token to the query
        queryBuilder.and(MongoUser.JSON_KEY_REGISTRATION_KEY).is(registrationId);

        // Execute query.
        DBCursor<MongoUser> result = collection.find(queryBuilder.get());

        // If multiple authentication tokens were returned, that is a violation
        // of the system.
        if (result.count() > 1) {
            throw new OmhException("Multiple users exist with the same registration ID: " + registrationId);
        }

        // If no tokens were returned, then return null.
        if (result.count() == 0) {
            return null;
        } else {
            return result.next();
        }
    }

    /*
     * (non-Javadoc)
     * @see org.openmhealth.reference.data.UserBin#updateUser(org.openmhealth.reference.domain.User)
     */
    @Override
    public void updateUser(final User user) throws OmhException {
        // Validate the input.
        if (user == null) {
            throw new OmhException("The user is null.");
        }

        // Get the user collection.
        JacksonDBCollection<User, Object> collection = JacksonDBCollection
                .wrap(MongoDao.getInstance().getDb().getCollection(DB_NAME), User.class, Object.class, JSON_MAPPER);

        // Ensure that we are only updating the user with the same user-name.
        Query query = DBQuery.is(User.JSON_KEY_USERNAME, user.getUsername());

        // Save the user.
        try {
            collection.update(query, user);
        } catch (MongoException e) {
            throw new OmhException("An internal error occurred.", e);
        }
    }
}