mx.org.cedn.avisosconagua.mongo.MongoInterface.java Source code

Java tutorial

Introduction

Here is the source code for mx.org.cedn.avisosconagua.mongo.MongoInterface.java

Source

/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Mxico Abierto
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * For more information visit https://github.com/mxabierto/avisos.
*/
package mx.org.cedn.avisosconagua.mongo;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.gridfs.GridFS;
import java.net.UnknownHostException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Date;
import java.util.Deque;
import java.util.HashMap;
import java.util.Set;
import mx.org.cedn.avisosconagua.util.Utils;

/**
 * Class to manage communication with MongoDB to persist and retrieve advice information.
 * @author serch
 */
public class MongoInterface {

    private final MongoClient mongoClient;
    private final MongoClientURI mongoClientURI;
    private final DB mongoDB;
    private static MongoInterface instance = null;
    private static final String CAPTURA_COL = "AdviceDataForms";
    public static final String INTERNAL_FORM_ID = "internalId";
    private static final String IMAGES_COL = "AdviceDataImages";
    private static final String IMAGES_FILES_COL = "AdviceDataImages.files";
    public static final String ADVICE_TYPE = "adviceType";
    public static final String UPDATE_TS = "updatedAt";
    private static final String PUBLISHED_COL = "GeneratedAdvices";
    private static final String GENERATED_COL = "GeneratedFiles";
    private static final String GENERATED_FILES_COL = "GeneratedFiles.files";
    private static final String GENERATED_TITLE = "generatedTitle";
    //public static final String LOCAL_MONGO_URL = "mongodb://heroku:DnZ2AYC8nmtWR3p1Dccs4N9WSLUIrQQTrjcvfLrDlLo8V8yD4Pz6yV5mR5HPuTdEDx2b34v2W0qfufBHUBZlQg@oceanic.mongohq.com:10080/app23903821";
    //public static final String LOCAL_MONGO_URL = "mongodb://conagua:C0n4gu4@192.168.204.147/conagua";
    public static final String LOCAL_MONGO_URL = "mongodb://localhost:25000/conagua";

    /**
     * Gets an instance of a MongoInterface.
     * @return current MongoInterface object
     */
    public static synchronized MongoInterface getInstance() {
        if (null == instance) {
            try {
                instance = new MongoInterface();
            } catch (UnknownHostException uhe) {
                System.out.println("Can't connect to MongoDB" + uhe.getLocalizedMessage());
            }
        }
        return instance;
    }

    /**
     * Constructor. Creates a new instance of a MongoInterface object.
     * @throws UnknownHostException 
     */
    private MongoInterface() throws UnknownHostException {
        boolean running = true;
        for (String key : System.getenv().keySet()) {
            if (key.startsWith("JAVA_MAIN")) {
                if (System.getenv(key).startsWith("org.apache.maven")) {
                    running = false;
                }
            }
        }
        if (null != System.getenv("MONGOHQ_URL") && running) {
            mongoClientURI = new MongoClientURI(System.getenv("MONGOHQ_URL"));
        } else {
            //mongodb://conagua:C0n4gu4@192.168.204.147/conagua
            //MONGOHQ_URL=mongodb://heroku:DnZ2AYC8nmtWR3p1Dccs4N9WSLUIrQQTrjcvfLrDlLo8V8yD4Pz6yV5mR5HPuTdEDx2b34v2W0qfufBHUBZlQg@oceanic.mongohq.com:10080/app23903821
            //mongoClientURI = new MongoClientURI("mongodb://heroku:DnZ2AYC8nmtWR3p1Dccs4N9WSLUIrQQTrjcvfLrDlLo8V8yD4Pz6yV5mR5HPuTdEDx2b34v2W0qfufBHUBZlQg@oceanic.mongohq.com:10080/app23903821");
            //mongoClientURI = new MongoClientURI("mongodb://conagua:C0n4gu4@192.168.204.147/conagua");
            mongoClientURI = new MongoClientURI(LOCAL_MONGO_URL);
        }
        mongoClient = new MongoClient(mongoClientURI);
        mongoDB = mongoClient.getDB(mongoClientURI.getDatabase());
        if (null != mongoClientURI.getUsername()) {
            mongoDB.authenticate(mongoClientURI.getUsername(), mongoClientURI.getPassword());
        }
    }

