package services; import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.URL; import java.net.URLConnection; import java.text.ParseException; import java.util.List; import matrix.DataMatrixInstance; import matrix.general.DataMatrixHandler; import org.molgenis.data.Data; import org.molgenis.framework.db.Database; import org.molgenis.framework.db.DatabaseException; import org.molgenis.framework.db.QueryRule; import org.molgenis.framework.db.QueryRule.Operator; import org.molgenis.framework.server.MolgenisContext; import org.molgenis.framework.server.MolgenisRequest; import org.molgenis.framework.server.MolgenisResponse; import org.molgenis.framework.server.MolgenisService; import org.molgenis.framework.ui.ApplicationController; import plugins.matrix.manager.MatrixManager; public class downloadmatrixasexcel implements MolgenisService { private MolgenisContext mc; public downloadmatrixasexcel(MolgenisContext mc) { this.mc = mc; } @Override public void handleRequest(MolgenisRequest request, MolgenisResponse response) throws ParseException, DatabaseException, IOException { boolean databaseIsAvailable = false; boolean setupSuccess = false; boolean argumentsAreCorrect = false; Database db = null; DataMatrixInstance instance = null; try { db = request.getDatabase(); databaseIsAvailable = true; } catch (Exception e) { PrintWriter out = response.getResponse().getWriter(); response.getResponse().setContentType("text/plain"); out.print("Database unavailable."); out.print("\n\n"); e.printStackTrace(out); out.close(); } if (databaseIsAvailable) { try { // special exception for filtered content: get matrix instance // from memory and do complete handle if (request.getString("id").equals("inmemory")) { ApplicationController molgenis = (ApplicationController) request.getRequest().getSession() .getAttribute("application"); DataMatrixInstance dm = ((DataMatrixInstance) molgenis.sessionVariables .get(MatrixManager.SESSION_MATRIX_DATA)); if (dm.getNumberOfCols() > 256) { throw new Exception("Too many columns selected. The maximum for Excel is 256."); } if (dm.getNumberOfRows() > 100000) { throw new Exception("Too many rows selected. The maximum is limited to 100k."); } File excelFile = dm.getAsExcelFile(); OutputStream outSpecial = response.getResponse().getOutputStream(); URL localURL = excelFile.toURI().toURL(); URLConnection conn = localURL.openConnection(); InputStream in = new BufferedInputStream(conn.getInputStream()); response.getResponse().setContentType("application/vnd.ms-excel"); response.getResponse().setContentLength((int) excelFile.length()); response.getResponse().setHeader("Content-disposition", "attachment; filename=\"" + dm.getData().getName() + "_" + "some" + ".xls" + "\""); byte[] buffer = new byte[2048]; for (;;) { int nBytes = in.read(buffer); if (nBytes <= 0) break; outSpecial.write(buffer, 0, nBytes); } outSpecial.flush(); outSpecial.close(); return; } int matrixId = request.getInt("id"); QueryRule q = new QueryRule("id", Operator.EQUALS, matrixId); List<Data> dataList = db.find(Data.class, q); if (dataList.size() != 1) { throw new Exception("Datamatrix for ID " + matrixId + " was not found."); } Data data = dataList.get(0); DataMatrixHandler dmh = new DataMatrixHandler(db); instance = dmh.createInstance(data, db); if (instance.getNumberOfCols() > 256) { throw new Exception("Too many columns selected. The maximum for Excel is 256."); } if (instance.getNumberOfRows() > 100000) { throw new Exception("Too many rows selected. The maximum is limited to 100k."); } setupSuccess = true; } catch (Exception e) { PrintWriter out = response.getResponse().getWriter(); e.printStackTrace(out); out.print("\n\n"); response.getResponse().setContentType("text/plain"); displayUsage(out, db); out.close(); } } if (setupSuccess) { try { if (request.getString("download").equals("all")) { // correct } else if (request.getString("download").equals("some")) { request.getInt("coff"); request.getInt("clim"); request.getInt("roff"); request.getInt("rlim"); // correct } else { throw new Exception("Bad arguments."); } argumentsAreCorrect = true; } catch (Exception e) { PrintWriter out = response.getResponse().getWriter(); response.getResponse().setContentType("text/plain"); displayUsage(out, db); out.print("\n\n"); e.printStackTrace(out); out.close(); } } if (argumentsAreCorrect) { OutputStream outFile = response.getResponse().getOutputStream(); try { File excelFile = null; String download = request.getString("download"); if (download.equals("all")) { excelFile = instance.getAsExcelFile(); } else if (download.equals("some")) { int colOffset = request.getInt("coff"); int colLimit = request.getInt("clim"); int rowOffset = request.getInt("roff"); int rowLimit = request.getInt("rlim"); excelFile = instance.getSubMatrixByOffset(rowOffset, rowLimit, colOffset, colLimit) .getAsExcelFile(); } URL localURL = excelFile.toURI().toURL(); URLConnection conn = localURL.openConnection(); InputStream in = new BufferedInputStream(conn.getInputStream()); response.getResponse().setContentType("application/vnd.ms-excel"); response.getResponse().setContentLength((int) excelFile.length()); response.getResponse().setHeader("Content-disposition", "attachment; filename=\"" + instance.getData().getName() + "_" + download + ".xls" + "\""); byte[] buffer = new byte[2048]; for (;;) { int nBytes = in.read(buffer); if (nBytes <= 0) break; outFile.write(buffer, 0, nBytes); } outFile.flush(); } catch (Exception e) { e.printStackTrace(); // logger.error(e); } finally { outFile.close(); } } } public void displayUsage(PrintWriter out, Database db) { String usage = "Potentially downloadable matrices available in this database:\n\n" + matricesFromDb(db) + "\n"; out.print(usage); } public String matricesFromDb(Database db) { String res = ""; try { List<Data> dataList = db.find(Data.class); // MolgenisFileHandler mfh = new MolgenisFileHandler(db); for (Data data : dataList) { // try{ // mfh.findFile(data).equals("null") // } res += data.toString() + "\n"; } } catch (Exception e) { res += "An error occurred when retrieving matrix information:\n\n"; res += e.getMessage(); } return res; } }