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.