예제 #1
0
파일: Rss.java 프로젝트: keithmasters/zeprs
  /**
   * Imports patient records from remote pc.
   *
   * @param conn
   * @param urlString - url of feed
   * @param view - if not 0, simply parses rss feed and provides output.
   * @param comments - messages generated during import process
   * @param start - indicates if this is the first time this feed has been imported.
   * @param siteId - id of site being imported.
   * @param reload
   * @param refreshPatientZeprsId
   * @return status message
   * @throws Exception
   */
  public static String importFeed(
      Connection conn,
      String urlString,
      Boolean view,
      StringBuffer comments,
      Long start,
      Long siteId,
      Long reload,
      String refreshPatientZeprsId)
      throws Exception, ConnectException, NoRouteToHostException {
    // download the rss file from the remote server
    URL feedUrl = new URL(urlString);
    HttpURLConnection httpcon = (HttpURLConnection) feedUrl.openConnection();
    boolean isProxied = httpcon.usingProxy();
    if (isProxied) {
      log.debug(" Proxied: " + isProxied);
    }
    // BASE64Encoder is Sun proprietary encoder. Use Apache commons Base64 codec instead.
    String credentials = new sun.misc.BASE64Encoder().encode("zepadmin:zepadmin11".getBytes());
    /*String encodeString = "zepadmin:zepadmin11";
    Base64 encoder = new Base64();
    String encoding = String.valueOf(encoder.encode(encodeString.getBytes()));*/
    httpcon.setRequestProperty("Authorization", "Basic " + credentials);

    final WireFeedInput input = new WireFeedInput();
    WireFeed rssFeed = null;
    XmlReader reader = null;
    String message = null;
    String siteAbbrev = null;
    Channel channel = null;
    java.util.Date lastBuildDate = null;

    Site site = (Site) DynaSiteObjects.getClinicMap().get(siteId);
    siteAbbrev = site.getAbbreviation();

    try {
      String importFilePath =
          org.cidrz.webapp.dynasite.Constants.ARCHIVE_PATH
              + siteAbbrev
              + Constants.pathSep
              + "import"
              + Constants.pathSep;
      // Save the feed to the local filesystem. This will be used to help the master create its own
      // feed for this site.
      BufferedInputStream in = null;
      in = new BufferedInputStream(httpcon.getInputStream());
      String importedRssPath = importFilePath + "rss.xml";
      Writer writer = new FileWriter(importedRssPath);
      for (int c = in.read(); c != -1; c = in.read()) {
        writer.write(c);
      }
      writer.close();

      // make a hashmap of zeprs id's:last_modified from database
      HashMap<String, Timestamp> localPatientMap = new HashMap<String, Timestamp>();
      ResultSet updatedPatients = PatientDAO.getAllRS(conn);
      while (updatedPatients.next()) {
        String zeprsId = updatedPatients.getString("district_patient_id");
        Timestamp lastModified = updatedPatients.getTimestamp("last_modified");
        // Long site_id = updatedPatients.getLong("site_id");
        String fileName = zeprsId + ".xml";
        localPatientMap.put(fileName, lastModified);
      }
      int changes = 0;
      // check what site this pc is publishing
      Long publisherSiteId = null;
      Publisher publisher = null;
      String publisherFile = Constants.ARCHIVE_PATH + "publisher.xml";
      try {
        publisher = (Publisher) XmlUtils.getOne(publisherFile);
        publisherSiteId = publisher.getSiteId();
      } catch (FileNotFoundException e) {
        // it's ok - file not created yet.
      }
      boolean process = true;
      Timestamp buildDate = null;
      try {
        UpdateLog updateLog = (UpdateLog) UpdateLogDAO.getLastUpdate(conn, siteAbbrev);
        buildDate = updateLog.getBuilddate();
      } catch (SQLException e) {
        e.printStackTrace();
      } catch (ServletException e) {
        e.printStackTrace();
      } catch (ObjectNotFoundException e) {
        // log.debug("No entries in updateLog - this must be a new site subscription for " +
        // siteAbbrev + ". Forcing import of records for this site. ");
        log.debug(
            "No entries in updateLog - this must be a new site subscription for "
                + siteAbbrev
                + ". ");
        // cekelley May 28, 2009 - disabled forced import (reload) of records. Unnecessary and
        // time-consuming.
        // reload = Long.valueOf("1");
        comments.append("Subscribed to site: " + siteAbbrev + ". ");
      }

      File importedRssFile = new File(importedRssPath);
      reader = new XmlReader(importedRssFile);
      rssFeed = input.build(reader);
      rssFeed.setFeedType("rss_2.0");
      channel = (Channel) rssFeed;
      List items = channel.getItems();
      siteAbbrev = channel.getTitle();
      lastBuildDate = channel.getLastBuildDate();
      String previousSiteAbbrev = null;

      for (int i = 0; i < items.size(); i++) {
        process = true;
        Item item = (Item) items.get(i);
        String link = item.getLink();
        String fileName = item.getTitle();
        Long clinicHomeId = null;
        if (item.getAuthor() != null) {
          clinicHomeId = Long.valueOf(item.getAuthor());
        }
        if (publisherSiteId != null
            && (publisherSiteId.longValue() != clinicHomeId.longValue())
            && !publisher.getSite().getSiteAlphaId().equals("MST")) {
          process = false;
        } else if (publisher.getSite().getSiteAlphaId().equals("MST")) {
          process = true; // MST site will update no matter the sites conti
        }
        java.util.Date pubDate = item.getPubDate();
        Timestamp lastModifiedTimestamp = localPatientMap.get(fileName);
        java.util.Date currentLastModified = null;
        if (lastModifiedTimestamp != null) {
          currentLastModified = DateUtils.toDate(lastModifiedTimestamp);
        }

        if ((DynaSiteObjects.getStatusMap().get("Halt-Feed-Imports") != null)
            && (DynaSiteObjects.getStatusMap().get("Halt-Feed-Imports").equals("true"))) {
          log.debug("Halting Feed Imports: Halt-Feed-Imports = true");
          break;
        }
        site = (Site) DynaSiteObjects.getClinicMap().get(clinicHomeId);
        try {
          siteAbbrev = site.getAbbreviation();
          previousSiteAbbrev = siteAbbrev;
        } catch (NullPointerException e) {
          log.debug(
              "Site not found for " + fileName + " Setting siteAbbrev to " + previousSiteAbbrev);
        }

        URL patientUrl = new URL(link);
        //  if (view == 0) {
        if (process) {
          // If imported record's pubDate > most recent buildDate, process. Previously we only
          // checked if
          // currentLastModified != pubdate, but that would cause every out-of-date record to be
          // imported.
          if (refreshPatientZeprsId != null
              && (refreshPatientZeprsId.concat(".xml").equals(fileName))) {
            try {
              importPatientRecord(
                  currentLastModified,
                  fileName,
                  pubDate,
                  importFilePath,
                  patientUrl,
                  credentials,
                  conn,
                  comments,
                  Long.valueOf(1),
                  siteAbbrev,
                  view);
            } catch (Exception e) {
              log.debug(e);
            }
          } else {
            if ((reload != null)
                || (view)
                || (currentLastModified == null)
                || (buildDate == null)
                || (buildDate != null && pubDate.getTime() > buildDate.getTime())) {
              changes++;
              try {
                importPatientRecord(
                    currentLastModified,
                    fileName,
                    pubDate,
                    importFilePath,
                    patientUrl,
                    credentials,
                    conn,
                    comments,
                    reload,
                    siteAbbrev,
                    view);
              } catch (Exception e) {
                log.debug(e);
                e.printStackTrace();
              }
            }
          }
        }
        // }
      }
    } catch (SocketException e1) {
      message = "Unable to connect to host for feed: " + urlString;
      log.debug(message);
    }

    if (!view) {
      if (comments.toString().equals("")) {
        message = "No records to update.";
      } else {
        Timestamp updated = new Timestamp(System.currentTimeMillis());
        // reset siteAbbrev to channel
        siteAbbrev = channel.getTitle();
        String commentsString = null;
        if (comments.toString().length() > 500) {
          commentsString = comments.toString().substring(0, 500);
        } else {
          commentsString = comments.toString();
        }
        UpdateLogDAO.save(
            conn, updated, new Timestamp(lastBuildDate.getTime()), siteAbbrev, commentsString);
        Subscription subscription = (Subscription) SubscriptionDAO.getOne(conn, urlString);
        // this is getting imported for the first time either manually or via a scheduled job.
        if (start != null || subscription.getDatesubscribed() == null) {
          Timestamp datesubscribed = new Timestamp(System.currentTimeMillis());
          SubscriptionDAO.updateSite(conn, subscription.getId(), siteAbbrev, datesubscribed);
        }
        // log.debug(comments);
      }
    }
    return message;
  }
