com.dhamacher.addressbook.DBController.java Source code

Java tutorial

Introduction

Here is the source code for com.dhamacher.addressbook.DBController.java

Source

/*
 * DBController.java - Controller for the MongoDB instance.
 * Copyright (C) 2013 Daniel Hamacher
 * 
 * This program 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 3 of the License, or (at your option) any later 
 * version.
 * 
 * This program 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 
 * this program. If not, see {http://www.gnu.org/licenses/}.
 */
package com.dhamacher.addressbook;

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.MongoException;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;

/**
 * This class implements methods for connecting to the mongoDB instance and
 * executes queries if needed. The functionality includes inserting, modifying,
 * and dropping the current contact table.
 * 
 * @author Daniel Hamacher
 * @version 1.0
 */
public class DBController {

    /* Used to connect to the database */
    private static MongoClient mongoClient;
    /* The database object */
    private DB database;
    /* The collection (Table) of the database */
    private DBCollection collection;
    /* The name of the database */
    private String databaseName;
    /* Flag to check if the connection is closed */
    private static boolean closed;
    /* The GUI instance to access the components */
    private Main main;

    /**
     * A private constructor that initializes the private fields of this class
     *
     * @param gui The user view
     * @param db The database object
     * @param dbn The database or collection name
     */
    private DBController(Main gui, DB db, String dbn) {
        main = gui;
        database = db;
        databaseName = dbn;
        collection = db.getCollection("addresses");
        closed = false;
    }

    /**
     * A factory method to open the database connection. Returns a DBController
     * object so the user can execute queries against the connected collection.
     *
     * @param gui The user view
     * @param dbname The database name
     * @return
     */
    protected static DBController connect(Main gui, String dbname) {
        try {
            /* Connect to the mongoDB server using default values */
            mongoClient = new MongoClient("localhost", 27017);

            /* Thrown if the database host is unknown */
        } catch (UnknownHostException ex) {
            Logger.getLogger(DBController.class.getName()).log(Level.SEVERE, null, ex);
            JOptionPane.showMessageDialog(null, "Error connecting to Database", "Database Connection Error",
                    JOptionPane.ERROR_MESSAGE);
        } catch (MongoException e) {
            JOptionPane.showMessageDialog(null, "Error connecting to Database", "Database Connection Error",
                    JOptionPane.ERROR_MESSAGE);
        }
        /* Return a new controller instance */
        return new DBController(gui, mongoClient.getDB(dbname), dbname);
    }

    /**
     * Creates a new Contact instance.
     *
     * @param firstName The first name of the contact
     * @param lastName The last name of the contact
     * @param homeNumber The home phone number of the contact
     * @param cellNumber The cell phone number of the contact
     * @param email The email address of the contact
     * @param relationship The relationship to this contact
     * @param notes The notes to further describe this contact
     * @return A new Contact instance
     */
    protected Contact createContact(String firstName, String lastName, String homeNumber, String cellNumber,
            String email, String relationship, String notes) {

        /* Build a new contact */
        Contact contact = new Contact.Builder(firstName, lastName).homePhone(homeNumber).cellPhone(cellNumber)
                .email(email).relationship(relationship).notes(notes).build();

        return contact;
    }

    /**
     * This methods provides the data that is then published in the JList
     * component of the user view [Main.class]
     *
     * @return An object array for the JList component in the user view
     */
    protected Object[] getContacts() {
        if (collection.count() == 0) {
            Object[] data = { "" };
            return data;
        } else {
            /* Use the database cursor to iterate trough the collection */
            DBCursor cursor = collection.find();

            /* New array based on the size of the collection */
            Object[] data = new Object[(int) collection.count()];
            int i = 0;
            while (cursor.hasNext()) {
                DBObject document = cursor.next();
                data[i] = document.get("first_name") + " " + document.get("last_name");
                i++;
            }
            cursor.close();
            return data;
        }
    }

