@Override
  protected void processRequest() throws Exception {
    FormProcessor fp = new FormProcessor(request);

    DiscrepancyNoteDAO dndao = new DiscrepancyNoteDAO(sm.getDataSource());
    int noteId = fp.getInt(NOTE_ID, true);

    DiscrepancyNoteBean note = (DiscrepancyNoteBean) dndao.findByPK(noteId);

    String entityType = note.getEntityType();
    UserAccountDAO udao = new UserAccountDAO(sm.getDataSource());

    ArrayList notes = dndao.findAllEntityByPK(note.getEntityType(), noteId);

    Date lastUpdatedDate = note.getCreatedDate();
    UserAccountBean lastUpdator = (UserAccountBean) udao.findByPK(note.getOwnerId());

    for (int i = 0; i < notes.size(); i++) {
      DiscrepancyNoteBean n = (DiscrepancyNoteBean) notes.get(i);
      int pId = n.getParentDnId();
      if (pId == 0) {
        note = n;
        note.setLastUpdator((UserAccountBean) udao.findByPK(n.getOwnerId()));
        note.setLastDateUpdated(n.getCreatedDate());
        lastUpdatedDate = note.getLastDateUpdated();
        lastUpdator = note.getLastUpdator();
      }
    }

    for (int i = 0; i < notes.size(); i++) {
      DiscrepancyNoteBean n = (DiscrepancyNoteBean) notes.get(i);
      int pId = n.getParentDnId();
      if (pId > 0) {
        note.getChildren().add(n);
        if (!n.getCreatedDate().before(lastUpdatedDate)) {
          lastUpdatedDate = n.getCreatedDate();
          lastUpdator = (UserAccountBean) udao.findByPK(n.getOwnerId());
          note.setLastUpdator(lastUpdator);
          note.setLastDateUpdated(lastUpdatedDate);
          note.setResolutionStatusId(n.getResolutionStatusId());
          note.setResStatus(ResolutionStatus.get(n.getResolutionStatusId()));
        }
      }
    }
    note.setNumChildren(note.getChildren().size());
    note.setDisType(DiscrepancyNoteType.get(note.getDiscrepancyNoteTypeId()));
    logger.info("Just set Note: " + note.getCrfName() + " column " + note.getColumn());
    request.setAttribute(DIS_NOTE, note);
    forwardPage(Page.VIEW_SINGLE_NOTE);
  }
  private DiscrepancyNoteBean findSingleMapping(DiscrepancyNoteBean note) {
    HashMap variables = new HashMap();
    variables.put(new Integer(1), new Integer(note.getId()));

    setMapTypesExpected();
    String entityType = note.getEntityType();
    String sql = "";
    if ("subject".equalsIgnoreCase(entityType)) {
      sql = digester.getQuery("findSubjectMapByDNId");
    } else if ("studySub".equalsIgnoreCase(entityType)) {
      sql = digester.getQuery("findStudySubjectMapByDNId");
    } else if ("eventCrf".equalsIgnoreCase(entityType)) {
      sql = digester.getQuery("findEventCRFMapByDNId");
    } else if ("studyEvent".equalsIgnoreCase(entityType)) {
      sql = digester.getQuery("findStudyEventMapByDNId");
    } else if ("itemData".equalsIgnoreCase(entityType)) {
      sql = digester.getQuery("findItemDataMapByDNId");
    }

    ArrayList hms = select(sql, variables);

    if (hms.size() > 0) {
      HashMap hm = (HashMap) hms.get(0);
      note = getMappingFromHashMap(hm, note);
    }

    return note;
  }
  /** Creates a new discrepancy note */
  public EntityBean create(EntityBean eb) {
    DiscrepancyNoteBean sb = (DiscrepancyNoteBean) eb;
    HashMap variables = new HashMap();
    HashMap nullVars = new HashMap();
    // INSERT INTO discrepancy_note
    // (description, discrepancy_note_type_id ,
    // resolution_status_id , detailed_notes , date_created,
    // owner_id, parent_dn_id)
    // VALUES (?,?,?,?,now(),?,?)
    variables.put(new Integer(1), sb.getDescription());
    variables.put(new Integer(2), new Integer(sb.getDiscrepancyNoteTypeId()));
    variables.put(new Integer(3), new Integer(sb.getResolutionStatusId()));
    variables.put(new Integer(4), sb.getDetailedNotes());

    variables.put(new Integer(5), new Integer(sb.getOwner().getId()));
    if (sb.getParentDnId() == 0) {
      nullVars.put(new Integer(6), new Integer(Types.INTEGER));
      variables.put(new Integer(6), null);
    } else {
      variables.put(new Integer(6), new Integer(sb.getParentDnId()));
    }
    variables.put(new Integer(7), sb.getEntityType());
    variables.put(new Integer(8), new Integer(sb.getStudyId()));

    this.executeWithPK(digester.getQuery("create"), variables, nullVars);
    if (isQuerySuccessful()) {
      sb.setId(getLatestPK());
    }

    return sb;
  }
  /**
   * Redirect the request to another page if the user is a Monitor type and the discrepancy note is
   * a type other than item data or event crf.
   *
   * @param module A String like "managestudy" or "admin"
   * @param discrepancyNoteBean
   */
  private void redirectMonitor(String module, DiscrepancyNoteBean discrepancyNoteBean) {

    if (discrepancyNoteBean != null) {

      String createNoteURL = "";
      // This String will determine whether the type is other than
      // itemdata.
      String entityType = discrepancyNoteBean.getEntityType().toLowerCase();
      // The id of the subject, study subject, or study event
      int entityId = discrepancyNoteBean.getEntityId();
      RequestDispatcher dispatcher = null;
      DiscrepancyNoteUtil discNoteUtil = new DiscrepancyNoteUtil();

      if (entityType != null
          && !"".equalsIgnoreCase(entityType)
          && !"itemdata".equalsIgnoreCase(entityType)
          && !"eventcrf".equalsIgnoreCase(entityType)) {
        // redirect to View Study Subject
        // addPageMessage(resword.getString("monitors_do_not_have_permission_to_resolve_discrepancy_notes"));
        if ("studySub".equalsIgnoreCase(entityType)) {
          dispatcher =
              request.getRequestDispatcher(
                  "/ViewStudySubject?id=" + entityId + "&module=" + module);
          discrepancyNoteBean.setSubjectId(entityId);
        } else if ("subject".equalsIgnoreCase(entityType)) {

          int studySubId =
              discNoteUtil.getStudySubjectIdForDiscNote(
                  discrepancyNoteBean, sm.getDataSource(), currentStudy.getId());

          dispatcher =
              request.getRequestDispatcher(
                  "/ViewStudySubject?id=" + studySubId + "&module=" + module);
          discrepancyNoteBean.setSubjectId(studySubId);
        } else if ("studyevent".equalsIgnoreCase(entityType)) {
          dispatcher = request.getRequestDispatcher("/EnterDataForStudyEvent?eventId=" + entityId);
        }

        // This code creates the URL for a popup window, which the
        // processing Servlet will initiate.
        // 'true' parameter means that ViewDiscrepancyNote is the
        // handling Servlet.
        createNoteURL =
            CreateDiscrepancyNoteServlet.getAddChildURL(
                discrepancyNoteBean, ResolutionStatus.CLOSED, true);
        request.setAttribute(POP_UP_URL, createNoteURL);

        try {
          if (dispatcher != null) {
            dispatcher.forward(request, response);
          }
        } catch (ServletException e) {
          e.printStackTrace();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }
  private DiscrepancyNoteBean getMappingFromHashMap(HashMap hm, DiscrepancyNoteBean note) {
    String entityType = note.getEntityType();
    String entityIDColumn = getEntityIDColumn(entityType);

    if (!entityIDColumn.equals("")) {
      note.setEntityId(selectInt(hm, entityIDColumn));
    }
    note.setColumn(selectString(hm, "column_name"));
    return note;
  }
  public static AuditableEntityDAO getAEDAO(DiscrepancyNoteBean note, DataSource ds) {
    String entityType = note.getEntityType();
    if ("subject".equalsIgnoreCase(entityType)) {
      return new SubjectDAO(ds);
    } else if ("studySub".equalsIgnoreCase(entityType)) {
      return new StudySubjectDAO(ds);
    } else if ("eventCrf".equalsIgnoreCase(entityType)) {
      return new EventCRFDAO(ds);
    } else if ("studyEvent".equalsIgnoreCase(entityType)) {
      return new StudyEventDAO(ds);
    } else if ("itemData".equalsIgnoreCase(entityType)) {
      return new ItemDataDAO(ds);
    }

    return null;
  }
  /** Creates a new discrepancy note map */
  public void createMapping(DiscrepancyNoteBean eb) {
    HashMap variables = new HashMap();
    variables.put(new Integer(1), new Integer(eb.getEntityId()));
    variables.put(new Integer(2), new Integer(eb.getId()));
    variables.put(new Integer(3), eb.getColumn());
    String entityType = eb.getEntityType();

    if ("subject".equalsIgnoreCase(entityType)) {
      this.execute(digester.getQuery("createSubjectMap"), variables);
    } else if ("studySub".equalsIgnoreCase(entityType)) {
      this.execute(digester.getQuery("createStudySubjectMap"), variables);
    } else if ("eventCrf".equalsIgnoreCase(entityType)) {
      this.execute(digester.getQuery("createEventCRFMap"), variables);
    } else if ("studyEvent".equalsIgnoreCase(entityType)) {
      this.execute(digester.getQuery("createStudyEventMap"), variables);
    } else if ("itemData".equalsIgnoreCase(entityType)) {
      this.execute(digester.getQuery("createItemDataMap"), variables);
    }
  }
  public Page getPageForForwarding(DiscrepancyNoteBean note, boolean isCompleted) {
    String entityType = note.getEntityType().toLowerCase();
    request.setAttribute("fromResolvingNotes", "yes");

    if ("subject".equalsIgnoreCase(entityType)) {
      if (ub.isSysAdmin() || ub.isTechAdmin()) {
        return Page.UPDATE_SUBJECT_SERVLET;
      } else {
        return Page.VIEW_STUDY_SUBJECT_SERVLET;
      }
      // UpdateSubject?id=8&studySubId=8&action=show
    } else if ("studysub".equalsIgnoreCase(entityType)) {
      if (ub.isSysAdmin() || ub.isTechAdmin()) {
        return Page.UPDATE_STUDY_SUBJECT_SERVLET;
      } else {
        return Page.VIEW_STUDY_SUBJECT_SERVLET;
      }
      // UpdateStudySubject?id=8&action=show
    } /*
       * BWP>> 2966, commented this out: else if
       * ("eventcrf".equalsIgnoreCase(entityType)) { return
       * Page.TABLE_OF_CONTENTS_SERVLET; //
       * TableOfContents?action=ae&ecid=51&submitted=1&editInterview=1&interviewer=abc&interviewDate=12/04/2003 }
       */ else if ("studyevent".equalsIgnoreCase(entityType)) {
      if (ub.isSysAdmin() || ub.isTechAdmin()) {
        return Page.UPDATE_STUDY_EVENT_SERVLET;
      } else {
        return Page.ENTER_DATA_FOR_STUDY_EVENT_SERVLET;
      }
      // UpdateStudyEvent?event_id=12&ss_id=12
    } else if ("itemdata".equalsIgnoreCase(entityType) || "eventcrf".equalsIgnoreCase(entityType)) {
      if (currentRole.getRole().equals(Role.MONITOR) || !isCompleted) {
        return Page.VIEW_SECTION_DATA_ENTRY_SERVLET;
        // ViewSectionDataEntry?eventDefinitionCRFId=&ecId=1&tabId=1&studySubjectId=1
      } else {
        return Page.ADMIN_EDIT_SERVLET;
      }
      // eventCRFId=51&sectionId=14
    }
    return null;
  }
  /*
   * (non-Javadoc)
   *
   * @see org.akaza.openclinica.control.core.SecureController#processRequest()
   */
  @Override
  protected void processRequest() throws Exception {

    FormProcessor fp = new FormProcessor(request);
    int noteId = fp.getInt(INPUT_NOTE_ID);
    String module = (String) session.getAttribute("module");
    // Integer subjectId = (Integer) session.getAttribute("subjectId");

    StudySubjectDAO studySubjectDAO = new StudySubjectDAO(sm.getDataSource());

    DiscrepancyNoteDAO dndao = new DiscrepancyNoteDAO(sm.getDataSource());
    dndao.setFetchMapping(true);

    // check that the note exists
    DiscrepancyNoteBean discrepancyNoteBean = (DiscrepancyNoteBean) dndao.findByPK(noteId);

    if (!discrepancyNoteBean.isActive()) {
      throw new InconsistentStateException(
          Page.MANAGE_STUDY_SERVLET,
          resexception.getString("you_are_trying_resolve_discrepancy_not_exist"));
    }

    // check that the note has not already been closed
    ArrayList children = dndao.findAllByParent(discrepancyNoteBean);
    discrepancyNoteBean.setChildren(children);
    // This logic has been reverted, issue-7459
    //        if (parentNoteIsClosed(discrepancyNoteBean)) {
    //            throw new InconsistentStateException(Page.VIEW_DISCREPANCY_NOTES_IN_STUDY_SERVLET,
    // respage
    //                    .getString("the_discrepancy_choose_has_been_closed_resolved_create_new"));
    //        }

    // all clear, send the user to the resolved screen
    String entityType = discrepancyNoteBean.getEntityType().toLowerCase();
    discrepancyNoteBean.setResStatus(
        ResolutionStatus.get(discrepancyNoteBean.getResolutionStatusId()));
    discrepancyNoteBean.setDisType(
        DiscrepancyNoteType.get(discrepancyNoteBean.getDiscrepancyNoteTypeId()));
    // BWP 03/17/2009 3166: if it's not an ItemData type note, redirect
    // Monitors to View Subject or
    // View Study Events <<
    if (currentRole.getRole().equals(Role.MONITOR)
        && !"itemdata".equalsIgnoreCase(entityType)
        && !"eventcrf".equalsIgnoreCase(entityType)) {
      redirectMonitor(module, discrepancyNoteBean);
      return;
    }
    // >>
    // If Study is Frozen or Locked
    if (currentStudy.getStatus().isFrozen()
        && !"itemdata".equalsIgnoreCase(entityType)
        && !"eventcrf".equalsIgnoreCase(entityType)) {
      redirectMonitor(module, discrepancyNoteBean);
      return;
    }

    boolean toView = false;
    boolean isCompleted = false;
    if ("itemdata".equalsIgnoreCase(entityType)) {
      ItemDataDAO iddao = new ItemDataDAO(sm.getDataSource());
      ItemDataBean idb = (ItemDataBean) iddao.findByPK(discrepancyNoteBean.getEntityId());

      EventCRFDAO ecdao = new EventCRFDAO(sm.getDataSource());

      EventCRFBean ecb = (EventCRFBean) ecdao.findByPK(idb.getEventCRFId());
      StudySubjectBean studySubjectBean =
          (StudySubjectBean) studySubjectDAO.findByPK(ecb.getStudySubjectId());

      discrepancyNoteBean.setSubjectId(studySubjectBean.getId());
      discrepancyNoteBean.setItemId(idb.getItemId());

      if (ecb.getStatus().equals(Status.UNAVAILABLE)) {
        isCompleted = true;
      }

      toView = true; // we want to go to view note page if the note is
      // for item data
    }
    // logger.info("set up pop up url: " + createNoteURL);
    // System.out.println("set up pop up url: " + createNoteURL);
    boolean goNext =
        prepareRequestForResolution(
            request, sm.getDataSource(), currentStudy, discrepancyNoteBean, isCompleted);

    Page p = getPageForForwarding(discrepancyNoteBean, isCompleted);

    // logger.info("found page for forwarding: " + p.getFileName());
    if (p == null) {
      throw new InconsistentStateException(
          Page.VIEW_DISCREPANCY_NOTES_IN_STUDY_SERVLET,
          resexception.getString("the_discrepancy_note_triying_resolve_has_invalid_type"));
    } else {
      if (p.getFileName().contains("?")) {
        if (!p.getFileName().contains("fromViewNotes=1")) {
          p.setFileName(p.getFileName() + "&fromViewNotes=1");
        }
      } else {
        p.setFileName(p.getFileName() + "?fromViewNotes=1");
      }
      String createNoteURL =
          CreateDiscrepancyNoteServlet.getAddChildURL(
              discrepancyNoteBean, ResolutionStatus.CLOSED, true);
      setPopUpURL(createNoteURL);
    }

    if (!goNext) {
      setPopUpURL("");
      addPageMessage(
          respage.getString("you_may_not_perform_admin_edit_on_CRF_not_completed_by_user"));
      p = Page.VIEW_DISCREPANCY_NOTES_IN_STUDY_SERVLET;
    }

    forwardPage(p);
  }
  public boolean prepareRequestForResolution(
      HttpServletRequest request,
      DataSource ds,
      StudyBean currentStudy,
      DiscrepancyNoteBean note,
      boolean isCompleted) {
    String entityType = note.getEntityType().toLowerCase();
    int id = note.getEntityId();
    if ("subject".equalsIgnoreCase(entityType)) {
      StudySubjectDAO ssdao = new StudySubjectDAO(ds);
      StudySubjectBean ssb = ssdao.findBySubjectIdAndStudy(id, currentStudy);

      request.setAttribute("action", "show");
      request.setAttribute("id", String.valueOf(note.getEntityId()));
      request.setAttribute("studySubId", String.valueOf(ssb.getId()));
    } else if ("studysub".equalsIgnoreCase(entityType)) {
      request.setAttribute("action", "show");
      request.setAttribute("id", String.valueOf(note.getEntityId()));
    } else if ("eventcrf".equalsIgnoreCase(entityType)) {
      request.setAttribute("editInterview", "1");

      EventCRFDAO ecdao = new EventCRFDAO(ds);
      EventCRFBean ecb = (EventCRFBean) ecdao.findByPK(id);
      request.setAttribute(TableOfContentsServlet.INPUT_EVENT_CRF_BEAN, ecb);
      // If the request is passed along to ViewSectionDataEntryServlet,
      // that code needs
      // an event crf id; the (ecb.getId()+"") is necessary because
      // FormProcessor throws
      // a ClassCastException without the casting to a String
      request.setAttribute(ViewSectionDataEntryServlet.EVENT_CRF_ID, ecb.getId() + "");
    } else if ("studyevent".equalsIgnoreCase(entityType)) {
      StudyEventDAO sedao = new StudyEventDAO(ds);
      StudyEventBean seb = (StudyEventBean) sedao.findByPK(id);
      request.setAttribute(EnterDataForStudyEventServlet.INPUT_EVENT_ID, String.valueOf(id));
      request.setAttribute(UpdateStudyEventServlet.EVENT_ID, String.valueOf(id));
      request.setAttribute(
          UpdateStudyEventServlet.STUDY_SUBJECT_ID, String.valueOf(seb.getStudySubjectId()));
    }

    // this is for item data
    else if ("itemdata".equalsIgnoreCase(entityType)) {
      ItemDataDAO iddao = new ItemDataDAO(ds);
      ItemDataBean idb = (ItemDataBean) iddao.findByPK(id);

      EventCRFDAO ecdao = new EventCRFDAO(ds);

      EventCRFBean ecb = (EventCRFBean) ecdao.findByPK(idb.getEventCRFId());

      StudySubjectDAO ssdao = new StudySubjectDAO(sm.getDataSource());

      StudySubjectBean ssb = (StudySubjectBean) ssdao.findByPK(ecb.getStudySubjectId());

      ItemFormMetadataDAO ifmdao = new ItemFormMetadataDAO(ds);
      ItemFormMetadataBean ifmb =
          ifmdao.findByItemIdAndCRFVersionId(idb.getItemId(), ecb.getCRFVersionId());

      if (currentRole.getRole().equals(Role.MONITOR) || !isCompleted) {
        StudyEventDAO sedao = new StudyEventDAO(ds);
        StudyEventBean seb = (StudyEventBean) sedao.findByPK(id);
        request.setAttribute(EVENT_CRF_ID, String.valueOf(idb.getEventCRFId()));
        request.setAttribute(STUDY_SUB_ID, String.valueOf(seb.getStudySubjectId()));

      } else {
        request.setAttribute(
            DataEntryServlet.INPUT_EVENT_CRF_ID, String.valueOf(idb.getEventCRFId()));
        request.setAttribute(
            DataEntryServlet.INPUT_SECTION_ID, String.valueOf(ifmb.getSectionId()));
      }
      DataEntryStage stage = ecb.getStage();

      // if (!stage.equals(DataEntryStage.DOUBLE_DATA_ENTRY_COMPLETE)) {
      // return false;
      // }
    }

    return true;
  }