예제 #2
0
파일: Rss.java 프로젝트: keithmasters/zeprs
  /**
   * Exports a list of patients at the clinic and their records. Compare a list of all patients in
   * the rss file last published by the server with a list of patients in the system. Publish any
   * changed records if they are not equal If site is the master data center (such as ZEPRS), loops
   * through each site's patient list and creates RSS file for each site. Note that a patient's xml
   * record could be listed in more than one site - The patient listing for each site selects from
   * patient_status.site_id. Download the remote site listing and see if there are adidtional
   * patients who may have been transferred to another site - UTH for instance. This enables sites
   * to see records of their regular patients who were referred to another site. Also creates an
   * index which is used on remote sites for finding patient records within the imported archive.
   *
   * @param conn
   * @param siteAbbrev - if siteabbrev = ZEP,, export all sites w/ their own rss feed.
   * @param siteId
   * @param checkXml - true if you want to check if xml files have been generated.
   * @return
   * @throws SQLException
   * @throws ServletException
   * @throws ObjectNotFoundException
   * @throws IOException
   * @throws ClassNotFoundException
   * @throws IllegalAccessException
   * @throws PersistenceException
   * @throws InvocationTargetException
   * @throws FeedException
   */
  public static String createSiteRssFiles(
      Connection conn, String siteAbbrev, Long siteId, Boolean checkXml)
      throws SQLException, ServletException, ObjectNotFoundException, IOException,
          ClassNotFoundException, IllegalAccessException, PersistenceException,
          InvocationTargetException, FeedException {
    String message = null;
    StringBuffer sbuf = new StringBuffer();
    Timestamp beginDate = null;
    Timestamp endDate = new Timestamp(System.currentTimeMillis());
    Map statusMap = DynaSiteObjects.getStatusMap();
    Publisher publisher = null;
    String publisherFile = Constants.ARCHIVE_PATH + "publisher.xml";
    String ipAddress = null;
    Boolean renderAllSites = false;
    try {
      publisher = (Publisher) XmlUtils.getOne(publisherFile);
      ipAddress = publisher.getUrl();
    } catch (FileNotFoundException e) {
      log.debug("publisher.xml not available - cannot render site rss files.");
    }

    if (publisher != null) {
      // check the db for the date of the last archive.
      // Fetch list of updated patients. This list is used to generate each patient's updated xml
      // file
      ResultSet updatedPatients = null;
      try {
        ArchiveLog mostRecentArchive = (ArchiveLog) ArchiveDAO.getOne(conn);
        beginDate = mostRecentArchive.getArchived();
        updatedPatients = PatientDAO.getAllDate(conn, beginDate, endDate);
      } catch (SQLException e) {
        e.printStackTrace();
      } catch (ServletException e) {
        e.printStackTrace();
      } catch (ObjectNotFoundException e) {
        // This is the first time this has been run - archive all.
        updatedPatients = PatientDAO.getAllRS(conn);
        renderAllSites = true;
      }

      // update date of last archive before any more records get updated.
      Long archiveId = (Long) ArchiveDAO.save(conn, endDate, (long) 1);
      HashMap updatedMap = new HashMap();
      while (updatedPatients.next()) {
        Long updatedId = updatedPatients.getLong("id");
        updatedMap.put(updatedId, updatedId);
      }
      List<Site> clinics = null;

      if (siteAbbrev.equals("ZEP")) {
        // loop thorough all of the sites and render an rss file for each one.
        clinics = DynaSiteObjects.getClinics();
        // todo: reset to the big list - preset to KAL and AIR
        /*clinics = new ArrayList<Site>();
        Site site = (Site) DynaSiteObjects.getClinicMap().get(Long.valueOf(16));
        clinics.add(site);
        site = (Site) DynaSiteObjects.getClinicMap().get(Long.valueOf(1));
        clinics.add(site);*/
      } else {
        clinics = new ArrayList<Site>();
        Site site = (Site) DynaSiteObjects.getClinicMap().get(siteId);
        clinics.add(site);
      }
      // create the archive listing
      // StringBuffer indexBuffer = new StringBuffer();
      HashMap<String, String> indexMap = new HashMap<String, String>();
      int currentSiteNum = 0;
      int archivedPatientsAllSites = 0;
      for (Site site : clinics) {
        currentSiteNum++;
        int archivedPatientsThisSite = 0;
        siteAbbrev = site.getAbbreviation();
        siteId = site.getId();
        String rssFileName =
            org.cidrz.webapp.dynasite.Constants.ARCHIVE_PATH
                + siteAbbrev
                + Constants.pathSep
                + "rss.xml";
        Timestamp lastBuildDate = new Timestamp(System.currentTimeMillis());
        Channel feed = new Channel();
        String feedType = "rss_2.0";
        feed.setFeedType(feedType);
        feed.setDescription(siteAbbrev + " Patients");
        String port = Constants.APP_PORT;
        feed.setLink(
            "http://" + ipAddress + ":" + port + "/" + "archive/" + siteAbbrev + "/rss.xml");
        feed.setTitle(siteAbbrev); // Title is used to identify which site the feed is from.
        feed.setLastBuildDate(lastBuildDate);
        List entries = new ArrayList();
        // Loop through the list of all patients and see if their id exists in the updatedMap
        ResultSet patientListResultSet = PatientDAO.getAllSiteRS(conn, siteId);
        ArrayList<Patient> patientRssList = new ArrayList<Patient>();
        while (patientListResultSet.next()) {
          Long patientId = patientListResultSet.getLong("id");
          String zeprsId = patientListResultSet.getString("district_patient_id");
          String surname = patientListResultSet.getString("surname");
          Timestamp lastModified = patientListResultSet.getTimestamp("last_modified");
          Long clinicId =
              patientListResultSet.getLong(
                  "site_id"); // clinic the patient belongs to - should be the same as the site
                              // feed.
          Patient rssPatient = new Patient();
          rssPatient.setId(patientId);
          rssPatient.setDistrictPatientid(zeprsId);
          rssPatient.setSurname(surname);
          rssPatient.setLastModified(lastModified);
          rssPatient.setSiteId(clinicId);
          patientRssList.add(rssPatient);
        }
        HashMap<String, String> patientRssMap = new HashMap<String, String>();
        // loop through the patientRssList to weed out duplicates
        for (Patient patient : patientRssList) {
          String zeprsId = patient.getDistrictPatientid();
          patientRssMap.put(zeprsId, zeprsId);
        }
        String rssMessage =
            "Generating RSS and Patient Xml for "
                + siteAbbrev
                + " :"
                + currentSiteNum
                + " out of "
                + clinics.size()
                + " sites. "
                + updatedMap.size()
                + " patient records to be generated.";
        statusMap.put("RSS-message", rssMessage);
        if (renderAllSites == true) {
          log.debug(rssMessage);
        }
        // see if there is already a subscription to this site.
        String importFilePath =
            org.cidrz.webapp.dynasite.Constants.ARCHIVE_PATH
                + siteAbbrev
                + Constants.pathSep
                + "import"
                + Constants.pathSep;
        String importedRssPath = importFilePath + "rss.xml";
        // Reader reader = new BufferedReader((new FileReader(importedRssPath)));
        File importedRssFile = new File(importedRssPath);
        if (importedRssFile.exists() && importedRssFile.length() > 0) {
          final WireFeedInput input = new WireFeedInput();
          WireFeed rssFeed = null;
          XmlReader reader = null;
          Channel channel = null;
          reader = new XmlReader(importedRssFile);
          try {
            rssFeed = input.build(reader);
            rssFeed.setFeedType("rss_2.0");
            channel = (Channel) rssFeed;
            List items = channel.getItems();
            // siteAbbrev = channel.getTitle();
            // Create a list of patients the remote site is "interested" in.
            // ArrayList<String> subscribedPatientList = new ArrayList<String>();
            ArrayList<Patient> subscribedPatientList = new ArrayList<Patient>();
            for (int i = 0; i < items.size(); i++) {
              Item item = (Item) items.get(i);
              // String link = item.getLink();
              String fileName = item.getTitle();
              String zeprsId = fileName.replace(".xml", "");
              try {
                Patient rssPatient = PatientDAO.getOneFromZeprsId(conn, zeprsId);
                // check if the patient is not already in the patientRssList
                if (patientRssMap.get(zeprsId) == null) {
                  subscribedPatientList.add(rssPatient);
                }
              } catch (ObjectNotFoundException e) {
                // Patient may not yet be in system. It should be OK.
              }
            }
            patientRssList.addAll(subscribedPatientList);
          } catch (ParsingFeedException e1) {
            log.debug("Unable to parse RSS feed at " + importedRssPath);
          }
          reader.close();
        }
        // while (patientListResultSet.next()) {
        for (Patient rssPatient : patientRssList) {
          Long patientId = rssPatient.getId();
          String zeprsId = rssPatient.getDistrictPatientid();
          String surname = rssPatient.getSurname();
          Timestamp lastModified = rssPatient.getLastModified();
          Long clinicId =
              rssPatient
                  .getSiteId(); // clinic the patient belongs to - should be the same as the site
                                // feed.
          // get the siteAbbrev from the parent's record only
          // no longer need this part.
          /*try {
          	site = (Site) DynaSiteObjects.getClinicMap().get(clinicId);
          	siteAbbrev = site.getAbbreviation();
          } catch (Exception e) {
          	log.error("Incorrect site data for patient: " + zeprsId + " clinicId: " + clinicId);
          }*/
          String filePath =
              org.cidrz.webapp.dynasite.Constants.ARCHIVE_PATH
                  + siteAbbrev
                  + Constants.pathSep
                  + "local"
                  + Constants.pathSep;
          String fileName = getPatientFilename(zeprsId, surname, patientId);
          // write to the index
          // String indexValue = zeprsId + ":" + siteAbbrev + Constants.pathSep + "local" +
          // Constants.pathSep + fileName + "\n";
          // indexBuffer.append(indexValue);
          indexMap.put(
              zeprsId, siteAbbrev + Constants.pathSep + "local" + Constants.pathSep + fileName);
          // check if the xml file exists. This is useful when testing - you may not have all of the
          // xml files generated yet.
          boolean forceXml = false;
          if (checkXml != null) {
            File filecheck = new File(filePath + fileName);
            if (filecheck.length() == 0) {
              log.debug("Re-rendering file for : " + fileName + " in " + siteAbbrev + "/local.");
              forceXml = true;
            }
          }
          if (updatedMap.get(patientId) != null || forceXml) {
            PatientRecordUtils.archivePatient(conn, patientId, siteAbbrev, filePath, fileName);
            archivedPatientsThisSite++;
            archivedPatientsAllSites++;
            rssMessage =
                "Generating RSS and Patient Xml for "
                    + siteAbbrev
                    + ": "
                    + currentSiteNum
                    + " out of "
                    + clinics.size()
                    + " sites. "
                    + archivedPatientsAllSites
                    + " out of "
                    + updatedMap.size()
                    + " patient records have been generated. "
                    + "Current file: "
                    + filePath
                    + fileName;
            statusMap.put("RSS-message", rssMessage);
            // don't remove from the list because this patient may also be at another site
            // (referral).
            // updatedMap.remove(patientId);
          }
          if (lastModified == null) {
            lastModified = DateUtils.generateTimestamp();
            log.debug("Null lastModified for patient: " + zeprsId);
          }
          java.util.Date pubDate = new Date(lastModified.getTime());
          Item item;
          Description description;
          String url =
              "http://" + ipAddress + ":" + port + "/archive/" + siteAbbrev + "/local/" + fileName;
          item = new Item();
          item.setTitle(fileName);
          item.setLink(url);
          item.setPubDate(pubDate);
          item.setAuthor(clinicId.toString());
          Guid gd = new Guid();
          gd.setPermaLink(true);
          gd.setValue(url);
          item.setGuid(gd);
          description = new Description();
          description.setType("text/plain");
          description.setValue(clinicId.toString());
          item.setDescription(description);
          entries.add(item);
        }
        // Open the remote site RSS file and add patients who may have been transferred
        // ArrayList<String> remotePatientIdList = populateRemotePatientIdList(urlString);
        // log.debug("RSS feed being generated for " + siteAbbrev + " has " + entries.size() + "
        // patients. URL: " + rssFileName);
        sbuf.append(entries.size() + " patients added to " + siteAbbrev + "<br/>");
        feed.setItems(entries);
        Writer writer = new FileWriter(rssFileName);
        WireFeedOutput output = new WireFeedOutput();
        output.output(feed, writer);
        writer.close();
        entries.clear();
      }
      // create the archive listing
      /*Writer indexWriter = new FileWriter(Constants.MASTER_ARCHIVE_INDEX);
      indexWriter.write(indexBuffer.toString());
      indexWriter.flush();
      indexWriter.close();*/
      XmlUtils.save(indexMap, Constants.MASTER_ARCHIVE_INDEX_XML);
      // log.debug("writing index file to " + Constants.MASTER_ARCHIVE_INDEX_JS);
      // XmlUtils.saveJson(indexMap, Constants.MASTER_ARCHIVE_INDEX_JS);
      updatedMap.clear();
      indexMap.clear();
      String rssMessage = "Completed RSS and patient XML generation task";
      statusMap.put("RSS-message", rssMessage);
    }

    // Create the archive
    // Compress.zipDirectory(Constants.ARCHIVE_PATH, Constants.MASTER_ARCHIVE_ZIP);
    // Zip.zip(Constants.ARCHIVE_PATH, Constants.MASTER_ARCHIVE_ZIP,
    // Constants.MASTER_ARCHIVE_CHECKSUM);
    // Zip.CreateZipFile(new File(Constants.MASTER_ARCHIVE_ZIP), new File[]{new
    // File(Constants.ARCHIVE_PATH)}, false);
    message = sbuf.toString();
    return message;
  }