de.knurt.fam.core.persistence.dao.couchdb.FamCouchDBDao.java Source code

Java tutorial

Introduction

Here is the source code for de.knurt.fam.core.persistence.dao.couchdb.FamCouchDBDao.java

Source

/*
 * Copyright 2009-2012 by KNURT Systeme (http://www.knurt.de)
 *
 * Licensed under the Creative Commons License Attribution-NonCommercial-ShareAlike 3.0 Unported;
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://creativecommons.org/licenses/by-nc-sa/3.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 de.knurt.fam.core.persistence.dao.couchdb;

import java.util.Date;
import java.util.Observable;

import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.jcouchdb.db.Database;
import org.jcouchdb.db.Response;
import org.jcouchdb.db.ServerImpl;
import org.svenson.JSONParseException;
import org.svenson.JSONParser;

import de.knurt.fam.connector.FamConnector;
import de.knurt.fam.core.aspects.logging.FamLog;
import de.knurt.fam.core.model.persist.User;
import de.knurt.fam.core.model.persist.document.FamBaseDocument;
import de.knurt.fam.core.persistence.dao.FamDocumentDao;
import de.knurt.heinzelmann.util.query.QueryString;

/**
 * dao for couchdb
 * 
 * @author Daniel Oltmanns <info@knurt.de>
 * @since 1.20 (08/13/2010)
 */
public class FamCouchDBDao extends Observable implements FamDocumentDao {

    // private Database database;

    /** one and only instance of CouchDBDao */
    private volatile static FamCouchDBDao me;

    /** construct CouchDBDao */
    private FamCouchDBDao() {
    }

    /**
     * return the one and only instance of CouchDBDao
     * 
     * @return the one and only instance of CouchDBDao
     */
    public static FamCouchDBDao getInstance() {
        if (me == null) { // no instance so far
            synchronized (FamCouchDBDao.class) {
                if (me == null) { // still no instance so far
                    me = new FamCouchDBDao(); // the one and only
                }
            }
        }
        return me;
    }

    @Override
    public synchronized boolean createDocument(FamBaseDocument document) {
        boolean result = true;
        document.setCreated(new Date().getTime());
        try {
            database().createDocument(document);
            document.setHasBeenCreated();
            setChanged();
            notifyObservers(document);
        } catch (Exception e) {
            FamLog.exception(e, 201203071217l);
            result = false;
        }
        return result;
    }

    public JSONParser getJSONParserUsed() {
        return database().getJsonConfig().getJsonParser();
    }

    /**
     * put the given body without any validation into the database under a
     * random uuid.
     * 
     * @param body
     * @return the response for the put request
     */
    public Response put(String body) {
        return database().getServer()
                .put("/" + FamConnector.getGlobalProperty("couchdb_dbname") + "/" + this.getUuid(), body);
    }

    public byte[] getAttachment(String docId, String attachmentId) {
        return database().getAttachment(docId, attachmentId);
    }

    private String getUuid() {
        return database().getServer().getUUIDs(1).get(0);
    }

    public String getContentAsString(String uri) {
        Response response = response(uri);
        String result = "";
        try {
            result = response.getContentAsString().trim();
        } finally {
            if (response != null)
                response.destroy();
        }
        return result;
    }

    public <R> R getContentAsBean(String uri, QueryString queryString, Class<R> cls) throws JSONParseException {
        Response response = response(uri + "?" + queryString.getAsQueryParams(false));
        R result = null;
        try {
            result = response.getContentAsBean(cls);
        } finally {
            if (response != null)
                response.destroy();
        }
        return result;
    }

    public String getContentAsString(String uri, QueryString queryString) {
        return this.getContentAsString(uri + "?" + queryString.getAsQueryParams(false));
    }

    /**
     * return one document as the result class given
     * 
     * @param <R>
     *            class document converted to
     * @param docId
     *            search for
     * @param resultClass
     *            document converted to
     * @return on document as the result class object or null
     * @see Database#getDocument(Class, String);
     */
    public <R> R getOne(String docId, Class<R> resultClass) {
        return database().getDocument(resultClass, docId);
    }

    /**
     * alias for {@link #getOne(String, Class)}
     */
    public <R> R getContentAsBean(String docId, Class<R> resultClass) {
        return this.getOne(docId, resultClass);
    }

    /** {@inheritDoc} */
    @Override
    public synchronized boolean updateDocument(FamBaseDocument documentToUpdate, FamBaseDocument existingDocument) {
        // update doc
        documentToUpdate.setId(existingDocument.getId());
        documentToUpdate.setRevision(existingDocument.getRevision());
        return this.updateDocument(documentToUpdate);
    }

    /** {@inheritDoc} */
    @Override
    public synchronized boolean updateDocument(FamBaseDocument document) {
        boolean result = true;
        document.setCreated(new Date().getTime());
        try {
            database().updateDocument(document);
        } catch (Exception e) {
            FamLog.exception(e, 201203071218l);
            result = false;
        }
        if (result) {
            FamLog.info("update document: " + document.getId(), 201203080925l);
        }
        return result;
    }

    protected static Database database() {
        String host = FamConnector.getGlobalProperty("couchdb_ip");
        int port = Integer.parseInt(FamConnector.getGlobalProperty("couchdb_port"));
        String name = FamConnector.getGlobalProperty("couchdb_dbname");
        return new Database(new ServerImpl(host, port), name);
    }

    protected static Database admindatabase(User auth) {
        if (auth.isAdmin()) {
            String username = FamConnector.getGlobalProperty("couchdb_username");
            String userpass = FamConnector.getGlobalProperty("couchdb_userpass");
            String ip = FamConnector.getGlobalProperty("couchdb_ip");
            String host = String.format("%s:%s@%s", username, userpass, ip);
            int port = Integer.parseInt(FamConnector.getGlobalProperty("couchdb_port"));
            String name = FamConnector.getGlobalProperty("couchdb_dbname");
            ServerImpl s = new ServerImpl(host, port);
            AuthScope authScope = new AuthScope(host, port, "_admin");
            Credentials credentials = new UsernamePasswordCredentials(username, userpass);
            s.setCredentials(authScope, credentials);
            return new Database(s, name);
        } else {
            FamLog.error("this must be called by an admin", 201205041254l);
            return null;
        }

    }

    public String databaseName() {
        return database().getName();
    }

    public long documentCount() {
        return database().getStatus().getDocumentCount();
    }

    /**
     * return the response object for the given uri. DO NOT FORGET TO DESTROY
     * THE RESPONSE!!!
     */
    protected static Response response(String uri) {
        return database().getServer().get("/" + FamConnector.getGlobalProperty("couchdb_dbname") + "/" + uri);
    }

}