/**
* Copyright (C) 2015 Orion Health (Orchestral Development Ltd)
*
* 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 xbdd.webapp.resource.feature;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.BeanParam;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
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.Response;
import xbdd.webapp.factory.MongoDBAccessor;
import xbdd.webapp.util.Coordinates;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
@Path("/rest/favourites")
public class Favourites {
private final MongoDBAccessor client;
@Inject
public Favourites(final MongoDBAccessor client) {
this.client = client;
}
public void setFavouriteStateOfProduct(final String product,
final boolean state,
final HttpServletRequest req) {
final DB db = this.client.getDB("bdd");
final DBCollection collection = db.getCollection("users");
final BasicDBObject user = new BasicDBObject();
user.put("user_id", req.getRemoteUser());
final DBObject blank = new BasicDBObject();
collection.findAndModify(user, blank, blank, false, new BasicDBObject("$set", user), true, true);
//User exists
final DBObject favourites = new BasicDBObject("favourites."+product, state);
final DBObject update = new BasicDBObject("$set",favourites);
collection.update(user, update);
}
@PUT
@Path("/{product}")
@Produces("application/json")
public Response productFavouriteStateOn(@PathParam("product") final String product,
@Context final HttpServletRequest req) {
setFavouriteStateOfProduct(product, true, req);
return Response.ok().build();
}
@DELETE
@Path("/{product}")
@Produces("application/json")
public Response productFavouriteStateOff(@PathParam("product") final String product,
@Context final HttpServletRequest req) {
setFavouriteStateOfProduct(product, false, req);
return Response.ok().build();
}
@GET
@Path("/{product}")
@Produces("application/json")
public boolean getFavouriteStateOfProduct(@PathParam("product") final String product,
@Context final HttpServletRequest req) {
final DB db = this.client.getDB("bdd");
final DBCollection collection = db.getCollection("users");
final BasicDBObject query = new BasicDBObject("user_id", req.getRemoteUser());
query.put("favourites."+product, true);
final DBObject favState = collection.findOne(query);
return (favState != null);
}
@GET
@Path("/")
@Produces("application/json")
public DBObject getSummaryOfAllReports(@Context final HttpServletRequest req) {
final DB db = this.client.getDB("bdd");
final DBCollection collection = db.getCollection("summary");
final DBCollection usersCollection = db.getCollection("users");
final BasicDBObject user = new BasicDBObject();
user.put("user_id", req.getRemoteUser());
final DBObject blank = new BasicDBObject();
DBObject uDoc = usersCollection.findAndModify(user, blank, blank, false, new BasicDBObject("$setOnInsert", new BasicDBObject("favourites", new BasicDBObject())), true, true);
DBObject userFavourites;
if (uDoc.containsField("favourites")) {
userFavourites = (DBObject) uDoc.get("favourites");
} else {
userFavourites = new BasicDBObject();
}
final DBCursor cursor = collection.find();
try {
final BasicDBList returns = new BasicDBList();
DBObject doc;
while (cursor.hasNext()) {
doc = cursor.next();
String product = ((String) ((DBObject) doc.get("coordinates")).get("product"));
if (userFavourites.containsField(product) && (boolean) userFavourites.get(product)) {
doc.put("favourite", userFavourites.get(product));
returns.add(doc);
}
}
return returns;
} finally {
cursor.close();
}
}
private void setPinStateOfBuild(final String product,
final String version,
final String build,
final boolean state) {
final DB db = this.client.getDB("bdd");
final DBCollection collection = db.getCollection("summary");
final BasicDBObject query = new BasicDBObject("_id",product+"/"+version);
final BasicDBObject toBePinned = new BasicDBObject("pinned",build);
final String method;
if (state) {
method = "$addToSet";
} else {
method = "$pull";
}
collection.update(query, new BasicDBObject(method,toBePinned));
}
@PUT
@Path("/pin/{product}/{major}.{minor}.{servicePack}/{build}/")
@Produces("application/json")
public Response pinABuild(@BeanParam Coordinates coordinates) {
setPinStateOfBuild(coordinates.getProduct(), coordinates.getVersionString(), coordinates.getBuild(), true);
return Response.ok().build();
}
@DELETE
@Path("/pin/{product}/{major}.{minor}.{servicePack}/{build}/")
@Produces("application/json")
public Response unPinABuild(@BeanParam Coordinates coordinates) {
setPinStateOfBuild(coordinates.getProduct(), coordinates.getVersionString(), coordinates.getBuild(), false);
return Response.ok().build();
}
}