package net.sourceforge.solexatools.webapp.controller;
import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import net.sourceforge.seqware.common.business.StudyService;
import net.sourceforge.seqware.common.model.Experiment;
import net.sourceforge.seqware.common.model.IUS;
import net.sourceforge.seqware.common.model.Lane;
import net.sourceforge.seqware.common.model.Processing;
import net.sourceforge.seqware.common.model.Registration;
import net.sourceforge.seqware.common.model.Sample;
import net.sourceforge.seqware.common.model.Study;
import net.sourceforge.seqware.common.model.WorkflowRun;
import net.sourceforge.seqware.common.util.Log;
import net.sourceforge.solexatools.Security;
import net.sourceforge.solexatools.util.PaginationUtil;
import net.sourceforge.solexatools.webapp.metamodel.Flexigrid;
import net.sourceforge.solexatools.webapp.metamodel.Flexigrid.Cells;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.BaseCommandController;
/**
*
* TODO:
*
* * it would be best if this controller would actually render the workflow_runs too. That will require paging to work properly in the
* Hibernate layer which VRP never actually did (no wonder the app is so slow!).
*
* RegistrationSetupController
*
* @author boconnor
* @version $Id: $Id
*/
public class StudyTableControllerDetails extends BaseCommandController {
private StudyService studyService;
private Flexigrid flexigrid;
/**
* <p>
* Constructor for AnalisysListController.
* </p>
*/
public StudyTableControllerDetails() {
super();
setSupportedMethods(new String[] { METHOD_GET, METHOD_POST });
}
/**
* {@inheritDoc}
*
* @return
* @throws java.lang.Exception
*/
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
// Registration registration = Security.requireRegistration(request, response);
Registration registration = Security.getRegistration(request);
if (registration == null) {
return null;
}
String tableSel = request.getParameter("tablesel");
String tableModel = request.getParameter("tablemodel");
String sortName = request.getParameter("sortname");
String sortOrder = request.getParameter("sortorder");
String pageStr = request.getParameter("page");
String rowsPagesStr = request.getParameter("rp");
String filter = request.getParameter("filter");
String qtype = request.getParameter("qtype");
String query = request.getParameter("query");
int page = 1;
int rowsPages = 15;
try {
page = Integer.parseInt(pageStr);
rowsPages = Integer.parseInt(rowsPagesStr);
} catch (NumberFormatException e) {
e.printStackTrace();
}
if (studyService != null) {
// This workflows. Statuses are generated for them.
// We sort them to have the same model as we have
// while generating table model
response.setContentType("application/json");
List<Study> studies = null;
String searchQuery = "";
if (qtype != null && !"".equals(qtype) && query != null && !"".equals(query)) {
searchQuery = " and cast(wr." + qtype + " as string) like '%" + query + "%'";
}
// LEFT OFF HERE!!!
studies = studyService.list(registration);
String json = createStudyTableJson(studies, page, rowsPages, sortName, sortOrder);
response.getWriter().write(json);
response.flushBuffer();
}
return null;
}
private String createStudyTableJson(List<Study> studies, int page, int rp, String sortName, String sortOrder) {
// FIXME:
flexigrid = createStudyFlexigrid(studies, page);
if (flexigrid == null) {
// flexigrid = createSampleFlexigrid(workflowRuns, page);
}
flexigrid.setPage(page);
List<Cells> rowsAll = flexigrid.getRows();
if (!"undefined".equals(sortOrder)) {
// long start = System.nanoTime();
sortRows(rowsAll, sortOrder, sortName);
// long end = System.nanoTime() - start;
// Log.info("Sorting SampleTable Time: " + end / 1e6);
}
@SuppressWarnings("unchecked")
List<Cells> pagedCells = PaginationUtil.subList(page - 1, rp, rowsAll);
flexigrid.setRows(pagedCells);
// Convert to Flexigrid JSON
Gson gson = new Gson();
String json = gson.toJson(flexigrid);
flexigrid.setRows(rowsAll);
return json;
}
private Flexigrid createStudyFlexigrid(List<Study> studies, int page) {
Flexigrid flexigrid = new Flexigrid(studies.size(), page);
for (Study study : studies) {
for (Experiment exp : study.getExperiments()) {
for (Sample sample : exp.getSamples()) {
ArrayList<String> sampleStrs = new ArrayList<>();
getSampleStrings(sample.getTitle(), sample, sampleStrs);
for (String sampleStr : sampleStrs) {
List<String> cellsModel = new LinkedList<>();
cellsModel.add(study.getTitle());
cellsModel.add(study.getCreateTimestamp().toString());
cellsModel.add(exp.getTitle());
cellsModel.add(sampleStr);
cellsModel.add("workflows");
Flexigrid.Cells cells = flexigrid.new Cells(cellsModel);
flexigrid.addRow(cells);
}
/*
* // not doing this right now HashMap<WorkflowRun, String> workflows = new HashMap<WorkflowRun, String>();
* getWorkflowRuns(sample, workflows, "");
*
* for (WorkflowRun workflow : workflows.keySet()) {
*
* List<String> cellsModel = new LinkedList<String>();
*
* cellsModel.add(study.getTitle()); cellsModel.add(study.getCreateTimestamp().toString());
* cellsModel.add(exp.getTitle());
*
* String sampleStr = workflows.get(workflow); cellsModel.add(sampleStr);
* cellsModel.add(workflow.getWorkflow().getName()+" "+workflow.getWorkflow().getVersion());
*
* Flexigrid.Cells cells = flexigrid.new Cells(cellsModel); flexigrid.addRow(cells); }
*/
}
}
}
return flexigrid;
}
/**
* This finds all the possible paths to leaf sample nodes.
*
* @param currString
* @param s
* @param sampleStrs
*/
private void getSampleStrings(String currString, Sample s, ArrayList<String> sampleStrs) {
if (s.getChildren() == null || s.getChildren().isEmpty()) {
sampleStrs.add(currString);
} else {
for (Sample s2 : s.getChildren()) {
getSampleStrings(currString + " / " + s2.getTitle(), s2, sampleStrs);
}
}
}
private void getWorkflowRuns(Sample sample, HashMap<WorkflowRun, String> workflows, String sampleString) {
String sampleStr = sampleString + " / " + sample.getTitle();
// find any workflows
List<WorkflowRun> workflowList = findSampleWorkflowRuns(sample);
for (WorkflowRun w : workflowList) {
workflows.put(w, sampleStr);
}
/*
* for (Sample child : sample.getChildren()) { getWorkflowRuns(child, workflows, sampleStr); }
*/
}
private List<WorkflowRun> findSampleWorkflowRuns(Sample sample) {
ArrayList<WorkflowRun> wr = new ArrayList<>();
HashMap<String, WorkflowRun> pwr = new HashMap<>();
findProcessingWorkflowRun(sample.getProcessings(), pwr);
// the hash should be unique, now dump everything into array list for return
for (WorkflowRun cwr : pwr.values()) {
wr.add(cwr);
}
return (wr);
}
private void findProcessingWorkflowRun(Set<Processing> processings, HashMap<String, WorkflowRun> pwr) {
for (Processing p : processings) {
WorkflowRun directWr = p.getWorkflowRun();
WorkflowRun ancestorWr = p.getWorkflowRunByAncestorWorkflowRunId();
if (directWr != null) {
pwr.put(directWr.getSwAccession().toString(), directWr);
}
if (ancestorWr != null) {
pwr.put(ancestorWr.getSwAccession().toString(), ancestorWr);
}
Log.stderr(p.getAlgorithm() + " " + p.getSwAccession() + " " + directWr);
// findProcessingWorkflowRun(p.getChildren(), pwr);
}
}
private String sampleToHtml(Set<Sample> samples) {
StringBuilder sb = new StringBuilder();
boolean first = true;
if (samples != null) {
for (Sample s : samples) {
if (!first) {
sb.append(", ");
}
sb.append(s.getTitle()).append(" (SWID:").append(s.getSwAccession()).append(")");
first = false;
}
}
return (sb.toString());
}
private String iUSToHtml(Set<IUS> ius) {
StringBuilder sb = new StringBuilder();
boolean first = true;
if (ius != null) {
for (IUS s : ius) {
if (!first) {
sb.append(", ");
}
sb.append(s.getName()).append(" (SWID:").append(s.getSwAccession()).append(")");
first = false;
}
}
return (sb.toString());
}
private String laneToHtml(Set<Lane> lanes) {
StringBuilder sb = new StringBuilder();
boolean first = true;
if (lanes != null) {
for (Lane s : lanes) {
if (!first) {
sb.append(", ");
}
sb.append(s.getName()).append(" (SWID:").append(s.getSwAccession()).append(")");
first = false;
}
}
return (sb.toString());
}
private void sortRows(List<Cells> rowsAll, String sortOrder, String sortName) {
int columnPos = 0;
if (null != sortName) switch (sortName) {
case "date":
columnPos = 0;
break;
case "status":
columnPos = 1;
break;
case "swid":
columnPos = 2;
break;
}
@SuppressWarnings("rawtypes")
Comparator comparator = null;
if (null != sortOrder) switch (sortOrder) {
case "asc":
comparator = new StudyTableControllerDetails.CellsComparator(columnPos);
break;
case "desc":
comparator = Collections.reverseOrder(new StudyTableControllerDetails.CellsComparator(columnPos));
break;
}
Collections.sort(rowsAll, comparator);
}
private void initSortingTreeAttr(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session.getAttribute("ascMyListAnalysis") == null) {
session.setAttribute("ascMyListAnalysis", true);
session.setAttribute("ascMySharedAnalysises", true);
session.setAttribute("ascAnalysisesSharedWithMe", true);
session.setAttribute("ascMyRunningListAnalysis", true);
}
}
/**
* <p>
* Getter for the field <code>studyService</code>.
* </p>
*
* @return a {@link net.sourceforge.seqware.common.business.StudyService} object.
*/
public StudyService getStudyService() {
return studyService;
}
/**
* <p>
* Setter for the field <code>studyService</code>.
* </p>
*
* @param studyService
* a {@link net.sourceforge.seqware.common.business.StudyService} object.
*/
public void setStudyService(StudyService studyService) {
this.studyService = studyService;
}
@SuppressWarnings({ "rawtypes" })
private class CellsComparator implements Comparator {
private int pos;
public CellsComparator(int pos) {
this.pos = pos;
}
@Override
public int compare(Object o1, Object o2) {
return (((Cells) o1).getCell().get(pos)).compareToIgnoreCase(((Cells) o2).getCell().get(pos));
}
};
}