package gov.nih.ncgc.bard.rest; import gov.nih.ncgc.bard.entity.BardLinkedEntity; import gov.nih.ncgc.bard.entity.ProteinTarget; import gov.nih.ncgc.bard.entity.Publication; import gov.nih.ncgc.bard.entity.TargetClassification; import gov.nih.ncgc.bard.tools.Util; import java.io.IOException; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.NotFoundException; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; /** * Prototype of MLBD REST resources. * <p/> * This is mainly to explore the use of Jersey for presenting REST * services for the MLBD * * @author Rajarshi Guha */ public class BARDTargetResource extends BARDResource<ProteinTarget> { public static final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss"; static final String VERSION = "1.0"; @Context ServletContext servletContext; @Context HttpServletRequest httpServletRequest; public Class<ProteinTarget> getEntityClass () { return ProteinTarget.class; } public String getResourceBase () { return BARDConstants.API_BASE+"/targets"; } @GET @Produces("text/plain") @Path("/_info") public String info() { StringBuilder msg = new StringBuilder("Returns protein target information\n\nAvailable resources:\n"); List<String> paths = Util.getResourcePaths(this.getClass()); for (String path : paths) msg.append(path).append("\n"); msg.append("/targets/" + BARDConstants.API_EXTRA_PARAM_SPEC + "\n"); return msg.toString(); } @GET public Response getResources(@QueryParam("filter") String filter, @QueryParam("expand") String expand, @QueryParam("skip") Integer skip, @QueryParam("top") Integer top) { if (skip == null) skip = -1; if (top == null) top = -1; boolean expandEntries = false; if (expand != null && (expand.toLowerCase().equals("true") || expand.toLowerCase().equals("yes"))) expandEntries = true; try { String linkString = null; if (filter == null) { if (countRequested) return Response.ok(String.valueOf(db.getEntityCount(ProteinTarget.class)), MediaType.TEXT_PLAIN).build(); if ((top == -1)) { // top was not specified, so we start from the beginning top = getDefaultEntityCount(); } if (skip == -1) skip = 0; String expandClause = "expand=false"; if (expandEntries) expandClause = "expand=true"; if (skip + top <= db.getEntityCount(ProteinTarget.class)) linkString = BARDConstants.API_BASE + "/targets?skip=" + (skip + top) + "&top=" + top + "&" + expandClause; } List<ProteinTarget> targets = db.searchForEntity(filter, skip, top, ProteinTarget.class); db.closeConnection(); if (countRequested) return Response.ok(String.valueOf(targets.size()), MediaType.TEXT_PLAIN).build(); if (expandEntries) { BardLinkedEntity linkedEntity = new BardLinkedEntity(targets, linkString); return Response.ok(Util.toJson(linkedEntity), MediaType.APPLICATION_JSON).build(); } else { List<String> links = new ArrayList<String>(); for (ProteinTarget a : targets) links.add(a.getResourcePath()); BardLinkedEntity linkedEntity = new BardLinkedEntity(links, linkString); return Response.ok(Util.toJson(linkedEntity), MediaType.APPLICATION_JSON).build(); } } catch (SQLException e) { throw new WebApplicationException(e, 500); } catch (IOException e) { throw new WebApplicationException(e, 500); } } @GET @Path("/accession/{acc}") @Produces("application/json") public Response getResources(@PathParam("acc") String resourceId, @QueryParam("filter") String filter, @QueryParam("expand") String expand) { ProteinTarget p; try { String json; if (countRequested) json = "1"; else { p = db.getProteinTargetByAccession(resourceId); db.closeConnection(); if (p.getAcc() == null) throw new WebApplicationException(404); json = p.toJson(); } return Response.ok(json, MediaType.APPLICATION_JSON).build(); } catch (SQLException e) { throw new WebApplicationException(e, 500); } catch (IOException e) { throw new WebApplicationException(e, 500); } } @GET @Path("/accession/{acc}/publications") public Response getTargetPublications(@PathParam("acc") String resourceId, @QueryParam("filter") String filter, @QueryParam("search") String search, @QueryParam("expand") String expand) { boolean expandEntries = false; if (expand != null && (expand.toLowerCase().equals("true") || expand.toLowerCase().equals("yes"))) expandEntries = true; List<Publication> pubs = null; try { pubs = db.getProteinTargetPublications(resourceId); Response response; if (countRequested) response = Response.ok(String.valueOf(pubs.size()), MediaType.TEXT_PLAIN).build(); else if (expandEntries) { String json = Util.toJson(pubs); response = Response.ok(json, MediaType.APPLICATION_JSON).build(); } else { List<String> links = new ArrayList<String>(); for (Publication pub : pubs) links.add(pub.getResourcePath()); String json = Util.toJson(links); response = Response.ok(json, MediaType.APPLICATION_JSON).build(); } db.closeConnection(); return response; } catch (SQLException e) { throw new WebApplicationException(e, 500); } catch (JsonMappingException e) { throw new WebApplicationException(e, 500); } catch (JsonGenerationException e) { throw new WebApplicationException(e, 500); } catch (IOException e) { throw new WebApplicationException(e, 500); } } @GET @Path("/accession/{acc}/classification/{source}") @Produces(MediaType.APPLICATION_JSON) public Response getClassificationsForAccession(@PathParam("source") String source, @PathParam("acc") String acc) throws SQLException, IOException { List<TargetClassification> classes = null; if (source.toLowerCase().equals("panther")) { classes = db.getPantherClassesForAccession(acc); } db.closeConnection(); if (classes == null) throw new NotFoundException("No classifications for " + acc + " in the " + source + " hierarchy"); if (countRequested) return Response.ok(String.valueOf(classes.size())).type(MediaType.TEXT_PLAIN_TYPE).build(); else { ObjectMapper mapper = new ObjectMapper(); ObjectNode node = mapper.createObjectNode(); JsonNode classNodes = mapper.valueToTree(classes); node.put(acc, classNodes); String json = mapper.writeValueAsString(node); return Response.ok(json).type(MediaType.APPLICATION_JSON_TYPE).build(); } } @POST @Path("/accession/classification/{source}") @Consumes("application/x-www-form-urlencoded") @Produces(MediaType.APPLICATION_JSON) public Response getClassificationsForAccessions(@PathParam("source") String source, @FormParam("accs") String accs) throws SQLException, IOException { String[] laccs = accs.split(","); ObjectMapper mapper = new ObjectMapper(); ObjectNode node = mapper.createObjectNode(); for (String acc : laccs) { List<TargetClassification> classes = null; if (source.toLowerCase().equals("panther")) { classes = db.getPantherClassesForAccession(acc.trim()); } JsonNode classNodes = mapper.valueToTree(classes); node.put(acc, classNodes); } db.closeConnection(); String json = mapper.writeValueAsString(node); return Response.ok(json).type(MediaType.APPLICATION_JSON_TYPE).build(); } @GET @Path("/classification/{source}/{clsid}") @Produces(MediaType.APPLICATION_JSON) public Response getAccessionsForClassification(@PathParam("source") String source, @PathParam("clsid") String clsid) throws SQLException, IOException { List<ProteinTarget> targets = null; if (source.toLowerCase().equals("panther")) { targets = db.getProteinTargetsForPantherClassification(clsid); } db.closeConnection(); if (targets == null) throw new NotFoundException("No protein targets for " + clsid + " in the " + source + " hierarchy"); if (countRequested) return Response.ok(String.valueOf(targets.size())).type(MediaType.TEXT_PLAIN_TYPE).build(); else return Response.ok(Util.toJson(targets)).type(MediaType.APPLICATION_JSON_TYPE).build(); } }