TopNLDirectoryScanner.java

  1. /*
  2.  * Copyright (C) 2017 B3Partners B.V.
  3.  */
  4. package nl.b3p.brmo.service.scanner;

  5. import static nl.b3p.brmo.persistence.staging.AutomatischProces.ProcessingStatus.ERROR;
  6. import static nl.b3p.brmo.persistence.staging.AutomatischProces.ProcessingStatus.PROCESSING;
  7. import static nl.b3p.brmo.persistence.staging.AutomatischProces.ProcessingStatus.WAITING;
  8. import static nl.b3p.topnl.TopNLType.*;

  9. import java.io.File;
  10. import java.io.FilenameFilter;
  11. import java.text.SimpleDateFormat;
  12. import java.util.ArrayList;
  13. import java.util.Arrays;
  14. import java.util.Calendar;
  15. import java.util.Collections;
  16. import java.util.Date;
  17. import java.util.HashMap;
  18. import java.util.List;
  19. import java.util.Map;
  20. import javax.persistence.Transient;
  21. import nl.b3p.brmo.loader.util.BrmoException;
  22. import nl.b3p.brmo.persistence.staging.AutomatischProces;
  23. import nl.b3p.brmo.persistence.staging.ClobElement;
  24. import nl.b3p.brmo.persistence.staging.LaadProces;
  25. import nl.b3p.brmo.persistence.staging.TopNLScannerProces;
  26. import org.apache.commons.logging.Log;
  27. import org.apache.commons.logging.LogFactory;
  28. import org.stripesstuff.stripersist.Stripersist;

  29. /**
  30.  * Directory scanner for topNL 10/50/100/250 files.
  31.  *
  32.  * @author Meine Toonen
  33.  */
  34. public class TopNLDirectoryScanner extends AbstractExecutableProces {

  35.   private static final Log LOG = LogFactory.getLog(TopNLDirectoryScanner.class);

  36.   private final TopNLScannerProces config;
  37.   private final int defaultCommitPageSize = 1000;
  38.   @Transient private ProgressUpdateListener listener;

  39.   @Transient private Integer filterAlVerwerkt = 0;
  40.   @Transient private Integer aantalGeladen = 0;
  41.   @Transient private Integer progress = 0;

  42.   public static final String[] subdirectoryNames = {
  43.     TOP10NL.getType(), TOP50NL.getType(), TOP100NL.getType(), TOP250NL.getType()
  44.   };

  45.   public TopNLDirectoryScanner(TopNLScannerProces config) {
  46.     this.config = config;
  47.   }

  48.   @Override
  49.   public void execute() throws BrmoException {
  50.     this.execute(
  51.         new ProgressUpdateListener() {
  52.           @Override
  53.           public void total(long total) {}

  54.           @Override
  55.           public void progress(long progress) {}

  56.           @Override
  57.           public void exception(Throwable t) {
  58.             LOG.error(t);
  59.           }

  60.           @Override
  61.           public void updateStatus(String status) {}

  62.           @Override
  63.           public void addLog(String log) {}
  64.         });
  65.   }

  66.   @Override
  67.   public void execute(ProgressUpdateListener listener) {
  68.     this.listener = listener;
  69.     config.setStatus(PROCESSING);
  70.     StringBuilder sb = new StringBuilder(AutomatischProces.LOG_NEWLINE);
  71.     String oldLog = config.getLogfile();
  72.     if (oldLog != null) {
  73.       if (oldLog.length() > OLD_LOG_LENGTH) {
  74.         sb.append(oldLog.substring(oldLog.length() - OLD_LOG_LENGTH / 10));
  75.       } else {
  76.         sb.append(oldLog);
  77.       }
  78.     }

  79.     String msg =
  80.         String.format(
  81.             "De TopNL scanner met ID %d is gestart op %tc.",
  82.             config.getId(), Calendar.getInstance());
  83.     LOG.info(msg);
  84.     listener.addLog(msg);
  85.     sb.append(msg);

  86.     // validatie van de directories, kunnen we lezen/bladeren en evt. schrijven?
  87.     final File scanDirectory = new File(this.config.getScanDirectory());
  88.     if (!scanDirectory.isDirectory() || !scanDirectory.canExecute()) {
  89.       config.setStatus(ERROR);
  90.       msg = String.format("De scan directory '%s' is geen executable directory", scanDirectory);
  91.       config.setLogfile(msg);
  92.       config.setSamenvatting("Er is een fout opgetreden, details staan in de logs");
  93.       this.listener.exception(new BrmoException(msg));
  94.       return;
  95.     }

  96.     config.setLogfile(sb.toString());
  97.     int total = 0;
  98.     Map<String, List<File>> filesPerDir = new HashMap<>();
  99.     FilenameFilter ff = (dir, name) -> name.toLowerCase().endsWith(".gml");
  100.     for (String topNLDir : subdirectoryNames) {
  101.       File subdir = new File(scanDirectory, topNLDir);
  102.       // File files[] = subdir.listFiles();
  103.       List<File> fs = getFilesFromDirectory(subdir, ff);
  104.       total += fs.size();
  105.       filesPerDir.put(topNLDir, fs);
  106.     }

  107.     listener.total(total);
  108.     for (String topNLDir : subdirectoryNames) {
  109.       List<File> files = filesPerDir.get(topNLDir);
  110.       Collections.sort(files);

  111.       processTopNLDirectory(files, scanDirectory, topNLDir);
  112.     }

  113.     Stripersist.getEntityManager().flush();
  114.     Stripersist.getEntityManager().getTransaction().commit();
  115.     Stripersist.getEntityManager().clear();
  116.   }

  117.   private List<File> getFilesFromDirectory(File dir, FilenameFilter ff) {
  118.     List<File> files = new ArrayList<>();
  119.     File[] fs = dir.listFiles(ff);
  120.     files.addAll(Arrays.asList(fs));

  121.     File[] dirs = dir.listFiles();
  122.     for (File d : dirs) {
  123.       if (d.isDirectory()) {
  124.         files.addAll(getFilesFromDirectory(d, ff));
  125.       }
  126.     }

  127.     return files;
  128.   }

  129.   /**
  130.    * verwerk een bestandenlijst.
  131.    *
  132.    * @param files array met xml bestanden
  133.    * @param scanDirectory directory met xml bestanden
  134.    * @param soort aanduiding
  135.    */
  136.   private void processTopNLDirectory(List<File> files, File scanDirectory, String soort) {
  137.     StringBuilder sb = new StringBuilder(AutomatischProces.LOG_NEWLINE + config.getLogfile());
  138.     String msg;
  139.     SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
  140.     int commitPageSize = this.getCommitPageSize();

  141.     msg = String.format("Laden van TopNL type %s.", soort);
  142.     LOG.info(msg);

  143.     listener.addLog(msg);
  144.     for (File f : files) {
  145.       if (f.isDirectory()) {
  146.         continue;
  147.       }
  148.       msg = String.format("Bestand %s is gevonden in %s.", f, scanDirectory);
  149.       LOG.info(msg);
  150.       listener.addLog(msg);
  151.       sb.append(AutomatischProces.LOG_NEWLINE).append(msg).append(AutomatischProces.LOG_NEWLINE);
  152.       if (this.isDuplicaatLaadProces(f, soort)) {
  153.         msg = String.format("  Bestand %s is een duplicaat en wordt overgeslagen.", f);
  154.         listener.addLog(msg);
  155.         LOG.info(msg);
  156.         sb.append(msg).append(AutomatischProces.LOG_NEWLINE);
  157.         filterAlVerwerkt++;
  158.       } else {
  159.         LaadProces lp = new LaadProces();
  160.         lp.setBestand_naam(getBestandsNaam(f));
  161.         lp.setBestand_datum(getBestandsDatum(f));
  162.         lp.setSoort(soort);
  163.         lp.setStatus(LaadProces.STATUS.STAGING_OK);
  164.         lp.setOpmerking(
  165.             String.format(
  166.                 "Type %s bestand geladen van %s op %s",
  167.                 soort, f.getAbsolutePath(), sdf.format(new Date())));
  168.         lp.setAutomatischProces(
  169.             Stripersist.getEntityManager().find(AutomatischProces.class, config.getId()));
  170.         Stripersist.getEntityManager().persist(lp);
  171.         Stripersist.getEntityManager().merge(this.config);

  172.         aantalGeladen++;
  173.         msg =
  174.             String.format(
  175.                 "  Bestand %s is geladen en heeft status: %s. En is van soort: %s",
  176.                 f, lp.getStatus(), soort);
  177.         LOG.info(msg);
  178.         this.listener.addLog(msg);
  179.         sb.append(msg).append(AutomatischProces.LOG_NEWLINE);
  180.         if (aantalGeladen % commitPageSize == 0) {
  181.           LOG.debug("Tussentijds opslaan van berichten, 'commitPageSize' is bereikt");
  182.           Stripersist.getEntityManager().flush();
  183.           Stripersist.getEntityManager().getTransaction().commit();
  184.           Stripersist.getEntityManager().clear();
  185.         }
  186.       }
  187.       listener.progress(++progress);
  188.     }
  189.     msg = String.format("Klaar met run op %tc", Calendar.getInstance());
  190.     LOG.info(msg);
  191.     listener.updateStatus(msg);
  192.     listener.addLog(msg);
  193.     sb.append(msg);

  194.     listener.addLog("\n\n**** resultaat ****");
  195.     listener.addLog("\nAantal bestanden die al waren geladen: " + filterAlVerwerkt);
  196.     listener.addLog("\nAantal bestanden geladen: " + aantalGeladen + "\n");

  197.     config.setStatus(WAITING);
  198.     config.setLogfile(sb.toString());
  199.     config.setLastrun(new Date());
  200.     config.updateSamenvattingEnLogfile(
  201.         "Aantal bestanden die al waren verwerkt: "
  202.             + filterAlVerwerkt
  203.             + AutomatischProces.LOG_NEWLINE
  204.             + "Aantal bestanden geladen: "
  205.             + aantalGeladen
  206.             + AutomatischProces.LOG_NEWLINE);
  207.     Stripersist.getEntityManager().merge(config);
  208.   }

  209.   private int getCommitPageSize() {
  210.     int commitPageSize;
  211.     try {
  212.       String s = ClobElement.nullSafeGet(config.getConfig().get("commitPageSize"));
  213.       commitPageSize = Integer.parseInt(s);
  214.       if (commitPageSize < 1 || commitPageSize > defaultCommitPageSize) {
  215.         commitPageSize = defaultCommitPageSize;
  216.       }
  217.     } catch (NumberFormatException nfe) {
  218.       commitPageSize = defaultCommitPageSize;
  219.     }

  220.     LOG.debug("Instellen van commit page size op: " + commitPageSize);
  221.     return commitPageSize;
  222.   }
  223. }