Package org.apache.abdera.protocol.server.adapters.couchdb

Source Code of org.apache.abdera.protocol.server.adapters.couchdb.CouchDbAdapter$DocumentComparator

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  The ASF licenses this file to You
* 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.  For additional information regarding
* copyright in this work, please see the NOTICE file in the top level
* directory of this distribution.
*/
package org.apache.abdera.protocol.server.adapters.couchdb;

import java.io.CharArrayWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONObject;

import org.apache.abdera.Abdera;
import org.apache.abdera.i18n.text.Normalizer;
import org.apache.abdera.i18n.text.Sanitizer;
import org.apache.abdera.model.AtomDate;
import org.apache.abdera.model.Entry;
import org.apache.abdera.model.Link;
import org.apache.abdera.protocol.server.ProviderHelper;
import org.apache.abdera.protocol.server.RequestContext;
import org.apache.abdera.protocol.server.ResponseContext;
import org.apache.abdera.protocol.server.Target;
import org.apache.abdera.protocol.server.provider.managed.FeedConfiguration;
import org.apache.abdera.protocol.server.provider.managed.ManagedCollectionAdapter;

import com.fourspaces.couchdb.Database;
import com.fourspaces.couchdb.Document;
import com.fourspaces.couchdb.Session;
import com.fourspaces.couchdb.ViewResults;

/**
* The CouchDB Adapter uses a CouchDB database as the backend storage for an Atompub Collection. As an extension of the
* ManagedCollectionAdapter class, the Adapter is intended to be used with implementations of the ManagedProvider and
* are configured using /abdera/adapter/*.properties files. By default, the CouchDbAdapter assumes that CouchDB is
* running on localhost on port 5984. The host name and port can be changed by setting the couchdb.host and couchdb.port
* values in the Adapter instance *.properties file. The Adapter uses the Abdera Atom-to-JSON converter to store
* Collection entries as JSON documents in a CouchDB database.
*/
public class CouchDbAdapter extends ManagedCollectionAdapter {

    private final DocumentComparator sorter = new DocumentComparator();
    private final String host;
    private final int port;

    public CouchDbAdapter(Abdera abdera, FeedConfiguration config) {
        this(abdera, config, null, -1);
    }

    public CouchDbAdapter(Abdera abdera, FeedConfiguration config, String host, int port) {
        super(abdera, config);
        if (host == null) {
            host = (String)config.getProperty("couchdb.host");
            if (host == null)
                host = "localhost";
        }
        if (port < 0) {
            try {
                port = Integer.parseInt((String)config.getProperty("couchdb.port"));
            } catch (Exception e) {
            }
            if (port < 0)
                port = 5984;
        }
        this.host = host;
        this.port = port;
    }

    private synchronized Database getDatabase(RequestContext request) {
        String name = request.getTarget().getParameter("feed");
        Session session = new Session(host, port);
        Database db = null;
        try {
            db = session.getDatabase(name);
        } catch (Exception e) {
            // error if the db is not found, ignore the error,
            // we're going to create it
            db = session.createDatabase(name);
        }
        return db;
    }

    public ResponseContext getFeed(RequestContext request) {
        Database db = getDatabase(request);
        ViewResults res = db.getAllDocuments();
        List<Document> entries = new ArrayList<Document>();
        List<Document> docs = res.getResults();
        for (Document doc : docs) {
            entries.add(db.getDocument(doc.getString("id")));
        }
        Collections.sort(entries, sorter);
        return new JsonObjectResponseContext(request.getAbdera(), config, res, entries.toArray(new Document[entries
            .size()])).setStatus(200).setEntityTag(res.getRev());
    }

    public ResponseContext deleteEntry(RequestContext request) {
        Target target = request.getTarget();
        String feed = target.getParameter("feed");
        String entry = target.getParameter("entry");
        Session session = new Session(host, port);
        Database db = session.getDatabase(feed);
        Document doc = null;
        try {
            doc = db.getDocument(entry);
        } catch (Exception e) {
            // error if the doc isn't found, we deal with the null result below
        }
        if (doc != null) {
            db.deleteDocument(doc);
            return ProviderHelper.nocontent();
        } else
            return ProviderHelper.notfound(request);
    }

    private void setEditDetail(RequestContext request) throws IOException {
        Target target = request.getTarget();
        String feed = target.getParameter("feed");
        String id = target.getParameter("entry");
        Entry entry = (Entry)request.getDocument().getRoot();
        entry.setEdited(new Date());
        Link link = entry.getEditLink();
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("feed", feed);
        params.put("entry", id);
        String href = request.absoluteUrlFor("entry", params);
        if (link == null) {
            entry.addLink(href, "edit");
        } else {
            link.setHref(href);
        }
    }

