@Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    CallingContext cc = ContextFactory.getCallingContext(this, req);
    User user = cc.getCurrentUser();
    UserService userService = cc.getUserService();

    // Check to make sure we are using the canonical server name.
    // If not, redirect to that name.  This ensures that authentication
    // cookies will have the proper realm(s) established for them.
    String newUrl = cc.getServerURL() + BasicConsts.FORWARDSLASH + ADDR;
    String query = req.getQueryString();
    if (query != null && query.length() != 0) {
      newUrl += "?" + query;
    }
    URL url = new URL(newUrl);
    if (!url.getHost().equalsIgnoreCase(req.getServerName())) {
      // we should redirect over to the proper fully-formed URL.
      logger.info(
          "Incoming servername: "
              + req.getServerName()
              + " expected: "
              + url.getHost()
              + " -- redirecting.");
      resp.sendRedirect(newUrl);
      return;
    }

    // OK. We are using the canonical server name.
    boolean isSuperUser = false;
    try {
      isSuperUser = userService.isSuperUser(cc);
    } catch (ODKDatastoreException e) {
      e.printStackTrace();
    }

    // determine if this is the first time the system has not been accessed...
    if (isSuperUser) {
      // this is the super-user -- examine the isEnabled
      // field to determine whether this is the first time
      // visiting the site. If it is, force a redirect to
      // the site-configuration tab.
      boolean directToConfigTab = false;
      Datastore ds = cc.getDatastore();
      try {
        long changeTimestamp = SecurityRevisionsTable.getLastSuperUserIdRevisionDate(ds, user);
        long reviewStamp = SecurityRevisionsTable.getLastPermissionsViewRevisionDate(ds, user);

        if (reviewStamp < changeTimestamp) {
          SecurityRevisionsTable.setLastPermissionsViewRevisionDate(ds, user);
          directToConfigTab = true;
        }
      } catch (ODKDatastoreException e) {
        e.printStackTrace();
      }
      if (directToConfigTab) {
        newUrl += "#admin/permission///";
        logger.info("Redirect to configuration tab: " + newUrl);
        resp.sendRedirect(newUrl);
        return;
      }
    }

    resp.setContentType(HtmlConsts.RESP_TYPE_HTML);
    resp.setCharacterEncoding(HtmlConsts.UTF8_ENCODE);
    PrintWriter out = resp.getWriter();
    out.print(PAGE_CONTENTS_FIRST);
    String simpleApiKey;
    try {
      simpleApiKey = ServerPreferencesProperties.getGoogleSimpleApiKey(cc);
      if (simpleApiKey != null && simpleApiKey.length() != 0) {
        out.print("key=" + encodeParameter(simpleApiKey) + "&amp;");
      }
    } catch (ODKEntityNotFoundException e) {
      e.printStackTrace();
      logger.info("Unable to access Map APIKey");
    } catch (ODKOverQuotaException e) {
      e.printStackTrace();
      logger.info("Unable to access Map APIKey");
    }
    out.print(PAGE_CONTENTS_SECOND);
  }
  /**
   * Handler for HTTP Get request to create xform upload page
   *
   * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest,
   *     javax.servlet.http.HttpServletResponse)
   */
  @Override
  public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    CallingContext cc = ContextFactory.getCallingContext(this, req);
    cc.setAsDaemon(true);

    logger.info("GAE servlet for CSV generation begins");

    // get parameter
    final String formId = getParameter(req, ServletConsts.FORM_ID);
    if (formId == null) {
      logger.error("Missing " + ServletConsts.FORM_ID + " key");
      errorMissingKeyParam(resp);
      return;
    }
    final String persistentResultsString = getParameter(req, ServletConsts.PERSISTENT_RESULTS_KEY);
    if (persistentResultsString == null) {
      logger.error("Missing " + ServletConsts.PERSISTENT_RESULTS_KEY + " key");
      errorBadParam(resp);
      return;
    }
    SubmissionKey persistentResultsKey = new SubmissionKey(persistentResultsString);
    final String attemptCountString = getParameter(req, ServletConsts.ATTEMPT_COUNT);
    if (attemptCountString == null) {
      logger.error("Missing " + ServletConsts.ATTEMPT_COUNT + " key");
      errorBadParam(resp);
      return;
    }
    Long attemptCount = 1L;
    try {
      attemptCount = Long.valueOf(attemptCountString);
    } catch (Exception e) {
      logger.error(
          "Invalid "
              + ServletConsts.ATTEMPT_COUNT
              + " value: "
              + attemptCountString
              + " exception: "
              + e.toString());
      errorBadParam(resp);
      return;
    }

    IForm form = null;
    try {
      form = FormFactory.retrieveFormByFormId(formId, cc);
    } catch (ODKFormNotFoundException e) {
      logger.error("Unable to retrieve formId: " + formId + " exception: " + e.toString());
      e.printStackTrace();
      odkIdNotFoundError(resp);
      return;
    } catch (ODKOverQuotaException e) {
      logger.error("Unable to retrieve formId: " + formId + " exception: " + e.toString());
      e.printStackTrace();
      quotaExceededError(resp);
      return;
    } catch (ODKDatastoreException e) {
      logger.error("Unable to retrieve formId: " + formId + " exception: " + e.toString());
      e.printStackTrace();
      datastoreError(resp);
      return;
    }

    if (!form.hasValidFormDefinition()) {
      logger.error("Unable to retrieve formId: " + formId + " invalid form definition");
      errorRetreivingData(resp);
      return; // ill-formed definition
    }

    CsvWorkerImpl impl = new CsvWorkerImpl(form, persistentResultsKey, attemptCount, cc);

    impl.generateCsv();
  }