Package org.molgenis.framework.server.services

Source Code of org.molgenis.framework.server.services.MolgenisDownloadService

package org.molgenis.framework.server.services;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.molgenis.framework.db.Database;
import org.molgenis.framework.db.DatabaseException;
import org.molgenis.framework.db.QueryRule;
import org.molgenis.framework.server.AuthStatus;
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.server.MolgenisServiceAuthenticationHelper;
import org.molgenis.io.TupleWriter;
import org.molgenis.io.csv.CsvWriter;
import org.molgenis.util.Entity;

public class MolgenisDownloadService implements MolgenisService
{
  Logger logger = Logger.getLogger(MolgenisDownloadService.class);

  private MolgenisContext mc;

  public MolgenisDownloadService(MolgenisContext mc)
  {
    this.mc = mc;
  }

  /**
   * Handle use of the download API.
   *
   * TODO: this method is horrible and should be properly refactored,
   * documented and tested!
   *
   * @param request
   * @param response
   */
  @Override
  public void handleRequest(MolgenisRequest req, MolgenisResponse res) throws ParseException, DatabaseException,
      IOException
  {
    logger.info("starting download " + req.getRequest().getPathInfo());
    long start_time = System.currentTimeMillis();

    res.getResponse().setBufferSize(10000);
    res.getResponse().setContentType("text/html; charset=UTF-8");

    PrintWriter out = res.getResponse().getWriter();
    Database db = req.getDatabase();

    try
    {

      AuthStatus authStatus = MolgenisServiceAuthenticationHelper.handleAuthentication(req, out);

      if (!authStatus.isShowApi())
      {
        out.println("<html><body>");
        out.println(authStatus.getPrintMe());
        out.println("</body></html>");
      }
      else
      {

        String entityName = req.getRequest().getPathInfo().substring(req.getServicePath().length());

        if (entityName.startsWith("/"))
        {
          entityName = entityName.substring(1);
        }

        if (entityName.equals(""))
        {
          out.println("<html><body>");
          out.println(authStatus.getPrintMe());
          if (req.getDatabase().getLogin().isAuthenticated())
          {
            out.println(MolgenisServiceAuthenticationHelper.displayLogoutForm());
          }
          showAvailableDownloads(out, db, req);
          out.println("</body></html>");
        }
        else
        {
          // Check if this entity exists and is downloadable
          List<org.molgenis.model.elements.Entity> downloadableEntities = getDownloadableEntities(db);
          boolean found = false;
          for (int i = 0; i < downloadableEntities.size() && !found; i++)
          {
            String name = downloadableEntities.get(i).getName();
            if ((name != null) && name.equals(entityName))
            {
              found = true;
            }
          }

          if (!found)
          {
            res.getResponse().sendError(404);// NOT FOUND
            return;
          }

          if (req.getRequest().getQueryString() != null
              && req.getRequest().getQueryString().equals("__showQueryDialogue=true"))
          {
            out.println("<html><body>");
            out.println(authStatus.getPrintMe());
            if (req.getDatabase().getLogin().isAuthenticated())
            {
              out.println(MolgenisServiceAuthenticationHelper.displayLogoutForm());
            }
            showFilterableDownload(out, entityName, db);
            out.println("</body></html>");
          }
          else
          {
            executeQuery(out, req, db, entityName);
          }
        }
      }
    }
    catch (Exception e)
    {
      out.println(e.getMessage());
      e.printStackTrace();
      logger.error(e.getMessage());
    }
    finally
    {
      out.flush();
      out.close();
      db.close();
    }

    logger.info("servlet took: " + (System.currentTimeMillis() - start_time));
    logger.info("------------");

  }

  private void showFilterableDownload(PrintWriter out, String entityName, Database db) throws InstantiationException,
      IllegalAccessException, ClassNotFoundException
  {
    // System.out.println("show 'set filters' dialogue");
    out.println("<form>");
    out.println("You choose to download '" + entityName // FIXME: bad,
                              // hardcoded
                              // location!
        + "' data. (<a href=\"../find\">back</a>)<br><br> Here you can set filters before downloading:<br>");
    out.println("<table>");

    String simpleEntityName = entityName.substring(entityName.lastIndexOf('.') + 1);
    Class<? extends Entity> klazz = db.getClassForName(simpleEntityName);

    for (String field : ((Entity) klazz.newInstance()).getFields())
    {
      out.println("<tr><td>" + field + "</td><td>=</td><td><input name=\"" + field
          + "\" type=\"text\"></td><tr/>");
    }
    out.println("</table>");
    out.println("<SCRIPT>" + "function createFilterURL(fields)" + "{  " + "  var query = '';" + "  var count = 0;"
        + "  for (i = 0; i < fields.length; i++) " + "  {"
        + "    if (fields[i].value != '' && fields[i].name != '__submitbutton')" + "    {" + "      if(count > 0)"
        + "        query +='&';" + "      query += fields[i].name + '=' + fields[i].value;" + "      count++;" + "    }"
        + "  }" + "  return query" + "}" + "</SCRIPT>");

    out.println("<input name=\"__submitbutton\" type=\"submit\" value=\"Download tab delimited file\" onclick=\""
        + "window.location.href = 'http://' + window.location.host + window.location.pathname + '?'+createFilterURL(this.form.elements);\"><br><br>");
    out.println("TIP: notice how the url is bookmarkeable for future downloads!<br>");
    out.println("TIP: click 'save as...' and name it as '.txt' file.");
    out.println("</form>");
  }

