package org.karmaexchange.resources;
import static java.lang.String.format;
import static org.karmaexchange.util.OfyService.ofy;
import java.net.URI;
import javax.servlet.ServletContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import org.karmaexchange.dao.BaseDao;
import org.karmaexchange.resources.msg.BaseDaoView;
import org.karmaexchange.resources.msg.ErrorResponseMsg;
import org.karmaexchange.resources.msg.ErrorResponseMsg.ErrorInfo;
import org.karmaexchange.util.OfyUtil;
import com.googlecode.objectify.Key;
@NoArgsConstructor
@AllArgsConstructor
public abstract class BaseDaoResource<T extends BaseDao<T>, U extends BaseDaoView<T>> {
public static final int DEFAULT_NUM_SEARCH_RESULTS = 25;
@Context
protected UriInfo uriInfo;
@Context
protected Request request;
@Context
protected ServletContext servletContext;
@POST
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response upsertResource(U resourceView) {
T resource = resourceView.getDao();
preProcessUpsert(resource);
BaseDao.upsert(resource);
URI uri = uriInfo.getAbsolutePathBuilder().path(resource.getKey()).build();
return Response.created(uri).build();
}
@Path("{resource}")
@GET
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response getResource(@PathParam("resource") String key) {
return Response.ok(createBaseDaoView(getResourceObj(key))).build();
}
protected T getResourceObj(String keyStr) {
Key<T> key;
try {
key = OfyUtil.createIfKey(keyStr);
} catch (IllegalArgumentException e) {
// See if the key is actually an id.
key = keyFromId(keyStr);
}
T resource = ofy().load().key(key).now();
if (resource == null) {
throw ErrorResponseMsg.createException("resource does not exist", ErrorInfo.Type.BAD_REQUEST);
}
return resource;
}
protected abstract U createBaseDaoView(T resource);
@Path("{resource}")
@POST
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response updateResource(@PathParam("resource") String key, U resourceView) {
T resource = resourceView.getDao();
preProcessUpsert(resource);
if (!resource.isKeyComplete()) {
throw ErrorResponseMsg.createException("the resource key is incomplete",
ErrorInfo.Type.BAD_REQUEST);
}
if (!key.equals(Key.create(resource).getString())) {
throw ErrorResponseMsg.createException(
format("the resource key [%s] does not match the url path key [%s]",
Key.create(resource).getString(), key),
ErrorInfo.Type.BAD_REQUEST);
}
BaseDao.upsert(resource);
return Response.created(uriInfo.getAbsolutePath()).build();
}
@Path("{resource}")
@DELETE
public void deleteResource(@PathParam("resource") String keyStr) {
BaseDao.delete(OfyUtil.<T>createKey(keyStr));
}
public void deleteResource(Key<T> key) {
BaseDao.delete(key);
}
protected void preProcessUpsert(T resource) {
// No-op.
}
protected Key<T> keyFromId(String id) {
throw ErrorResponseMsg.createException("invalid key", ErrorInfo.Type.BAD_REQUEST);
}
}