    /**
     * Gets an array of the collection names in the current Mongo database.
     * @return array of the collection names
     */
    public String[] getCollections() {
        Set<String> names = mongoDB.getCollectionNames();
        return names.toArray(new String[0]);
    }

    /**
     * Creates a new advice object 
     * @param currentId ID for the advice object
     * @param tipo type of the advice. One of pacdp|atldp|pacht|atlht.
     * @return BasicDBObject for the advice
     */
    public BasicDBObject createNewAdvice(String currentId, String tipo) {
        //System.out.println("new advice:" + currentId);
        BasicDBObject newdata = new BasicDBObject(INTERNAL_FORM_ID, currentId).append(ADVICE_TYPE, tipo)
                .append(UPDATE_TS, new Date());
        mongoDB.getCollection(CAPTURA_COL).insert(newdata);
        return newdata;
    }

    /**
     * Gets the BasicDBObject with the advice information.
     * @param currentId ID for the current advice
     * @return BasicDBObject with the advice information
     */
    public BasicDBObject getAdvice(String currentId) {
        //System.out.println("getAdvice: " + currentId);
        BasicDBObject newdata = new BasicDBObject(INTERNAL_FORM_ID, currentId);
        return (BasicDBObject) mongoDB.getCollection(CAPTURA_COL).findOne(newdata);
    }

    /**
     * Stores a set of key-value pairs in a BasicDBObject.
     * @param currentId ID for the current advice
     * @param formId form ID
     * @param parametros key-value pairs to store
     */
    public void savePlainData(String currentId, String formId, HashMap<String, String> parametros) {
        //System.out.println("saveAdvice: " + currentId + " screen:" + formId);
        BasicDBObject actual = getAdvice(currentId);
        BasicDBObject interno = new BasicDBObject(parametros);
        actual.append(formId, interno);
        actual.append(UPDATE_TS, new Date());
        mongoDB.getCollection(CAPTURA_COL).update(getAdvice(currentId), actual);
    }

    /**
     * Gets a GridFS object to retrieve an image from.
     * @return GridFS object
     */
    public GridFS getImagesFS() {
        return new GridFS(mongoDB, IMAGES_COL);
    }

    /**
     * Gets a GridFS object to store an image.
     * @return GridFS object
     */
    public GridFS getGeneratedFS() {
        return new GridFS(mongoDB, GENERATED_COL);
    }

    /**
     * Gets a GridFS object for the provided type of operation.
     * @param type type of operation (get or store the image)
     * @return GridFS object
     */
    public GridFS getGridFS(String type) {
        String collection = GENERATED_COL;
        if ("getImage".equals(type)) {
            collection = IMAGES_COL;
        }
        return new GridFS(mongoDB, collection);
    }

    /**
     * Gets a list of the last 10 generated advices from the Mongo database.
     * @return list conitaining the last 10 generated advices
     */
    public ArrayList<String> getPublisedAdvicesList() {
        return getPublisedAdvicesList(null);
    }

    /**
     * Gets the count of all generated advices in the Mongo database.
     * @return Count of generated advices.
     */
    public long countPublishedAdvices() {
        DBCollection col = mongoDB.getCollection(GENERATED_COL);
        return col.count();
    }