  private void showAvailableDownloads(PrintWriter out, Database db, MolgenisRequest req) throws DatabaseException
  {
    // print message to indicate your are anonymous
    if (!db.getLogin().isAuthenticated())
    {
      out.println("You are currently browsing as anonymous.<br>");
    }

    out.println("You can download these data:<br>");
    out.println("<table>");

    for (org.molgenis.model.elements.Entity eClass : getDownloadableEntities(db))
    {
      String name = eClass.getName();
      Class<? extends Entity> klazz = db.getClassForName(name);

      // hide entities without read permission
      if (db.getLogin().canRead(klazz))
      {
        out.println("<tr>");
        out.println("<td><a href=\""
            + (req.getRequest().getPathInfo().endsWith("/") ? "" : "/" + mc.getVariant()
                + req.getServicePath() + "/") + name + "\">" + name + "</a></td>");
        out.println("<td><a href=\""
            + (req.getRequest().getPathInfo().endsWith("/") ? "" : "/" + mc.getVariant()
                + req.getServicePath() + "/") + name + "?__showQueryDialogue=true\">" + "filter"
            + "</a></td>");
        out.println("</tr>");
      }
    }
    out.println("</table>");
  }

  private List<org.molgenis.model.elements.Entity> getDownloadableEntities(Database db) throws DatabaseException
  {
    return db.getMetaData().getEntities(false, false);
  }

  private List<QueryRule> createQueryRules(MolgenisRequest req, Class<? extends Entity> klazz) throws Exception
  {
    List<QueryRule> rulesList = new ArrayList<QueryRule>();

    // use get
    if (req.getRequest().getQueryString() != null)
    {
      // System.out.println("handle find query via http-get: " +
      // request.getQueryString());
      String[] ruleStrings = req.getRequest().getQueryString().split("&");

      for (String rule : ruleStrings)
      {
        String[] ruleElements = rule.split("=");

        if (ruleElements.length != 2)
        {
          // this is OK: just a not-filled-in queryrule
          // throw new Exception("cannot understand querystring " +
          // rule + ", does not have 2 elements");
        }
        else if (ruleElements[1].startsWith("["))
        {
          ruleElements[1] = ruleElements[1].replace("%20", " ");
          String[] values = ruleElements[1].substring(1, ruleElements[1].indexOf("]")).split(",");
          rulesList.add(new QueryRule(ruleElements[0], QueryRule.Operator.IN, values));
        }
        else
        {
          if (ruleElements[1] != "" && !"__submitbutton".equals(ruleElements[0])) rulesList
              .add(new QueryRule(ruleElements[0], QueryRule.Operator.EQUALS, ruleElements[1]));
        }
      }
    }
    // use post
    else
    {
      for (String name : req.getColNames())
      {
        if (klazz.newInstance().getFields().contains(name))
        {
          if (req.getString(name).startsWith("["))
          {
            String[] values = req.getString(name).substring(1, req.getString(name).indexOf("]")).split(",");
            rulesList.add(new QueryRule(name, QueryRule.Operator.IN, values));
          }
          else
          {
            rulesList.add(new QueryRule(name, QueryRule.Operator.EQUALS, req.getString(name)));
          }
        }
      }
    }
    return rulesList;
  }

  private void executeQuery(PrintWriter out, MolgenisRequest req, Database db, String entityName) throws Exception
  {

    String simpleEntityName = entityName.substring(entityName.lastIndexOf('.') + 1);
    Class<? extends Entity> klazz = db.getClassForName(simpleEntityName);

    // create query rules
    List<QueryRule> rulesList = createQueryRules(req, klazz);

    // execute query
    TupleWriter csvWriter = new CsvWriter(out);
    try
    {
      db.find(klazz, csvWriter, rulesList.toArray(new QueryRule[rulesList.size()]));
    }
    finally
    {
      csvWriter.close();
    }
  }

}
TOP

Related Classes of org.molgenis.framework.server.services.MolgenisDownloadService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.