package net.sourceforge.solexatools.webapp.controller;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sourceforge.seqware.common.business.FileReportService;
import net.sourceforge.seqware.common.business.SampleReportService;
import net.sourceforge.seqware.common.business.SampleReportService.Status;
import net.sourceforge.seqware.common.business.SampleService;
import net.sourceforge.seqware.common.business.StudyService;
import net.sourceforge.seqware.common.model.FileReportRow;
import net.sourceforge.seqware.common.model.Lane;
import net.sourceforge.seqware.common.model.LaneAttribute;
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.SampleAttribute;
import net.sourceforge.seqware.common.model.SequencerRun;
import net.sourceforge.seqware.common.model.Study;
import net.sourceforge.seqware.common.model.Workflow;
import net.sourceforge.seqware.common.model.WorkflowRun;
import net.sourceforge.solexatools.Security;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.BaseCommandController;
/**
* <p>
* StudyReportBoxController class.
* </p>
*
* @author boconnor
* @version $Id: $Id
*/
@SuppressWarnings("deprecation")
public class StudyReportBoxController extends BaseCommandController {
/** Constant <code>STUDY_ID="study_id"</code> */
public static final String STUDY_ID = "study_id";
/** Constant <code>JSON="json"</code> */
public static final String JSON = "json";
/** Constant <code>SORT_NAME="sortname"</code> */
public static final String SORT_NAME = "sortname";
/** Constant <code>SORT_ORDER="sortorder"</code> */
public static final String SORT_ORDER = "sortorder";
/** Constant <code>CSV_TYPE="csvtype"</code> */
public static final String CSV_TYPE = "csvtype";
/** Constant <code>CHECK="check"</code> */
public static final String CHECK = "check";
private StudyService studyService;
private SampleService sampleService;
private FileReportService fileReportService;
private SampleReportService sampleReportService;
private boolean isSampleDownloaded;
private boolean isFileDownloaded;
/**
* <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;
}
/**
* <p>
* Setter for the field <code>sampleService</code>.
* </p>
*
* @param service
* a {@link net.sourceforge.seqware.common.business.SampleService} object.
*/
public void setSampleService(SampleService service) {
this.sampleService = service;
}
/**
* <p>
* Setter for the field <code>fileReportService</code>.
* </p>
*
* @param service
* a {@link net.sourceforge.seqware.common.business.FileReportService} object.
*/
public void setFileReportService(FileReportService service) {
this.fileReportService = service;
}
/**
* <p>
* Setter for the field <code>sampleReportService</code>.
* </p>
*
* @param service
* a {@link net.sourceforge.seqware.common.business.SampleReportService} object.
*/
public void setSampleReportService(SampleReportService service) {
this.sampleReportService = service;
}
/**
* {@inheritDoc}
*
* @return
* @throws java.lang.Exception
*/
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
Registration registration = Security.getRegistration(request);
if (registration == null) {
return new ModelAndView("redirect:/login.htm");
}
boolean hasError = false;
List<String> errMsgs = new ArrayList<>();
// Get StudyId, for which Report is generated
String idStr = request.getParameter(STUDY_ID);
String csvtype = request.getParameter(CSV_TYPE);
String check = request.getParameter(CHECK);
int studyId = 0;
try {
studyId = Integer.parseInt(idStr);
} catch (NumberFormatException e) {
e.printStackTrace();
hasError = true;
errMsgs.add(e.getMessage());
}
Study currentStudy = studyService.findByID(studyId);
ModelAndView modelAndView = new ModelAndView("ReportStudy");
if (!hasError || check != null) {
if (csvtype != null) {
// Sample CSV
if (csvtype.equals("sample")) {
if (check != null) {
response.getWriter().write(Boolean.toString(isSampleDownloaded));
// reset
if (isSampleDownloaded) {
isSampleDownloaded = false;
}
response.flushBuffer();
return null;
}
StringBuilder sb = new StringBuilder();
sb.append("Sample\tChild Sample\t");
List<Workflow> workflows = sampleReportService.getWorkflowsForStudy(currentStudy);
for (Workflow wf : workflows) {
sb.append(wf.getName()).append("\t");
}
sb.append("\n");
List<Sample> childSamples = sampleReportService.getChildSamples(currentStudy);
// Generate Rows
for (Sample sample : childSamples) {
Sample rootSample = sampleService.getRootSample(sample);
sb.append(rootSample.getTitle()).append("\t");
sb.append(rootSample.getSampleId() != sample.getSampleId() ? sample.getTitle() + "\t"
: "no child" + "\t");
for (Workflow workflow : workflows) {
Status status = sampleReportService.getStatus(currentStudy, sample, workflow);
if (status == null) {
sb.append(Status.notstarted).append("\t");
} else {
sb.append(status).append("\t");
}
}
sb.append("\n");
}
response.setContentType("text/csv");
response.addHeader("Content-Disposition", "attachment;filename=sampleReport.csv");
response.getWriter().write(sb.toString());
isSampleDownloaded = true;
response.flushBuffer();
return null;
}
// File CSV
if (csvtype.equals("file")) {
if (check != null) {
response.getWriter().write(Boolean.toString(isFileDownloaded));
// reset
if (isFileDownloaded) {
isFileDownloaded = false;
}
response.flushBuffer();
return null;
}
StringBuilder sb = new StringBuilder();
sb.append("Study Title\tStudy SWID\tExperiment Name\tExperiment SWID\tParent Sample Name\t"
+ "Parent Sample SWID\tParent Sample Attributes\t" + "Sample Name\tSample SWID\tSample Attributes\t"
+ "Sequencer Run Name\tSequencer Run SWID\t" + "Lane Name\tLane Number\tLane SWID\tLane Attributes\t"
+ "IUS Tag\tIUS SWID\t" + "Workflow Name\tWorkflow Version\tWorkflow SWID\t"
+ "Workflow Run Name\t Workflow Run SWID\t" + "Processing Algorithm\tProcessing SWID\t"
+ "File Meta-Type\tFile SWID\tFile Path\n");
List<FileReportRow> rows = fileReportService.getReportForStudy(currentStudy);
for (FileReportRow row : rows) {
sb.append(row.getStudy().getTitle()).append("\t");
sb.append(row.getStudy().getSwAccession()).append("\t");
sb.append(row.getExperiment().getName()).append("\t");
sb.append(row.getExperiment().getSwAccession()).append("\t");
sb.append(row.getSample().getName()).append("\t");
sb.append(row.getSample().getSwAccession()).append("\t");
StringBuffer attributes = new StringBuffer();
for (SampleAttribute attribute : row.getSample().getSampleAttributes()) {
attributes.append(attribute.getTag()).append("=").append(attribute.getValue()).append(" ");
}
sb.append(attributes.toString()).append("\t");
sb.append(row.getChildSample().getName()).append("\t");
sb.append(row.getChildSample().getSwAccession()).append("\t");
attributes = new StringBuffer();
for (SampleAttribute attribute : row.getChildSample().getSampleAttributes()) {
attributes.append(attribute.getTag()).append("=").append(attribute.getValue()).append(" ");
}
sb.append(attributes.toString()).append("\t");
Lane lane = row.getLane();
SequencerRun sequencerRun = null;
if (lane != null) {
sequencerRun = lane.getSequencerRun();
}
if (sequencerRun != null) {
sb.append(sequencerRun.getName()).append("\t");
sb.append(sequencerRun.getSwAccession()).append("\t");
} else {
sb.append(" \t");
sb.append(" \t");
}
if (lane != null) {
sb.append(lane.getName()).append("\t");
sb.append(lane.getLaneIndex()).append("\t");
sb.append(lane.getSwAccession()).append("\t");
attributes = new StringBuffer();
for (LaneAttribute attribute : lane.getLaneAttributes()) {
attributes.append(attribute.getTag()).append("=").append(attribute.getValue()).append(" ");
}
sb.append(attributes).append("\t");
} else {
sb.append(" \t");
sb.append(" \t");
sb.append(" \t");
sb.append(" \t");
}
sb.append(row.getIus().getTag()).append("\t");
sb.append(row.getIus().getSwAccession()).append("\t");
Processing processing = row.getProcessing();
WorkflowRun run = null;
Workflow workflow = null;
if (processing != null) {
run = processing.getWorkflowRun();
if (run == null) {
run = processing.getWorkflowRunByAncestorWorkflowRunId();
}
}
if (run != null) {
workflow = run.getWorkflow();
}
if (workflow != null) {
sb.append(workflow.getName()).append("\t");
sb.append(workflow.getVersion()).append("\t");
sb.append(workflow.getSwAccession()).append("\t");
} else {
sb.append(" \t");
sb.append(" \t");
sb.append(" \t");
}
if (run != null) {
sb.append(run.getName()).append("\t");
sb.append(run.getSwAccession()).append("\t");
} else {
sb.append(" \t");
sb.append(" \t");
}
if (processing != null) {
sb.append(processing.getAlgorithm()).append("\t");
sb.append(processing.getSwAccession()).append("\t");
} else {
sb.append(" \t");
sb.append(" \t");
}
sb.append(row.getFile().getMetaType()).append("\t");
sb.append(row.getFile().getSwAccession()).append("\t");
sb.append(row.getFile().getFilePath()).append("\t");
sb.append("\n");
}
response.setContentType("text/csv");
response.addHeader("Content-Disposition", "attachment;filename=fileReport.csv");
response.getWriter().write(sb.toString());
isFileDownloaded = true;
response.flushBuffer();
return null;
}
}
if (currentStudy != null) {
ModelAndView mv = new ModelAndView("ReportStudy");
createChartModel(currentStudy, mv);
mv.addObject("study_id", studyId);
return mv;
}
}
return modelAndView;
}
private void createChartModel(Study study, ModelAndView modelAndView) {
createOverallChart(modelAndView, study);
createWorkflowCharts(modelAndView, study);
}
private void createWorkflowCharts(ModelAndView modelAndView, Study study) {
Map<Workflow, String> workflowCharts = new HashMap<>();
List<Workflow> usedWorkflows = sampleReportService.getWorkflowsForStudy(study);
for (Workflow workflow : usedWorkflows) {
List<Status> statuses = sampleReportService.getStatusesForWorkflow(study, workflow);
Map<Status, Integer> statusCount = new LinkedHashMap<>();
statusCount.put(Status.failed, 0);
statusCount.put(Status.pending, 0);
statusCount.put(Status.running, 0);
statusCount.put(Status.notstarted, 0);
statusCount.put(Status.completed, 0);
for (Status status : statuses) {
int count = sampleReportService.countOfStatus(study, workflow, status);
statusCount.put(status, count);
}
int current = 0;
StringBuilder out = new StringBuilder();
for (Status status : statusCount.keySet()) {
current++;
int count = statusCount.get(status);
String sStatus = status.toString();
if (Status.notstarted == status) {
sStatus = "not started";
}
out.append("['").append(sStatus).append("',").append(count).append("]");
if (current != statusCount.keySet().size()) {
out.append(",");
}
}
workflowCharts.put(workflow, out.toString());
}
modelAndView.addObject("names", usedWorkflows);
modelAndView.addObject("chartData", workflowCharts);
}
private void createOverallChart(ModelAndView modelAndView, Study study) {
List<Status> statuses = sampleReportService.getStatusesForStudy(study);
Map<Status, Integer> statusCount = new LinkedHashMap<>();
statusCount.put(Status.failed, 0);
statusCount.put(Status.pending, 0);
statusCount.put(Status.running, 0);
statusCount.put(Status.notstarted, 0);
statusCount.put(Status.completed, 0);
for (Status status : statuses) {
int count = sampleReportService.countOfStatus(study, status);
statusCount.put(status, count);
}
int current = 0;
StringBuilder out = new StringBuilder();
for (Status status : statusCount.keySet()) {
current++;
int count = statusCount.get(status);
String sStatus = status.toString();
if (Status.notstarted == status) {
sStatus = "not started";
}
out.append("['").append(sStatus).append("',").append(count).append("]");
if (current != statusCount.keySet().size()) {
out.append(",");
}
}
modelAndView.addObject("overallChartData", out.toString());
}
}