DirectoryCrawler.java

  1. /* Copyright 2002-2018 CS Systèmes d'Information
  2.  * Licensed to CS Systèmes d'Information (CS) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * CS licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *   http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.orekit.data;

  18. import java.io.File;
  19. import java.io.FileInputStream;
  20. import java.io.IOException;
  21. import java.io.InputStream;
  22. import java.text.ParseException;
  23. import java.util.Arrays;
  24. import java.util.Comparator;
  25. import java.util.regex.Pattern;

  26. import org.hipparchus.exception.DummyLocalizable;
  27. import org.orekit.errors.OrekitException;
  28. import org.orekit.errors.OrekitMessages;


  29. /**  Provider for data files stored in a directories tree on filesystem.

  30.  * <p>
  31.  * This class handles data files recursively starting from a root directories
  32.  * tree. The organization of files in the directories is free. There may be
  33.  * sub-directories to any level. All sub-directories are browsed and all terminal
  34.  * files are checked for loading.
  35.  * </p>
  36.  * <p>
  37.  * Gzip-compressed files are supported.
  38.  * </p>
  39.  * <p>
  40.  * Zip archives entries are supported recursively.
  41.  * </p>
  42.  * <p>
  43.  * This is a simple application of the <code>visitor</code> design pattern for
  44.  * directory hierarchy crawling.
  45.  * </p>
  46.  * @see DataProvidersManager
  47.  * @author Luc Maisonobe
  48.  */
  49. public class DirectoryCrawler implements DataProvider {

  50.     /** Root directory. */
  51.     private final File root;

  52.     /** Build a data files crawler.
  53.      * @param root root of the directories tree (must be a directory)
  54.      * @exception OrekitException if root is not a directory
  55.      */
  56.     public DirectoryCrawler(final File root) throws OrekitException {
  57.         if (!root.isDirectory()) {
  58.             throw new OrekitException(OrekitMessages.NOT_A_DIRECTORY, root.getAbsolutePath());
  59.         }
  60.         this.root = root;
  61.     }

  62.     /** {@inheritDoc} */
  63.     public boolean feed(final Pattern supported, final DataLoader visitor)
  64.         throws OrekitException {
  65.         try {
  66.             return feed(supported, visitor, root);
  67.         } catch (IOException ioe) {
  68.             throw new OrekitException(ioe, new DummyLocalizable(ioe.getMessage()));
  69.         } catch (ParseException pe) {
  70.             throw new OrekitException(pe, new DummyLocalizable(pe.getMessage()));
  71.         }
  72.     }

  73.     /** Feed a data file loader by browsing a directory hierarchy.
  74.      * @param supported pattern for file names supported by the visitor
  75.      * @param visitor data file visitor to feed
  76.      * @param directory current directory
  77.      * @exception OrekitException if some data is missing, duplicated
  78.      * or can't be read
  79.      * @return true if something has been loaded
  80.      * @exception IOException if data cannot be read
  81.      * @exception ParseException if data cannot be read
  82.      */
  83.     private boolean feed(final Pattern supported, final DataLoader visitor, final File directory)
  84.         throws OrekitException, IOException, ParseException {

  85.         // search in current directory
  86.         final File[] list = directory.listFiles();
  87.         Arrays.sort(list, new Comparator<File>() {
  88.             @Override
  89.             public int compare(final File o1, final File o2) {
  90.                 return o1.compareTo(o2);
  91.             }
  92.         });

  93.         OrekitException delayedException = null;
  94.         boolean loaded = false;
  95.         for (int i = 0; i < list.length; ++i) {
  96.             try {
  97.                 if (visitor.stillAcceptsData()) {
  98.                     final File file = list[i];
  99.                     if (file.isDirectory()) {

  100.                         // recurse in the sub-directory
  101.                         loaded = feed(supported, visitor, file) || loaded;

  102.                     } else if (ZIP_ARCHIVE_PATTERN.matcher(file.getName()).matches()) {

  103.                         // browse inside the zip/jar file
  104.                         final DataProvider zipProvider = new ZipJarCrawler(file);
  105.                         loaded = zipProvider.feed(supported, visitor) || loaded;

  106.                     } else {

  107.                         // apply all registered filters
  108.                         NamedData data = new NamedData(file.getName(), () -> new FileInputStream(file));
  109.                         data = DataProvidersManager.getInstance().applyAllFilters(data);

  110.                         if (supported.matcher(data.getName()).matches()) {
  111.                             // visit the current file
  112.                             try (InputStream input = data.getStreamOpener().openStream()) {
  113.                                 visitor.loadData(input, file.getPath());
  114.                                 loaded = true;
  115.                             }
  116.                         }

  117.                     }
  118.                 }
  119.             } catch (OrekitException oe) {
  120.                 delayedException = oe;
  121.             }

  122.         }

  123.         if (!loaded && delayedException != null) {
  124.             throw delayedException;
  125.         }

  126.         return loaded;

  127.     }

  128. }