    public ResponseContext postEntry(RequestContext request) {
        Target target = request.getTarget();
        String feed = target.getParameter("feed");
        Session session = new Session(host, port);
        Database db = session.getDatabase(feed);
        try {
            CharArrayWriter cwriter = new CharArrayWriter();
            setEditDetail(request);
            request.getDocument().getRoot().writeTo("json", cwriter);
            String json = new String(cwriter.toCharArray());
            JSONObject obj = JSONObject.fromObject(json);
            String key = createKey(request);
            Document doc = null;
            try {
                doc = db.getDocument(key);
            } catch (Exception e) {
                // error if the doc isn't found, we deal with the null result below
            }
            if (doc != null) {
                return ProviderHelper.conflict(request, "Entry with that key already exists");
            } else {
                doc = new Document(obj);
                doc.setId(key);
                db.saveDocument(doc);
                doc = db.getDocument(key);
                if (doc != null) {
                    Map<String, Object> params = new HashMap<String, Object>();
                    params.put("feed", feed);
                    params.put("entry", key);
                    String urlFor = request.absoluteUrlFor("entry", params);
                    return new JsonObjectResponseContext(request.getAbdera(), config, doc).setStatus(201)
                        .setEntityTag(doc.getRev()).setLocation(urlFor);
                } else {
                    return ProviderHelper.servererror(request, null);
                }
            }
        } catch (IOException e) {
            return ProviderHelper.servererror(request, e);
        }
    }

    private String createKey(RequestContext request) throws IOException {
        String slug = request.getSlug();
        if (slug == null) {
            slug = ((Entry)request.getDocument().getRoot()).getTitle();
        }
        return Sanitizer.sanitize(slug, "", true, Normalizer.Form.D);
    }

    public ResponseContext getEntry(RequestContext request) {
        Target target = request.getTarget();
        String feed = target.getParameter("feed");
        String entry = target.getParameter("entry");
        Session session = new Session(host, port);
        Database db = session.getDatabase(feed);
        Document doc = null;
        try {
            doc = db.getDocument(entry);
        } catch (Exception e) {
            // error if the doc isn't found, we deal with the null result below
        }
        if (doc != null)
            return new JsonObjectResponseContext(request.getAbdera(), config, doc).setStatus(200).setEntityTag(doc
                .getRev());
        else
            return ProviderHelper.notfound(request);
    }

    public ResponseContext putEntry(RequestContext request) {
        Target target = request.getTarget();
        String feed = target.getParameter("feed");
        Session session = new Session(host, port);
        Database db = session.getDatabase(feed);
        try {
            CharArrayWriter cwriter = new CharArrayWriter();
            setEditDetail(request);
            request.getDocument().getRoot().writeTo("json", cwriter);
            String json = new String(cwriter.toCharArray());
            JSONObject obj = JSONObject.fromObject(json);
            String key = target.getParameter("entry");
            Document doc = null;
            try {
                doc = db.getDocument(key);
            } catch (Exception e) {
                // error if the doc isn't found, we deal with the null result below
            }
            if (doc == null) {
                return ProviderHelper.notfound(request);
            } else {
                db.deleteDocument(doc);
                doc = new Document(obj);
                doc.setId(key);
                db.saveDocument(doc);
                doc = db.getDocument(key);
                if (doc != null)
                    return new JsonObjectResponseContext(request.getAbdera(), config, doc).setStatus(200)
                        .setEntityTag(doc.getRev());
                else
                    return ProviderHelper.servererror(request, null);
            }
        } catch (IOException e) {
            return ProviderHelper.servererror(request, e);
        }
    }

    public ResponseContext getCategories(RequestContext request) {
        return ProviderHelper.notfound(request);
    }

    public ResponseContext extensionRequest(RequestContext request) {
        return ProviderHelper.notfound(request);
    }

    private static class DocumentComparator implements Comparator<Document> {
        public int compare(Document doc1, Document doc2) {
            String ed1 = doc1.getString("edited");
            String ed2 = doc2.getString("edited");
            Date d1 = AtomDate.parse(ed1);
            Date d2 = AtomDate.parse(ed2);
            if (d1.before(d2))
                return 1;
            else if (d1.after(d2))
                return -1;
            else
                return 0;
        }
    }
}
TOP

Related Classes of org.apache.abdera.protocol.server.adapters.couchdb.CouchDbAdapter$DocumentComparator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.