package net.sourceforge.solexatools.webapp.controller;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
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 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;
import com.google.gson.Gson;
import net.sourceforge.seqware.common.util.Log;
/**
* <p>
* StudyReportTableController class.
* </p>
*
* @author boconnor
* @version $Id: $Id
*/
@SuppressWarnings("deprecation")
public class StudyReportTableController 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>SORT_ORDER_ASC="asc"</code> */
public static final String SORT_ORDER_ASC = "asc";
/** Constant <code>SORT_ORDER_DESC="desc"</code> */
public static final String SORT_ORDER_DESC = "desc";
/** Constant <code>PAGE_NUM="page"</code> */
public static final String PAGE_NUM = "page";
/** Constant <code>ROWS_PER_PAGE="rp"</code> */
public static final String ROWS_PER_PAGE = "rp";
/** Constant <code>TABLE_SEL="tablesel"</code> */
public static final String TABLE_SEL = "tablesel";
/** Constant <code>TABLE_MODEL="tablemodel"</code> */
public static final String TABLE_MODEL = "tablemodel";
// Sortfields
/** Constant <code>FILE_SAMPLE="f_sample"</code> */
public static final String FILE_SAMPLE = "f_sample";
/** Constant <code>FILE_TISSUE="f_tissue"</code> */
public static final String FILE_TISSUE = "f_tissue";
/** Constant <code>FILE_LIBRARY="f_library"</code> */
public static final String FILE_LIBRARY = "f_library";
/** Constant <code>FILE_TEMPLATE="f_template"</code> */
public static final String FILE_TEMPLATE = "f_template";
/** Constant <code>FILE_IUS="f_ius"</code> */
public static final String FILE_IUS = "f_ius";
/** Constant <code>FILE_LANE="f_lane"</code> */
public static final String FILE_LANE = "f_lane";
/** Constant <code>FILE_FILE="f_file"</code> */
public static final String FILE_FILE = "f_file";
// New sort fields
/** Constant <code>FILE_STUDY_TITLE="f_study_title"</code> */
public static final String FILE_STUDY_TITLE = "f_study_title";
/** Constant <code>FILE_STUDY_SWID="f_study_swid"</code> */
public static final String FILE_STUDY_SWID = "f_study_swid";
/** Constant <code>FILE_EXPERIMENT_NAME="f_exp_name"</code> */
public static final String FILE_EXPERIMENT_NAME = "f_exp_name";
/** Constant <code>FILE_EXPERIMENT_SWID="f_exp_swid"</code> */
public static final String FILE_EXPERIMENT_SWID = "f_exp_swid";
/** Constant <code>FILE_PARENT_SAMPLE_NAME="f_sample_name"</code> */
public static final String FILE_PARENT_SAMPLE_NAME = "f_sample_name";
/** Constant <code>FILE_PARENT_SAMPLE_SWID="f_sample_swid"</code> */
public static final String FILE_PARENT_SAMPLE_SWID = "f_sample_swid";
/** Constant <code>FILE_SAMPLE_NAME="f_child_sample_name"</code> */
public static final String FILE_SAMPLE_NAME = "f_child_sample_name";
/** Constant <code>FILE_SAMPLE_SWID="f_child_sample_swid"</code> */
public static final String FILE_SAMPLE_SWID = "f_child_sample_swid";
/** Constant <code>FILE_SEQUENCER_NAME="f_seqrun_name"</code> */
public static final String FILE_SEQUENCER_NAME = "f_seqrun_name";
/** Constant <code>FILE_SEQUENCER_SWID="f_seqrun_swid"</code> */
public static final String FILE_SEQUENCER_SWID = "f_seqrun_swid";
/** Constant <code>FILE_LANE_NAME="f_lane_name"</code> */
public static final String FILE_LANE_NAME = "f_lane_name";
/** Constant <code>FILE_LANE_NUMBER="f_lane_num"</code> */
public static final String FILE_LANE_NUMBER = "f_lane_num";
/** Constant <code>FILE_LANE_SWID="f_lane_swid"</code> */
public static final String FILE_LANE_SWID = "f_lane_swid";
/** Constant <code>FILE_IUS_TAG="f_ius_tag"</code> */
public static final String FILE_IUS_TAG = "f_ius_tag";
/** Constant <code>FILE_IUS_SWID="f_ius_swid"</code> */
public static final String FILE_IUS_SWID = "f_ius_swid";
/** Constant <code>FILE_WF_NAME="f_wf_name"</code> */
public static final String FILE_WF_NAME = "f_wf_name";
/** Constant <code>FILE_WF_VERSION="f_wf_version"</code> */
public static final String FILE_WF_VERSION = "f_wf_version";
/** Constant <code>FILE_WF_SWID="f_wf_swid"</code> */
public static final String FILE_WF_SWID = "f_wf_swid";
/** Constant <code>FILE_RUN_NAME="f_run_name"</code> */
public static final String FILE_RUN_NAME = "f_run_name";
/** Constant <code>FILE_RUN_SWID="f_run_swid"</code> */
public static final String FILE_RUN_SWID = "f_run_swid";
/** Constant <code>FILE_PROCESSING_ALG="f_processing_alg"</code> */
public static final String FILE_PROCESSING_ALG = "f_processing_alg";
/** Constant <code>FILE_PROCESSING_SWID="f_processing_swid"</code> */
public static final String FILE_PROCESSING_SWID = "f_processing_swid";
/** Constant <code>FILE_META_TYPE="f_file_meta"</code> */
public static final String FILE_META_TYPE = "f_file_meta";
/** Constant <code>FILE_SWID="f_file_swid"</code> */
public static final String FILE_SWID = "f_file_swid";
/** Constant <code>FILE_PATH="f_file_path"</code> */
public static final String FILE_PATH = "f_file_path";
/** Constant <code>SAMPLE_SAMPLE="s_sample"</code> */
public static final String SAMPLE_SAMPLE = "s_sample";
/** Constant <code>SAMPLE_CHILD="s_child"</code> */
public static final String SAMPLE_CHILD = "s_child";
// Services
private StudyService studyService;
private SampleService sampleService;
private FileReportService fileReportService;
private SampleReportService sampleReportService;
// Statuses
private static final String NOT_STARTED = "notstarted";
// Table model data
private static final int WIDTH = 100;
// Various data
private List<Workflow> workflows;
private Flexigrid fileFlexigrid;
private Flexigrid sampleFlexigrid;
/**
* <p>
* Constructor for StudyReportTableController.
* </p>
*/
public StudyReportTableController() {
super();
}
/**
* {@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 null;
String studyID = request.getParameter(STUDY_ID);
String tableSel = request.getParameter(TABLE_SEL);
String tableModel = request.getParameter(TABLE_MODEL);
String sortName = request.getParameter(SORT_NAME);
String sortOrder = request.getParameter(SORT_ORDER);
String pageStr = request.getParameter(PAGE_NUM);
String rowsPagesStr = request.getParameter(ROWS_PER_PAGE);
Integer studyId = null;
int page = 1;
int rowsPages = 15;
try {
studyId = Integer.parseInt(studyID);
page = Integer.parseInt(pageStr);
rowsPages = Integer.parseInt(rowsPagesStr);
} catch (NumberFormatException e) {
e.printStackTrace();
}
// Study was not int??
if (studyId == null) {
return null;
}
Study study = studyService.findByID(studyId);
if (study == null) {
return 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");
if (tableModel != null) {
// Clear all the data
fileFlexigrid = null;
sampleFlexigrid = null;
workflows = sampleReportService.getWorkflowsForStudy(study);
Collections.sort(workflows);
// Get Model for sample
String json = createSampleTableModelJson(study);
response.getWriter().write(json);
response.flushBuffer();
return null;
}
if ("sample".equals(tableSel)) {
String json = createSampleTableJson(study, page, rowsPages, sortName, sortOrder);
response.getWriter().write(json);
response.flushBuffer();
}
if ("file".equals(tableSel)) {
String json = createFileTableJson(study, page, rowsPages, sortName, sortOrder);
response.getWriter().write(json);
response.flushBuffer();
}
return null;
}
private String createSampleTableModelJson(Study study) {
List<Flexigrid.ColumnModel> model = new LinkedList<>();
model.add(new Flexigrid.ColumnModel("Sample", "s_sample", WIDTH, true, "left"));
model.add(new Flexigrid.ColumnModel("Child Sample", "s_child", WIDTH, true, "left"));
for (Workflow workflow : this.workflows) {
Flexigrid.ColumnModel column = new Flexigrid.ColumnModel(workflow.getName() + " " + workflow.getVersion(), "wf_"
+ workflow.getSwAccession(), WIDTH, false, "left");
model.add(column);
}
model.add(new Flexigrid.ColumnModel("Overall", "overall", WIDTH, false, "left"));
// Convert to Flexigrid JSON
Gson gson = new Gson();
String json = gson.toJson(model);
return json;
}
private String createFileTableJson(Study study, int page, int rp, String sortName, String sortOrder) {
fileFlexigrid = createFileFlexigrid(study, page, rp, sortName, sortOrder);
fileFlexigrid.setPage(page);
List<Cells> rowsAll = fileFlexigrid.getRows();
fileFlexigrid.setRows(rowsAll);
// Convert to Flexigrid JSON
Gson gson = new Gson();
String json = gson.toJson(fileFlexigrid);
fileFlexigrid.setRows(rowsAll);
return json;
}
private Flexigrid createFileFlexigrid(Study study, int page, int rp, String sortName, String sortOrder) {
// long start = System.nanoTime();
String sortField = "study.studyId";
if (!"undefined".equals(sortOrder)) {
if (FILE_STUDY_TITLE.equals(sortName)) {
sortField = "study.title";
}
if (FILE_STUDY_SWID.equals(sortName)) {
sortField = "study.swAccession";
}
if (FILE_EXPERIMENT_NAME.equals(sortName)) {
sortField = "experiment.name";
}
if (FILE_EXPERIMENT_SWID.equals(sortName)) {
sortField = "experiment.swAccession";
}
if (FILE_PARENT_SAMPLE_NAME.equals(sortName)) {
sortField = "sample.name";
}
if (FILE_PARENT_SAMPLE_SWID.equals(sortName)) {
sortField = "sample.swAccession";
}
if (FILE_SAMPLE_NAME.equals(sortName)) {
sortField = "childSample.name";
}
if (FILE_SAMPLE_SWID.equals(sortName)) {
sortField = "childSample.swAccession";
}
if (FILE_SEQUENCER_NAME.equals(sortName)) {
sortField = "lane.sequencerRun.name";
}
if (FILE_SEQUENCER_SWID.equals(sortName)) {
sortField = "lane.sequencerRun.swid";
}
if (FILE_LANE_NAME.equals(sortName)) {
sortField = "lane.name";
}
if (FILE_LANE_NUMBER.equals(sortName)) {
sortField = "lane.laneIndex";
}
if (FILE_LANE_SWID.equals(sortName)) {
sortField = "lane.swAccession";
}
if (FILE_IUS_TAG.equals(sortName)) {
sortField = "ius.tag";
}
if (FILE_IUS_SWID.equals(sortName)) {
sortField = "ius.swAccession";
}
if (FILE_WF_NAME.equals(sortName)) {
sortField = "processing.workflowRun.workflow.name";
}
if (FILE_WF_SWID.equals(sortName)) {
sortField = "processing.workflowRun.workflow.swAccession";
}
if (FILE_WF_VERSION.equals(sortName)) {
sortField = "processing.workflowRun.workflow.version";
}
if (FILE_RUN_NAME.equals(sortName)) {
sortField = "processing.workflowRun.name";
}
if (FILE_RUN_SWID.equals(sortName)) {
sortField = "processing.workflowRun.swAccession";
}
if (FILE_PROCESSING_ALG.equals(sortName)) {
sortField = "processing.algorithm";
}
if (FILE_PROCESSING_SWID.equals(sortName)) {
sortField = "processing.swAccession";
}
if (FILE_META_TYPE.equals(sortName)) {
sortField = "file.metaType";
}
if (FILE_SWID.equals(sortName)) {
sortField = "file.swAccession";
}
if (FILE_PATH.equals(sortName)) {
sortField = "file.filePath";
}
}
if (!sortOrder.equals("asc") && !sortOrder.equals("desc")) {
sortOrder = "asc";
}
List<FileReportRow> rows = fileReportService.getReportForStudy(study, sortField, sortOrder, (page - 1) * rp, rp);
Flexigrid flexigrid = new Flexigrid(0, 0);
int total = fileReportService.countOfRows(study);
for (FileReportRow row : rows) {
List<String> cellsModel = new ArrayList<>();
// The model is
// Study Title\tStudy SWID\tExperiment Name\tExperiment SWID\tParent
// Sample Name\t" +
// "Parent Sample SWID | Parent Sample Attributes |" +
// "Sample Name | Sample SWID | Sample Attributes |" +
// "Sequencer Run Name | Sequencer Run SWID |" +
// "Lane Name | Lane Number | Lane SWID | Lane Attributes |" +
// "IUS Tag | IUS SWID |" +
// "Workflow Name | Workflow Version | Workflow SWID |" +
// "Workflow Run Name | Workflow Run SWID |" +
// "Processing Algorithm | Processing SWID |" +
// "File Meta-Type | File SWID | File Path"
cellsModel.add(wrapSwAccession(row.getStudy().getSwAccession(), row.getStudy().getTitle()));
cellsModel.add(wrapSwAccession(row.getStudy().getSwAccession(), row.getStudy().getSwAccession().toString()));
cellsModel.add(wrapSwAccession(row.getExperiment().getSwAccession(), row.getExperiment().getName()));
cellsModel.add(wrapSwAccession(row.getExperiment().getSwAccession(), row.getExperiment().getSwAccession().toString()));
cellsModel.add(wrapSwAccession(row.getSample().getSwAccession(), row.getSample().getName()));
cellsModel.add(wrapSwAccession(row.getSample().getSwAccession(), row.getSample().getSwAccession().toString()));
StringBuffer attributes = new StringBuffer();
// get all the sample attributes
for (SampleAttribute attribute : row.getSample().getSampleAttributes()) {
attributes.append(attribute.getTag()).append("=").append(attribute.getValue()).append("<br />");
}
cellsModel.add(attributes.toString());
cellsModel.add(wrapSwAccession(row.getChildSample().getSwAccession(), row.getChildSample().getName()));
cellsModel.add(wrapSwAccession(row.getChildSample().getSwAccession(), row.getChildSample().getSwAccession().toString()));
attributes = new StringBuffer();
// get all the child sample attributes
for (SampleAttribute attribute : row.getChildSample().getSampleAttributes()) {
attributes.append(attribute.getTag()).append("=").append(attribute.getValue()).append("<br />");
}
cellsModel.add(attributes.toString());
Lane lane = row.getLane();
SequencerRun sequencerRun = null;
if (lane != null) {
// if there is lane, get appropriate sequencer run for it
sequencerRun = lane.getSequencerRun();
}
if (sequencerRun != null) {
cellsModel.add(wrapSwAccession(sequencerRun.getSwAccession(), sequencerRun.getName()));
cellsModel.add(wrapSwAccession(sequencerRun.getSwAccession(), sequencerRun.getSwAccession().toString()));
} else {
// no sequencer run - skip it
cellsModel.add("");
cellsModel.add("");
}
if (lane != null) {
cellsModel.add(wrapSwAccession(lane.getSwAccession(), lane.getName()));
cellsModel.add(lane.getLaneIndex().toString());
cellsModel.add(wrapSwAccession(lane.getSwAccession(), lane.getSwAccession().toString()));
attributes = new StringBuffer();
// get all the lane attributes
for (LaneAttribute attribute : lane.getLaneAttributes()) {
attributes.append(attribute.getTag()).append("=").append(attribute.getValue()).append("<br />");
}
cellsModel.add(attributes.toString());
} else {
cellsModel.add("");
cellsModel.add("");
cellsModel.add("");
cellsModel.add("");
}
cellsModel.add(wrapSwAccession(row.getIus().getSwAccession(), row.getIus().getTag()));
cellsModel.add(wrapSwAccession(row.getIus().getSwAccession(), row.getIus().getSwAccession().toString()));
Processing processing = row.getProcessing();
Workflow workflow = null;
WorkflowRun run = null;
if (processing != null) {
// try to get processing related workflow run
run = processing.getWorkflowRun();
if (run == null) {
// if no workflow run found, let's try to get workflow run by ancestor
// run id
run = processing.getWorkflowRunByAncestorWorkflowRunId();
}
if (run != null) {
// if run is found, get workflow
workflow = run.getWorkflow();
}
}
if (workflow != null) {
cellsModel.add(workflow.getName());
cellsModel.add(workflow.getVersion());
cellsModel.add(workflow.getSwAccession().toString());
} else {
cellsModel.add("");
cellsModel.add("");
cellsModel.add("");
}
if (run != null) {
cellsModel.add(run.getName());
cellsModel.add(run.getSwAccession().toString());
} else {
cellsModel.add("");
cellsModel.add("");
}
if (processing != null) {
cellsModel.add(processing.getAlgorithm());
cellsModel.add(processing.getSwAccession().toString());
} else {
cellsModel.add("");
cellsModel.add("");
}
cellsModel.add(row.getFile().getMetaType());
cellsModel.add(row.getFile().getSwAccession().toString());
cellsModel.add(wrapSwAccession(row.getFile().getSwAccession(), row.getFile().getFilePath()));
Flexigrid.Cells cells = flexigrid.new Cells(cellsModel);
flexigrid.addRow(cells);
}
flexigrid.setTotal(total);
// long end = System.nanoTime() - start;
// Log.info("Flexigrid FileTable created. Time: " + end / 1e6);
return flexigrid;
}
private String createSampleTableJson(Study study, int page, int rp, String sortName, String sortOrder) {
if (sampleFlexigrid == null) {
sampleFlexigrid = createSampleFlexigrid(study, page);
}
sampleFlexigrid.setPage(page);
List<Cells> rowsAll = sampleFlexigrid.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);
sampleFlexigrid.setRows(pagedCells);
// Convert to Flexigrid JSON
Gson gson = new Gson();
String json = gson.toJson(sampleFlexigrid);
sampleFlexigrid.setRows(rowsAll);
return json;
}
private Flexigrid createSampleFlexigrid(Study study, int page) {
long start = System.nanoTime();
List<Sample> childSamples = sampleReportService.getChildSamples(study);
// Generate Rows
Flexigrid flexigrid = new Flexigrid(childSamples.size(), page);
for (Sample sample : childSamples) {
Sample rootSample = sampleService.getRootSample(sample);
// Fill statuses with row model
List<String> statusesOut = new ArrayList<>();
for (Workflow workflow : this.workflows) {
Status status = sampleReportService.getStatus(study, sample, workflow);
if (status == null) {
statusesOut.add(wrapStatus(Status.notstarted));
} else {
statusesOut.add(wrapStatus(status));
}
}
List<String> cellsModel = new LinkedList<>();
cellsModel.add(wrapSwAccession(rootSample.getSwAccession(), rootSample.getTitle()));
cellsModel.add(wrapSwAccession(sample.getSwAccession(), rootSample.getSampleId() != sample.getSampleId() ? sample.getTitle()
: "no child"));
cellsModel.addAll(statusesOut);
cellsModel.add(wrapOverall());
Flexigrid.Cells cells = flexigrid.new Cells(cellsModel);
flexigrid.addRow(cells);
}
long end = System.nanoTime() - start;
Log.info("Flexigrid SampleTable created. Time: " + end / 1e6);
return flexigrid;
}
@SuppressWarnings("unchecked")
private void sortRows(List<Cells> rowsAll, String sortOrder, String sortName) {
int columnPos = 0;
if (FILE_SAMPLE.equals(sortName) || (SAMPLE_SAMPLE.equals(sortName))) {
columnPos = 0;
}
if (FILE_TISSUE.equals(sortName) || (SAMPLE_CHILD.equals(sortName))) {
columnPos = 1;
}
if (FILE_LIBRARY.equals(sortName)) {
columnPos = 2;
}
if (FILE_TEMPLATE.equals(sortName)) {
columnPos = 3;
}
if (FILE_IUS.equals(sortName)) {
columnPos = 4;
}
if (FILE_LANE.equals(sortName)) {
columnPos = 5;
}
if (FILE_FILE.equals(sortName)) {
columnPos = 6;
}
@SuppressWarnings("rawtypes")
Comparator comparator = null;
if (SORT_ORDER_ASC.equals(sortOrder)) {
comparator = new CellsComparator(columnPos);
}
if (SORT_ORDER_DESC.equals(sortOrder)) {
comparator = Collections.reverseOrder(new CellsComparator(columnPos));
}
Collections.sort(rowsAll, comparator);
}
@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));
}
};
private String wrapSwAccession(Integer swId, String label) {
return "<div class=\"label\">" + label + "</div>" + "<div class=\"sw\" swid=\"" + swId + "\"></div>";
}
private String wrapStatus(Status status) {
return "<div class=\"status\" >" + status + "</div>";
}
private String wrapOverall() {
return "<div class=\"overall\" />";
}
/**
* <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;
}
}