    /**
     * Gets a list with the last 10 generated (complete) advices in the Mongo database.
     * @param type type of the advice. One of pacdp|atldp|pacht|atlht
     * @return list with the last 10 generated (complete) advices
     */
    public ArrayList<String> getPublisedAdvicesList(String type) {
        DBCollection col = mongoDB.getCollection(GENERATED_COL);
        ArrayList<String> ret = null;
        DBCursor cursor = null;
        if (null == type) {
            cursor = col.find().sort(new BasicDBObject("issueDate", -1)).limit(10);
        } else {
            cursor = col.find(new BasicDBObject("adviceType", type)).sort(new BasicDBObject("issueDate", -1))
                    .limit(10);
        }
        if (null != cursor) {
            ret = new ArrayList<>();
            for (DBObject object : cursor) {
                String advice = object.get(INTERNAL_FORM_ID) + "|" + object.get(GENERATED_TITLE);
                ret.add(advice);
            }
        }
        return ret;
    }

    /**
     * Gets a list of the files stored in an advice.
     * @param adviceID ID for the current advice
     * @return list of the files stored in an advice
     */
    ArrayList<String> listFilesFromAdvice(String adviceID) {
        ArrayList<String> ret = new ArrayList<>();
        DBCollection col = mongoDB.getCollection(IMAGES_FILES_COL);
        DBCursor cursor = col.find(new BasicDBObject("filename", new BasicDBObject("$regex", adviceID)));
        if (null != cursor) {
            ret = new ArrayList<>();
            for (DBObject obj : cursor) {
                ret.add((String) obj.get("filename"));

            }
        }
        return ret;
    }

    /**
     * Flags te advice as succesfully generated (completed)
     * @param adviceID ID for the current advice
     * @param previous ID for the previous advice (if any)
     * @param title title of the advice
     * @param type type of the advice. One of pacdp|atldp|pacht|atlht.
     * @param date issue date of the advice
     */
    public void setGenerated(String adviceID, String previous, String title, String type, String date) {
        DBCollection col = mongoDB.getCollection(GENERATED_COL);
        String isodate = Utils.getOrderDate(date);
        BasicDBObject nuevo = new BasicDBObject(INTERNAL_FORM_ID, adviceID).append(GENERATED_TITLE, title)
                .append("previousIssue", previous).append("generationTime", Utils.sdf.format(new Date()))
                .append("adviceType", type).append("issueDate", isodate);
        BasicDBObject query = new BasicDBObject(INTERNAL_FORM_ID, adviceID);
        BasicDBObject old = (BasicDBObject) col.findOne(query);
        if (null == old) {
            col.insert(nuevo);
        } else {
            col.update(old, nuevo);
        }
    }

    /**
     * Gets the chain of tracking advices (from newest to oldest)
     * @param currentId ID for the current advice
     * @return list of previous advices starting from the current advice
     */
    public ArrayList<Statistics> getAdviceChain(String currentId) {
        String searchId = currentId;
        DBCollection col = mongoDB.getCollection(CAPTURA_COL);
        Deque<String> deque = new ArrayDeque<>();
        while (searchId != null && !searchId.trim().equals("")) {
            deque.push(searchId);
            BasicDBObject current = (BasicDBObject) col.findOne(new BasicDBObject(INTERNAL_FORM_ID, searchId));
            if (null != current) {
                current = (BasicDBObject) current.get("precapture");
            }
            if (null != current) {
                searchId = current.getString("previousIssue");
            } else {
                searchId = null;
            }
        }
        ArrayList<Statistics> ret = new ArrayList<>();
        while (!deque.isEmpty()) {
            String curr = deque.pop();
            BasicDBObject lobj = (BasicDBObject) col.findOne(new BasicDBObject(INTERNAL_FORM_ID, curr));
            if (null != lobj) {
                ret.add(new Statistics(lobj));
            }
        }
        return ret;
    }

    /**
     * Gets a list of the last 10 published (complete) advices.
     * @return list of the published (complete) advices 
     */
    public ArrayList<String> listPublishedAdvices() {
        return listPublishedAdvices(10);
    }

