package org.genedb.web.mvc.controller;
import org.genedb.db.dao.SequenceDao;
import org.genedb.querying.history.HistoryManager;
import org.genedb.querying.history.HistoryType;
import org.gmod.schema.feature.Gene;
import org.gmod.schema.feature.Transcript;
import org.gmod.schema.mapped.Feature;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpSession;
import com.google.common.collect.Lists;
/**
* Controller for uploading a list of ids, either from a file or a textbox.
* After validating them it stores them in the user's history
*/
@Controller
@RequestMapping("/IdList")
public class IdListController {
private final Logger logger = Logger.getLogger(IdListController.class);
private HistoryManagerFactory hmFactory;
private SequenceDao sequenceDao;
@RequestMapping(method=RequestMethod.GET)
public String prepareForm() {
return "analysis/idList";
}
@RequestMapping(method=RequestMethod.POST)
public ModelAndView processImageUpload(
HttpSession session,
@RequestParam("idList") String idList,
//@RequestParam("oldIds") boolean useOldIds,
//@RequestParam("historyItemName") String historyItemName,
@RequestParam("ids") MultipartFile mf) {
List<String> ids = Lists.newArrayList();
if (!mf.isEmpty()) {
try {
addIds(ids, new String(mf.getBytes()));
}
catch (IOException exp) {
exp.printStackTrace();
return new ModelAndView("redirect:internalError");
}
}
if (StringUtils.hasText(idList)) {
addIds(ids, idList);
}
List<String> okIds = Lists.newArrayList();
List<String> oldIds = Lists.newArrayList();
List<String> ambiguousIds = Lists.newArrayList();
List<String> badIds = Lists.newArrayList();
validateIds(ids, okIds, oldIds, ambiguousIds, badIds);
HistoryManager hm = hmFactory.getHistoryManager(session);
// if (useOldIds) {
// okIds.addAll(oldIds);
// }
String historyName = "Uploaded";
// if (StringUtils.hasText(historyItemName)) {
// historyName = historyItemName;
// }
for (String string : okIds) {
logger.error("The list of ok ids includes '"+string+"'");
}
if (ambiguousIds.size() > 0 || badIds.size() > 0) {
// A problem, some of the submitted ids are wrong
ModelAndView mav = new ModelAndView();
mav.setViewName("analysis/idList");
StringBuilder message = new StringBuilder();
if (badIds.size() > 0) {
message.append("Unrecognized ids\n");
for (String badId : badIds) {
message.append(badId);
message.append('\n');
}
message.append("\n\n\n");
}
if (ambiguousIds.size() > 0) {
message.append("Ambiguous ids\n");
for (String ambiguousId : ambiguousIds) {
message.append(ambiguousId);
message.append('\n');
}
message.append("\n\n\n");
}
for (String okId : okIds) {
message.append(okId);
message.append('\n');
}
mav.addObject("idList", message.toString());
return mav;
}
hm.addHistoryItem(historyName, HistoryType.MANUAL, okIds);
return new ModelAndView("redirect:/History");
}
private void validateIds(List<String> ids, List<String> okIds,
List<String> oldIds, List<String> ambiguousIds, List<String> badIds) {
for (String id : ids) {
String realId;
if ((realId = validatePrimaryId(id))!= null) {
okIds.add(realId);
logger.error("Found '"+realId+"'");
continue;
}
if (validateSecondaryId(id, okIds, oldIds, ambiguousIds)) {
continue;
}
logger.error("Missed '"+id+"'");
badIds.add(id);
}
}
private boolean validateSecondaryId(String id, List<String> okIds, List<String> oldIds, List<String> ambiguousIds) {
// First check previous systematic ids
List<Feature> lf = sequenceDao.getFeaturesByPreviousSystematicId(id);
if (lf.size() > 1) {
ambiguousIds.add(id);
return true;
}
if (lf.size() == 1) {
okIds.add(lf.get(0).getUniqueName());
return true;
}
// If no match, try all current names
lf = sequenceDao.getFeaturesByAnyCurrentName(id);
if (lf.size() == 0) {
return false;
}
if (lf.size() > 1) {
ambiguousIds.add(id);
return true;
}
okIds.add(id);
return true;
}
private String validatePrimaryId(String id) {
Feature f = sequenceDao.getFeatureByUniqueName(id, Feature.class);
if (f == null) {
return null;
}
if (f instanceof org.gmod.schema.feature.Gene) {
Gene g = (org.gmod.schema.feature.Gene) f;
Transcript t = g.getTranscripts().iterator().next();
return t.getUniqueName();
}
return f.getUniqueName();
}
private void addIds(List<String> ids, String idList) {
String[] lines = idList.split("[\\r]?\\n");
ids.addAll(Arrays.asList(lines));
}
public void setSequenceDao(SequenceDao sequenceDao) {
this.sequenceDao = sequenceDao;
}
public void setHmFactory(HistoryManagerFactory hmFactory) {
this.hmFactory = hmFactory;
}
}