/*
* Copyright (c) 2012. The Genome Analysis Centre, Norwich, UK
* MISO project contacts: Robert Davey, Mario Caccamo @ TGAC
* *********************************************************************
*
* This file is part of MISO.
*
* MISO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MISO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MISO. If not, see <http://www.gnu.org/licenses/>.
*
* *********************************************************************
*/
package uk.ac.bbsrc.tgac.miso.spring.ajax;
import com.eaglegenomics.simlims.core.manager.SecurityManager;
import com.eaglegenomics.simlims.core.User;
import org.springframework.security.core.context.SecurityContextHolder;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sourceforge.fluxion.ajax.Ajaxified;
import net.sourceforge.fluxion.ajax.util.JSONUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import uk.ac.bbsrc.tgac.miso.core.data.*;
import uk.ac.bbsrc.tgac.miso.core.data.impl.LibraryDilution;
import uk.ac.bbsrc.tgac.miso.core.data.impl.PoolImpl;
import uk.ac.bbsrc.tgac.miso.core.data.impl.StudyImpl;
import uk.ac.bbsrc.tgac.miso.core.data.type.PlatformType;
import uk.ac.bbsrc.tgac.miso.core.exception.MalformedDilutionException;
import uk.ac.bbsrc.tgac.miso.core.exception.MalformedPoolException;
import uk.ac.bbsrc.tgac.miso.core.exception.MalformedPoolQcException;
import uk.ac.bbsrc.tgac.miso.core.factory.DataObjectFactory;
import uk.ac.bbsrc.tgac.miso.core.manager.RequestManager;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* Created by IntelliJ IDEA.
* User: bianx
* Date: 18-Aug-2011
* Time: 16:44:32
* To change this template use File | Settings | File Templates.
*/
@Ajaxified
public class PoolWizardControllerHelperService {
protected static final Logger log = LoggerFactory.getLogger(PoolControllerHelperService.class);
@Autowired
private SecurityManager securityManager;
@Autowired
private RequestManager requestManager;
@Autowired
private DataObjectFactory dataObjectFactory;
public JSONObject addPool(HttpSession session, JSONObject json) {
JSONObject response = new JSONObject();
DateFormat df = new SimpleDateFormat("dd/mm/yyyy");
String alias = json.getString("alias");
Double concentration = json.getDouble("concentration");
PlatformType platformType = PlatformType.get(json.getString("platformType"));
StringBuilder sb = new StringBuilder();
List<Integer> ids = JSONArray.fromObject(json.getString("dilutions"));
List<PoolQC> pqcs = new ArrayList<PoolQC>();
JSONArray qcs = JSONArray.fromObject(json.get("qcs"));
for (JSONObject q : (Iterable<JSONObject>) qcs) {
PoolQC s = dataObjectFactory.getPoolQC();
try {
s.setResults(Double.valueOf(q.getString("poolQcResults")));
s.setQcCreator(SecurityContextHolder.getContext().getAuthentication().getName());
s.setQcDate(df.parse(q.getString("poolQcDate")));
s.setQcType(requestManager.getPoolQcTypeById(q.getLong("poolQcType")));
}
catch (IOException e) {
e.printStackTrace();
return JSONUtils.SimpleJSONError("Failed: " + e.getMessage());
}
catch (ParseException e) {
e.printStackTrace();
return JSONUtils.SimpleJSONError("Failed: " + e.getMessage());
}
pqcs.add(s);
}
if (ids.size() > 0 && platformType != null && concentration != null) {
try {
User user = securityManager.getUserByLoginName(SecurityContextHolder.getContext().getAuthentication().getName());
List<Dilution> dils = new ArrayList<Dilution>();
for (Integer id : ids) {
dils.add(requestManager.getDilutionByIdAndPlatform(id.longValue(), platformType));
}
boolean barcodeCollision = false;
if (dils.size() > 1) {
for (Dilution d1 : dils) {
if (d1 != null) {
for (Dilution d2 : dils) {
if (d2 != null && !d1.equals(d2)) {
if (!d1.getLibrary().getTagBarcodes().isEmpty() && !d2.getLibrary().getTagBarcodes().isEmpty()) {
if (d1.getLibrary().getTagBarcodes().equals(d2.getLibrary().getTagBarcodes())) {
barcodeCollision = true;
}
}
}
}
}
}
}
if (!barcodeCollision) {
Pool pool;
//TODO special type of pool for LibraryDilutions that will go on to be emPCRed as a whole
if (dils.get(0) instanceof LibraryDilution &&
(platformType.equals(PlatformType.SOLID) || platformType.equals(PlatformType.LS454))) {
pool = dataObjectFactory.getEmPCRPool(platformType, user);
}
else {
pool = dataObjectFactory.getPoolOfType(platformType, user);
}
if (alias != null) {
pool.setAlias(alias);
}
pool.setCreationDate(new Date());
pool.setConcentration(concentration);
pool.setPlatformType(platformType);
pool.setReadyToRun(true);
for (Dilution d : dils) {
try {
pool.addPoolableElement(d);
}
catch (MalformedDilutionException dle) {
log.error("Failed", dle);
return JSONUtils.SimpleJSONError("Failed: " + dle.getMessage());
}
}
for (PoolQC qc : pqcs) {
try {
qc.setPool(pool);
pool.addQc(qc);
}
catch (MalformedPoolException e) {
e.printStackTrace();
log.error("Failed", e);
return JSONUtils.SimpleJSONError("Failed: " + e.getMessage());
}
catch (MalformedPoolQcException e) {
e.printStackTrace();
log.error("Failed", e);
return JSONUtils.SimpleJSONError("Failed: " + e.getMessage());
}
}
requestManager.savePool(pool);
//sb.append("<a class='dashboardresult' href='/miso/pool/"+pool.getPlatformType().getKey().toLowerCase()+"/" + pool.getId() + "' target='_blank'><div onmouseover=\"this.className='dashboardhighlight ui-corner-all'\" onmouseout=\"this.className='dashboard ui-corner-all'\" class='dashboard ui-corner-all' >");
sb.append("<a class='dashboardresult' href='/miso/pool/" + pool.getId() + "' target='_blank'><div onmouseover=\"this.className='dashboardhighlight ui-corner-all'\" onmouseout=\"this.className='dashboard ui-corner-all'\" class='dashboard ui-corner-all' >");
sb.append("Pool ID: <b>" + pool.getId() + "</b><br/>");
sb.append("Pool Name: <b>" + pool.getName() + "</b><br/>");
sb.append("Platform Type: <b>" + pool.getPlatformType().name() + "</b><br/>");
sb.append("Dilutions: <ul class='bullets'>");
for (Dilution dl : (Collection<? extends Dilution>) pool.getDilutions()) {
sb.append("<li>" + dl.getName() + " (<a href='/miso/library/" + dl.getLibrary().getId() + "'>" + dl.getLibrary().getAlias() + "</a>)</li>");
}
sb.append("</ul>");
sb.append("QCs: <ul class='bullets'>");
for (PoolQC qc : (Collection<PoolQC>) pool.getPoolQCs()) {
sb.append("<li>")
.append(qc.getResults()).append(" ").append(qc.getQcType().getUnits())
.append(" (").append(qc.getQcType().getName()).append(")</li>");
}
sb.append("</ul>");
sb.append("</div></a>");
}
else {
throw new IOException("Tag barcode collision. Two or more selection dilutions have the same tag barcode and therefore cannot be pooled together.");
}
}
catch (IOException e) {
log.error("Failed", e);
return JSONUtils.SimpleJSONError("Failed: " + e.getMessage());
}
}
else {
sb.append("<br/>No dilution available to save.");
}
response.put("html", sb.toString());
return response;
}
public JSONObject addStudy(HttpSession session, JSONObject json) {
String studyType = null;
Long projectId = json.getLong("projectId");
String studyDescription = null;
StringBuilder sb = new StringBuilder();
JSONArray a = JSONArray.fromObject(json.get("form"));
for (JSONObject j : (Iterable<JSONObject>) a) {
if (j.getString("name").equals("studyDescription")) {
studyDescription = j.getString("value");
}
else if (j.getString("name").equals("studyType")) {
studyType = j.getString("value");
}
}
try {
Project p = requestManager.getProjectById(projectId);
Study s = new StudyImpl();
s.setProject(p);
s.setAlias(p.getAlias());
s.setDescription(studyDescription);
s.setSecurityProfile(p.getSecurityProfile());
s.setStudyType(studyType);
requestManager.saveStudy(s);
sb.append("<a class=\"dashboardresult\" href='/miso/study/" + s.getId() + "' target='_blank'><div onmouseover=\"this.className='dashboardhighlight ui-corner-all'\" onmouseout=\"this.className='dashboard ui-corner-all'\" class='dashboard ui-corner-all' >New Study Added:<br/>");
sb.append("Study ID: " + s.getId() + "<br/>");
sb.append("Study Name: <b>" + s.getName() + "</b><br/>");
sb.append("Study Alias: <b>" + s.getAlias() + "</b><br/>");
sb.append("Study Description: <b>" + s.getDescription() + "</b></div></a><br/><hr/><br/>");
}
catch (IOException e) {
log.debug("Failed", e);
return JSONUtils.SimpleJSONError("Failed: " + e.getMessage());
}
return JSONUtils.JSONObjectResponse("html", sb.toString());
}
public JSONObject populateDilutions(HttpSession session, JSONObject json) {
Long projectId = json.getLong("projectId");
PlatformType platformType = PlatformType.get(json.getString("platformType"));
try {
StringBuilder b = new StringBuilder();
JSONArray a = new JSONArray();
List<Dilution> dls = new ArrayList<Dilution>(requestManager.listAllDilutionsByProjectAndPlatform(projectId, platformType));
Collections.sort(dls);
for (Dilution dl : dls) {
if (dl.getLibrary().getQcPassed()) {
//b.append("<tr id='"+dl.getDilutionId()+"'><td class='rowSelect'><input class='chkbox' type='checkbox' name='ids' value='" + dl.getDilutionId() + "'/></td>");
StringBuilder barcode = new StringBuilder();
if (!dl.getLibrary().getTagBarcodes().isEmpty()) {
int count = 0;
for (TagBarcode tb : dl.getLibrary().getTagBarcodes().values()) {
if (dl.getLibrary().getTagBarcodes().values().size() > 1 && count > 0) {
barcode.append("-");
}
barcode.append(tb.getName());
count++;
}
}
b.append("<tr id='" + dl.getId() + "'><td class='rowSelect'></td>");
b.append("<td>" + dl.getName() + "</td>");
b.append("<td>");
b.append(barcode);
b.append("</td>");
b.append("</tr>");
a.add(JSONObject.fromObject("{'id':" + dl.getId() + ",'name':'" + dl.getName() + "','description':'" + dl.getLibrary().getDescription() + "','library':'" + dl.getLibrary().getAlias() + "','libraryBarcode':'" + barcode.toString() + "'}"));
}
}
JSONObject j = new JSONObject();
j.put("dilutions", a);
return JSONUtils.JSONObjectResponse(j);
}
catch (IOException e) {
log.debug("Failed", e);
return JSONUtils.SimpleJSONError("Failed: " + e.getMessage());
}
}
public void setSecurityManager(com.eaglegenomics.simlims.core.manager.SecurityManager securityManager) {
this.securityManager = securityManager;
}
public void setRequestManager(uk.ac.bbsrc.tgac.miso.core.manager.RequestManager requestManager) {
this.requestManager = requestManager;
}
public void setDataObjectFactory(DataObjectFactory dataObjectFactory) {
this.dataObjectFactory = dataObjectFactory;
}
}