    /**
     * This methods handles updates and insertion of documents in the collection
     */
    protected void insertUpdateQueryHandler() {
        /* Display message if fisrt name and last name is empty */
        if (main.firstName.getText().equals("") || main.lastName.getText().equals("")) {
            JOptionPane.showMessageDialog(main,
                    "First name and last name are " + "required\nto save new contact or update an existing one",
                    "INFO", JOptionPane.INFORMATION_MESSAGE);
            /* 
             * Else if no contact is selected in the list, insert new document
             * into the collection.
             */
        } else if (main.addressList.getSelectedIndex() == -1 || main.addressList.getSelectedValue() == "") {
            insert(createContact(main.firstName.getText().replace(" ", ""),
                    main.lastName.getText().replace(" ", ""), main.homePhone.getText().trim(),
                    main.cellPhone.getText().trim(), main.email.getText().trim(),
                    (String) main.relationship.getSelectedItem(), main.notes.getText()));
            main.addressList.setListData(getContacts());
            int index = main.addressList.getLastVisibleIndex();
            main.addressList.setSelectedIndex(index);
            main.addressList.ensureIndexIsVisible(index);
            /*
             * If a contact is selected in the contact list, get the selected 
             * contact and update the information in the collection for this 
             * contact.
             */
        } else {
            /* Get the selected Contact index */
            int index = main.addressList.getSelectedIndex();

            /* Confirm if the user wants to update the contact */
            int i = JOptionPane.showConfirmDialog(main, "Sure you want to update the " + "current Contact?",
                    "ATTENTION", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
            /* If the user confirms update, wrte changes to the collection */
            if (i == JOptionPane.YES_OPTION) {
                Contact updatedContact = createContact(main.firstName.getText().replace(" ", ""),
                        main.lastName.getText().replace(" ", ""), main.homePhone.getText().trim(),
                        main.cellPhone.getText().trim(), main.email.getText().trim(),
                        (String) main.relationship.getSelectedItem(), main.notes.getText());
                /* Update contact in collection */
                updateContact(main.oldContact, updatedContact);

                /* Refresh the contact list in the user view */
                main.addressList.setListData(getContacts());
                main.addressList.setSelectedIndex(index);
                main.addressList.ensureIndexIsVisible(index);
                fillContactPanel(updatedContact);
                /* 
                 * The user decided not to update the contact, so fill the 
                 * contact panel with previous values.
                 */
            } else {
                fillContactPanel(main.oldContact);
            }
        }
    }

    /**
     * Insert the contact attributes into the panel of the user view.
     * @param contact Contact instance 
     */
    protected void fillContactPanel(Contact contact) {
        main.firstName.setText(contact.getFirstName());
        main.lastName.setText(contact.getLastName());
        main.homePhone.setText(contact.getHomeNumber());
        main.cellPhone.setText(contact.getCellNumber());
        main.email.setText(contact.getEmail());
        main.relationship.setSelectedItem(contact.getRelationship());
        main.notes.setText(contact.getNotes());
    }

    /**
     * Retrieve the Contact instance form the database.
     * @param c The contact to look for.
     * @return BasicDBObject from the mongoDB
     */
    private DBObject getDocument(Contact c) {
        BasicDBObject document = new BasicDBObject();
        document.put("first_name", c.getFirstName());
        document.put("last_name", c.getLastName());
        document.put("home_phone", c.getHomeNumber());
        document.put("cell_phone", c.getCellNumber());
        document.put("email", c.getEmail());
        document.put("relationship", c.getRelationship());
        document.put("notes", c.getNotes());
        return document;
    }

    /**
     * Insert the Contact as document into the mongoDB
     * @param contact The contact instance to insert into the collection
     */
    private void insert(Contact contact) {
        DBObject document = getDocument(contact);
        collection.insert(document);
    }

    /**
     * This methods is used for contact lookup in the database. The parameter 
     * comes from the selected item from the JList component
     * @param fullname The full name of the contact.
     * @return Contact instance
     */
    protected Contact getContact(String fullname) {
        String[] name = fullname.split(" ");
        BasicDBObject query = new BasicDBObject();
        query.put("first_name", name[0]);
        query.put("last_name", name[1]);
        DBObject document = collection.findOne(query);
        Contact contact = new Contact.Builder((String) document.get("first_name"),
                (String) document.get("last_name")).homePhone((String) document.get("home_phone"))
                        .cellPhone((String) document.get("cell_phone")).email((String) document.get("email"))
                        .relationship((String) document.get("relationship")).notes((String) document.get("notes"))
                        .build();
        return contact;
    }

    /**
     * Find the contact and update it with the updated contact instance
     * @param oldContact The unchanged contact instance
     * @param updatedContact The updated contact instance
     */
    private void updateContact(Contact oldContact, Contact updatedContact) {
        collection.update(getDocument(oldContact), getDocument(updatedContact), false, false);
    }

    /**
     * This method will remove a contact from the collection.
     * @param contact The contact that will be removed 
     */
    protected void deleteContact(Contact contact) {
        collection.remove(getDocument(contact));
    }

    /**
     * Delete the collection
     */
    protected void dropAddressBook() {
        if (closed == true) {
            JOptionPane.showMessageDialog(null, "Invalid Operation. Database " + "connection closed.", "Error",
                    JOptionPane.ERROR_MESSAGE);
        } else {
            mongoClient.dropDatabase(databaseName);
        }
    }

    /**
    * Close the database connection
    */
    protected void close() {
        mongoClient.close();
        closed = true;
    }
}