package org.genedb.web.mvc.controller;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Calendar;
import java.util.Iterator;
import java.lang.StringBuffer;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.text.FieldPosition;
import java.text.ParseException;
import javax.servlet.http.HttpServletRequest;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.genedb.web.mvc.model.AnnotationChangesRssContent;
@Controller
@RequestMapping(value="/rss")
public class AnnotationChangesRssController {
private JsonParser parser = new JsonParser();
private ClientHttpRequestFactory fac = new SimpleClientHttpRequestFactory();
private SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
private String getJSONforOrganism(String url) throws IOException, URISyntaxException {
BufferedReader bufferedReader = null;
StringBuilder builder = new StringBuilder();
ClientHttpRequest req = fac.createRequest(new URI(url), HttpMethod.GET);
ClientHttpResponse res = req.execute();
InputStream inputStream = res.getBody();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
for (String line = null; (line = bufferedReader.readLine()) != null;) {
builder.append(line).append("\n");
}
return builder.toString();
}
private String getDateSinceFormatted(int value, int unit) {
StringBuffer returnedStringBuf = new StringBuffer(20);
Date now = new Date();
Calendar c = Calendar.getInstance();
c.setTime(now);
c.add(unit, -1 * value);
returnedStringBuf = dateFormatter.format(c.getTime(), returnedStringBuf, new FieldPosition(0));
return returnedStringBuf.toString();
}
@SuppressWarnings("unchecked")
@RequestMapping(method = RequestMethod.GET , value="/{orgName}")
public ModelAndView getRssForOrganism(
@PathVariable(value="orgName") String orgName) throws IOException, URISyntaxException {
// default: 120 days
return getRssForOrganismAndTime(orgName, 120, Calendar.DAY_OF_MONTH);
}
@SuppressWarnings("unchecked")
@RequestMapping(method = RequestMethod.GET , value="/{orgName}/since/{nDays}/days")
public ModelAndView getRssForOrganismAndDays(
@PathVariable(value="orgName") String orgName,
@PathVariable(value="nDays") int nDays) throws IOException, URISyntaxException {
return getRssForOrganismAndTime(orgName, nDays, Calendar.DAY_OF_MONTH);
}
@SuppressWarnings("unchecked")
@RequestMapping(method = RequestMethod.GET , value="/{orgName}/since/{nMonths}/months")
public ModelAndView getRssForOrganismAndMonths(
@PathVariable(value="orgName") String orgName,
@PathVariable(value="nMonths") int nMonths) throws IOException, URISyntaxException {
return getRssForOrganismAndTime(orgName, nMonths, Calendar.MONTH);
}
private ModelAndView getRssForOrganismAndTime(String orgName, int since, int unit) throws IOException, URISyntaxException {
ServletRequestAttributes sra = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest req = sra.getRequest();
List<AnnotationChangesRssContent> items = new ArrayList<AnnotationChangesRssContent>();
String baseUrl = req.getScheme()+"://"+req.getServerName()+":"+req.getServerPort();
String dateSince = getDateSinceFormatted(since, unit);
JsonElement rootElement = parser.parse(getJSONforOrganism(baseUrl
+ "/services/features/annotation_changes.json?organism=com%3A"
+ orgName + "&date="+dateSince));
if (rootElement.isJsonArray()) {
JsonArray jsonArray = rootElement.getAsJsonArray();
Iterator<JsonElement> msg = jsonArray.iterator();
while (msg.hasNext()) {
JsonObject jo = msg.next().getAsJsonObject();
Date lastDate;
// get unique name
String uniqueName = jo.get("uniqueName").getAsString();
// get changes
JsonArray changes = jo.get("changes").getAsJsonArray();
Iterator<JsonElement> changeIt = changes.iterator();
StringBuilder changeStrB = new StringBuilder();
String dateStr = "";
while (changeIt.hasNext()) {
JsonObject changeO = changeIt.next().getAsJsonObject();
try {
String user = changeO.get("user").getAsString();
String detail = changeO.get("detail").getAsString();
String type = changeO.get("type").getAsString();
changeStrB.append(user + " (" + type + ")" + ": " + detail ).append("\n");
dateStr = changeO.get("date").getAsString();
} catch (Exception e) {
// skip invalid entries (of which there should be none)
continue;
}
}
// get date
try {
lastDate = dateFormatter.parse(dateStr);
} catch (ParseException e) {
lastDate = new Date();
}
AnnotationChangesRssContent content = new AnnotationChangesRssContent();
content.setGene(uniqueName);
content.setUrl(baseUrl+"/gene/"+uniqueName);
content.setSummary(changeStrB.toString());
content.setDate(lastDate);
items.add(content);
}
}
Collections.sort(items);
ModelAndView mav = new ModelAndView();
mav.setViewName("rssViewer");
mav.addObject("feedContent", items);
mav.addObject("orgName", orgName);
mav.addObject("dateSince", dateSince);
return mav;
}
}