/**
   * Activate rules for accruals. Called for new registrations only. Checks if accrual notifications
   * are configured. Fires rules if thresholds are met.
   *
   * @param studySubjectObj the study subject obj
   */
  private void activateRulesForAccruals(Object studySubjectObj) {
    StudySubject studySubject = null;
    StudyOrganization studyOrg = null;
    StudySite studySite = null;

    if (studySubjectObj instanceof StudySubject) {
      studySubject = (StudySubject) studySubjectObj;
    } else {
      return;
    }

    List<Object> objects = new ArrayList<Object>();
    objects.add(studySubject);
    int studyAccruals = 0;
    int threshold = 0;
    List<HealthcareSite> hcsList = getSites(studySubject);
    for (PlannedNotification pn : getPlannedNotifications(hcsList)) {
      if (pn.getEventName().equals(NotificationEventTypeEnum.STUDY_ACCRUAL_EVENT)) {
        Iterator<StudyOrganization> iter =
            studySubject.getStudySite().getStudy().getStudyOrganizations().iterator();
        while (iter.hasNext()) {
          studyOrg = iter.next();
          // ensure that the host org is in the studyOrg list for the study
          if (studyOrg
              .getHealthcareSite()
              .getPrimaryIdentifier()
              .equalsIgnoreCase(configuration.get(Configuration.LOCAL_NCI_INSTITUTE_CODE))) {
            studyAccruals = calculateStudyAccrual(studySubject);
            threshold = studySubject.getStudySite().getStudy().getTargetAccrualNumber().intValue();
            // if accruals exceed specified threshold value then send out email
            if (studyAccruals * 100 / threshold >= pn.getStudyThreshold()) {
              objects.add(pn);
              rulesDelegationService.activateRules(
                  NotificationEventTypeEnum.STUDY_ACCRUAL_EVENT, objects);
            }
          }
        }
      }
      if (pn.getEventName().equals(NotificationEventTypeEnum.STUDY_SITE_ACCRUAL_EVENT)) {
        studySite = studySubject.getStudySite();
        // ensure that the host org is in the studySite list for the study
        if (studySite
            .getHealthcareSite()
            .getPrimaryIdentifier()
            .equalsIgnoreCase(configuration.get(Configuration.LOCAL_NCI_INSTITUTE_CODE))) {
          studyAccruals = calculateStudySiteAccrual(studySubject);
          threshold = studySubject.getStudySite().getTargetAccrualNumber().intValue();
          // if accruals exceed specified threshold value then send out email
          if ((studyAccruals / threshold) * 100 >= pn.getStudySiteThreshold()) {
            objects.add(pn);
            rulesDelegationService.activateRules(
                NotificationEventTypeEnum.STUDY_SITE_ACCRUAL_EVENT, objects);
          }
        }
      }
    }
  }
  @Override
  public boolean checkAuthorization(
      Authentication authentication, String privilege, Object object) {

    boolean authorize = false;
    StudyOrganization studyOrganization = null;
    StudyOrganization studyCoordinatingCenter = null;
    if (object instanceof StudyOrganization) {
      studyOrganization = (StudyOrganization) object;
      studyCoordinatingCenter = studyOrganization.getStudy().getStudyCoordinatingCenter();
    }

    // super.checkAuthorization will enforce that the logged in user only sees his organization.
    // however if the logged in user is a Coordinating center for the study being viewed the he
    // shud be able to see all sites
    if (studyCoordinatingCenter != null) {
      authorize = super.checkAuthorization(authentication, privilege, studyCoordinatingCenter);
    }

    return authorize ? authorize : super.checkAuthorization(authentication, privilege, object);
  }
  /**
   * Gets the sites. Returns the list of sites associated with the
   * study/studySite/studySubject(depending on the event).
   *
   * @param entity the entity
   * @return the sites
   */
  private List<HealthcareSite> getSites(Object entity) {

    List<HealthcareSite> hcsList = new ArrayList<HealthcareSite>();
    if (entity instanceof StudySubject) {
      //			Original code, commented out for the time-being.
      /*if(((StudySubject)entity).getStudySite() != null){
      	hcsList.add(((StudySubject)entity).getStudySite().getHealthcareSite());
      	hcsList.add(((StudySubject)entity).getStudySite().getStudy().getStudyCoordinatingCenter().getHealthcareSite());

      }*/

      // Try this if the above doesn't work
      StudySubject studySubject = (StudySubject) entity;
      if (studySubject.getStudySubjectStudyVersion() != null
          && studySubject.getStudySubjectStudyVersion().getStudySiteStudyVersion() != null) {
        hcsList.add(
            studySubject
                .getStudySubjectStudyVersion()
                .getStudySiteStudyVersion()
                .getStudySite()
                .getHealthcareSite());
        hcsList.add(
            studySubject
                .getStudySiteVersion()
                .getStudyVersion()
                .getStudy()
                .getStudyCoordinatingCenter()
                .getHealthcareSite());
      }
    }
    if (entity instanceof StudySubjectStudyVersion) {
      StudySubjectStudyVersion studySubjectStudyVersion = (StudySubjectStudyVersion) entity;
      hcsList.add(
          studySubjectStudyVersion.getStudySiteStudyVersion().getStudySite().getHealthcareSite());
      hcsList.add(
          studySubjectStudyVersion
              .getStudySiteStudyVersion()
              .getStudySite()
              .getStudy()
              .getStudyCoordinatingCenter()
              .getHealthcareSite());
    }

    if (entity instanceof SiteStatusHistory) {
      hcsList.add(((SiteStatusHistory) entity).getStudySite().getHealthcareSite());
      hcsList.add(
          ((SiteStatusHistory) entity)
              .getStudySite()
              .getStudy()
              .getStudyCoordinatingCenter()
              .getHealthcareSite());
    }
    if (entity instanceof StudySite) {
      hcsList.add(((StudySite) entity).getHealthcareSite());
      hcsList.add(((StudySite) entity).getStudy().getStudyCoordinatingCenter().getHealthcareSite());
    }
    if (entity instanceof Study) {
      for (StudyOrganization so : ((Study) entity).getStudyOrganizations()) {
        hcsList.add(so.getHealthcareSite());
      }
    }
    // defaulting to the hosting site if nothing is found
    if (hcsList.size() == 0) {
      String localNciCode = this.configuration.get(Configuration.LOCAL_NCI_INSTITUTE_CODE);
      hcsList.add(healthcareSiteDao.getByPrimaryIdentifierFromLocal(localNciCode));
    }
    removeDuplicates(hcsList);
    return hcsList;
  }