Package net.caprazzi.slabs

Source Code of net.caprazzi.slabs.SlabsOnKeez

package net.caprazzi.slabs;

import java.util.Date;

import net.caprazzi.keez.Keez;
import net.caprazzi.keez.Keez.Db;
import net.caprazzi.keez.Keez.Entry;
import net.caprazzi.keez.Keez.List;
import net.caprazzi.keez.Keez.Put;
import net.caprazzi.keez.KeezException;

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ObjectNode;

import com.google.common.base.Function;
import com.google.common.collect.Iterables;

/**
* Slabs implementations based on Keez
*/
public class SlabsOnKeez implements Slabs {

  private final Db db;
  private Class<?>[] typeMap;

  public SlabsOnKeez(Db db, Class<? extends SlabsDoc>... types) {
    this.db = db;
    typeMap = setupTypes(types);
  }   
 
  @Override
  public void list(final SlabsList list) {
     db.list(new List() {
      
      @Override public void entries(Iterable<Entry> entries) {
        list.callEntries(Iterables.transform(entries, entriesToDocs));
      }

      @Override public void notFound() {
        list.callNotFound();
      }

      @Override public void error(KeezException ex) {
        list.callError(ex);
      }
     
      @Override public void applicationError(KeezException ex) {
        list.callApplicationError(ex);
      }
    })
  }
 
  private Function<Keez.Entry, SlabsDoc> entriesToDocs = new Function<Keez.Entry, SlabsDoc>() {
    @Override
    public SlabsDoc apply(Entry e) {
      ObjectMapper mapper = new ObjectMapper();
      try {
        ObjectNode root = mapper.readValue(e.getData(), ObjectNode.class);
        String typeName = root.get("name").getTextValue();
        Class<?> clz = getType(typeName);
        SlabsDoc doc = (SlabsDoc) mapper.readValue(root.get("obj"), clz);
        doc.setId(e.getKey());
        doc.setRevision(e.getRevision());
        return doc;
      } catch (Exception ex) {       
        throw new RuntimeException(ex);
      }
    }
  };
 
  @Override
  public void put(final SlabsDoc doc, final SlabsPut callback) {
    byte[] data;
    try {
      ObjectNode databaseJson = doc.getDatabaseJson();
      databaseJson.put("_last_update", new Date().getTime());
      ObjectMapper mapper = new ObjectMapper();
      data = mapper.writeValueAsBytes(databaseJson);
    } catch (Exception e) {
      callback.callError(doc.getId(), e);
      return;
    }
   
    db.put(doc.getId(), doc.getRevision(), data, new Put() {

      @Override public void collision(String key, int yourRev, int foundRev) {
        callback.callCollision(key, yourRev, foundRev);
      }

      @Override public void error(String key, KeezException ex) {
        callback.callError(key, ex);
      }

      @Override public void ok(String key, int revision) {
        doc.setId(key);
        doc.setRevision(revision);
        callback.callOk(doc);
      }
    });
  }
 
  /***
   *
   *  TODO: this hashmap is not happy at all
   *
   */
  private Class<?>[] setupTypes(Class<? extends SlabsDoc>[] types) {
    Class<?>[] clz = new Class[100];   
    for (Class<?> t : types) {     
      String typeName = t.getAnnotation(SlabsType.class).value();     
      int hashCode = typeName.hashCode();
      int pos = Math.abs(hashCode) % clz.length;
      if (clz[pos] != null) {
        throw new RuntimeException("collision while building type map list");
      }
      clz[pos] = t;
    }
    return clz;
  }
 
  private Class<?> getType(String name) {
    return typeMap[Math.abs(name.hashCode()) % typeMap.length];
  }
 
 
    /**********************************************************
    /* Callbacks
    /**********************************************************/
   
 
  public static abstract class Callback {
    public void applicationError(SlabsException ex) {
      ex.printStackTrace();
    }
   
    void callApplicationError(Exception ex) {
      try {
        applicationError(new SlabsException(ex));
      }
      catch (Exception e) {
        System.err.println("Exception while executing applicationError");
        e.printStackTrace();
      }
    }
  }
 
  public static abstract class SlabsPut extends Callback {
   
    public abstract void ok(SlabsDoc doc);

    public abstract void collision(String id, int yourRev, int foundRev);

    public abstract void error(String id, SlabsException e);

    final void callError(String id, Exception e) {
      try {
        error(id, new SlabsException(e));
      }
      catch(Exception ex) {
        callApplicationError(ex);
      }
    }

    final void callOk(SlabsDoc doc) {
      try {
        ok(doc);
      }
      catch(Exception ex) {
        callApplicationError(ex);
      }
    }

    public final void callCollision(String id, int yourRev, int foundRev) {
      try {
        collision(id, yourRev, foundRev);
      }
      catch(Exception ex) {
        callApplicationError(ex);
      }
    }
  }
 
  public static abstract class SlabsList extends Callback {
   
    public abstract void entries(Iterable<SlabsDoc> docs);
   
    public abstract void error(SlabsException ex);
   
    public abstract void notFound();
   
    protected final void callEntries(Iterable<SlabsDoc> docs) {
      try {
        entries(docs);
      }
      catch (Exception ex) {
        callApplicationError(ex);
      }
    }
   
    public final void callError(Exception ex) {
      try {
        error(new SlabsException(ex));
      }
      catch (Exception e) {
        callApplicationError(ex);
      }
    }

    public final void callNotFound() {
      try {
        notFound();
      }
      catch (SlabsException ex) {
        callApplicationError(ex);
      }
    }
  }
 
  public interface SlabsDelete {
   
  }

}
TOP

Related Classes of net.caprazzi.slabs.SlabsOnKeez

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.