JsonCollection.java

/***************************************************************************
   Copyright 2012 Emily Estes

   Licensed 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.
***************************************************************************/
package net.metanotion.contentstore.simple;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import net.metanotion.json.JsonObject;

import net.metanotion.util.Dictionary;

import net.metanotion.web.HttpStatus;
import net.metanotion.web.HttpValues;
import net.metanotion.web.concrete.HttpException;
import net.metanotion.web.concrete.HttpUtil;
import net.metanotion.web.concrete.JsonUtil;

import net.metanotion.contentstore.SimpleCollection;

final class JsonCollection implements SimpleCollectionApi {
	private static final String SLASH = "/";
	private static final HttpException INSUFFICIENT_STORAGE =
		new HttpException(HttpUtil.newJsonResponse("", HttpStatus.INSUFFICIENT_STORAGE.codeNumber()));
	private static final HttpException NOT_FOUND = new HttpException(HttpUtil.new404(""));
	private static final HttpException FORBIDDEN =
		new HttpException(HttpUtil.newJsonResponse("{}", HttpStatus.FORBIDDEN.codeNumber()));

	private final Dictionary<String,SimpleCollection<JsonObject>> db;
	private final int maxPageSize;
	private final String prefix;

	public JsonCollection(final Dictionary<String,SimpleCollection<JsonObject>> db, final int maxPageSize, final String prefix) {
		this.db = db;
		this.maxPageSize = maxPageSize;
		this.prefix = prefix;
	}

	// CollectionManager
	@Override public Object api(final String collection) {
		return JsonUtil.makeWebApi(CollectionManager.class, prefix + collection + SLASH);
	}

	@Override public HttpValues notFound() { throw NOT_FOUND; }

	@Override public JList list(final String collection, final int page) {
		final Iterable<Map.Entry<String,JsonObject>> list = db.get(collection).list(maxPageSize + 1, page * maxPageSize);
		if(list == null) { throw FORBIDDEN; }
		final ArrayList<JsonObject> eList = new ArrayList<>(maxPageSize);
		int ct = 0;
		for(final Map.Entry<String,JsonObject> ix: list) {
			ct++;
			if(ct > maxPageSize) { break; }
			eList.add(makeJsonItem(collection, ix.getKey(), ix.getValue()));
		}
		final String next = (ct > maxPageSize) ? (prefix + collection + "/list?page=" + Integer.toString(page + 1)) : null;
		return new JList(eList, next);
	}

	private final String itemPrefix(final String collection, final String id) {
		return prefix + collection + "/item/" + id + SLASH;
	}

	private final JsonObject makeJsonItem(final String collection, final String id, final JsonObject obj) {
		final HashMap<String,Object> v = new HashMap<>();
		v.put("value", obj);
		return JsonUtil.makeWebApi(ItemManager.class, itemPrefix(collection, id), v);
	}

	@Override public JsonObject create(final String collection, final JsonObject json) {
		final String id = db.get(collection).create(json);
		if(id == null) { throw INSUFFICIENT_STORAGE; }
		return makeJsonItem(collection, id, json);
	}

	// ItemManager
	@Override public JsonObject get(final String collection, final String id) {
		final JsonObject o = db.get(collection).get(id);
		if(o == null) { throw NOT_FOUND; }
		return makeJsonItem(collection, id, o);
	}

	@Override public JsonObject update(final String collection, final String id, final JsonObject json) {
		final Map.Entry<String,JsonObject> idx = db.get(collection).update(id, json);
		if(idx == null) { throw NOT_FOUND; }
		return makeJsonItem(collection, idx.getKey(), idx.getValue());
	}

	@Override public JRemoved remove(final String collection, final String id) {
		return new JRemoved(db.get(collection).remove(id), itemPrefix(collection, id) + "get");
	}
}