    /**
     * Gets a paged list of generated advices in the Mongo database.
     * @param pNumber Page number to retrieve.
     * @param nPerPage Items per page to retrieve.
     * @return List of the nPerPage published (complete) advices in the page pNumber
     */
    public ArrayList<String> listPagedPublishedAdvices(int pNumber, int nPerPage) {
        DBCollection col = mongoDB.getCollection(GENERATED_COL);
        ArrayList<String> ret = null;
        DBCursor cursor;

        cursor = col.find().skip(pNumber > 0 ? ((pNumber - 1) * nPerPage) : 0)
                .sort(new BasicDBObject("issueDate", -1)).limit(nPerPage);
        if (null != cursor) {
            ret = new ArrayList<>();
            for (DBObject obj : cursor) {
                ret.add((String) obj.get(INTERNAL_FORM_ID));
            }
        }
        return ret;
    }

    /**
     * Gets a list of the n last published advices.
     * @param limit number of advices to get
     * @return list of the n last published advices
     */
    public ArrayList<String> listPublishedAdvices(int limit) {
        DBCollection col = mongoDB.getCollection(GENERATED_COL);
        ArrayList<String> ret = null;
        DBCursor cursor;
        if (limit > 0) {
            cursor = col.find().sort(new BasicDBObject("issueDate", -1)).limit(limit);
        } else {
            cursor = col.find().sort(new BasicDBObject("issueDate", -1));
        }
        if (null != cursor) {
            ret = new ArrayList<>();
            for (DBObject obj : cursor) {
                ret.add((String) obj.get(INTERNAL_FORM_ID));
            }
        }
        return ret;
    }

    /**
     * Gets a list of the last n published hurricane advices.
     * @param limit number of advices to get
     * @return list of the last n published hurricane advices
     */
    public ArrayList<String> listPublishedHurricanes(int limit) {
        DBCollection col = mongoDB.getCollection(GENERATED_COL);
        ArrayList<String> ret = null;
        DBCursor cursor;
        if (limit > 0) {
            cursor = col.find().sort(
                    new BasicDBObject("issueDate", -1).append("adviceType", new BasicDBObject("$regex", "ht$")))
                    .limit(limit);
        } else {
            cursor = col.find().sort(
                    new BasicDBObject("issueDate", -1).append("adviceType", new BasicDBObject("$regex", "ht$")));
        }
        if (null != cursor) {
            ret = new ArrayList<>();
            for (DBObject obj : cursor) {
                ret.add((String) obj.get(INTERNAL_FORM_ID));
            }
        }
        return ret;
    }

    /**
     * Gets the DBObject for the given advice ID.
     * @param adviceId ID for the current advice
     * @return DBObject for the given advice ID
     */
    public DBObject getPublishedAdvice(String adviceId) {
        return mongoDB.getCollection(GENERATED_COL).findOne(new BasicDBObject(INTERNAL_FORM_ID, adviceId));
    }

    /**
     * Makes a deep clone of an existing advice object.
     * @param originAdviceID source object
     * @param currentAdviceId ID for the cloned advice object
     */
    public void copyFromAdvice(String originAdviceID, String currentAdviceId) {
        BasicDBObject origen = getAdvice(originAdviceID);
        BasicDBObject destino = getAdvice(currentAdviceId);
        destino.putAll(origen.toMap());
        destino.put(INTERNAL_FORM_ID, currentAdviceId);
        origen = getAdvice(currentAdviceId);
        mongoDB.getCollection(CAPTURA_COL).update(origen, destino);
    }

    /**
     * Gets the prefix of the HTML file name for the advice, depending on its type.
     * @param adviceID ID for the current advice
     * @return prefix for the file name. One of pacifico|atlantico.
     */
    public String getHTMLFileNamePrefix(String adviceID) {
        BasicDBObject newdata = new BasicDBObject(INTERNAL_FORM_ID, adviceID);
        newdata = (BasicDBObject) mongoDB.getCollection(CAPTURA_COL).findOne(newdata);
        String type = newdata.getString("adviceType");
        String ret = null;
        if (type.indexOf("pac") > -1) {
            ret = "pacifico";
        }
        if (type.indexOf("atl") > -1) {
            ret = "atlantico";
        }
        return ret;
    }
}