AbstractListCrawler.java

  1. /* Copyright 2002-2024 CS GROUP
  2.  * Licensed to CS GROUP (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.IOException;
  19. import java.io.InputStream;
  20. import java.text.ParseException;
  21. import java.util.Arrays;
  22. import java.util.Collections;
  23. import java.util.List;
  24. import java.util.regex.Pattern;
  25. import java.util.stream.Collectors;

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


  28. /** Provider for data files defined in a list.
  29.  * <p>
  30.  * All {@link FiltersManager#addFilter(DataFilter) registered}
  31.  * {@link DataFilter filters} are applied.
  32.  * </p>
  33.  * <p>
  34.  * Zip archives entries are supported recursively.
  35.  * </p>
  36.  * @since 10.1
  37.  * @see DataProvidersManager
  38.  * @see NetworkCrawler
  39.  * @see FilesListCrawler
  40.  * @author Luc Maisonobe
  41.  * @param <T> The type of resource, e.g. File or URL.
  42.  */
  43. public abstract class AbstractListCrawler<T> implements DataProvider {

  44.     /** Inputs list. */
  45.     private final List<T> inputs;

  46.     /** Build a data classpath crawler.
  47.      * @param inputs list of inputs (may be empty if {@link #addInput(Object) addInput} is called later)
  48.      */
  49.     @SafeVarargs
  50.     protected AbstractListCrawler(final T... inputs) {
  51.         this.inputs = Arrays.stream(inputs).collect(Collectors.toList());
  52.     }

  53.     /** Add an input to the supported list.
  54.      * @param input input to add
  55.      */
  56.     public void addInput(final T input) {
  57.         inputs.add(input);
  58.     }

  59.     /** Get the list of inputs supported by the instance.
  60.      * @return unmodifiable view of the list of inputs supported by the instance
  61.      */
  62.     public List<T> getInputs() {
  63.         return Collections.unmodifiableList(inputs);
  64.     }

  65.     /** Get the complete name of a input.
  66.      * @param input input to consider
  67.      * @return complete name of the input
  68.      */
  69.     protected abstract String getCompleteName(T input);

  70.     /** Get the base name of an input.
  71.      * @param input input to consider
  72.      * @return base name of the input
  73.      */
  74.     protected abstract String getBaseName(T input);

  75.     /** Get a zip/jar crawler for an input.
  76.      * @param input input to consider
  77.      * @return zip/jar crawler for an input
  78.      */
  79.     protected abstract ZipJarCrawler getZipJarCrawler(T input);

  80.     /** Get the stream to read from an input.
  81.      * @param input input to read from
  82.      * @return stream to read the content of the input
  83.      * @throws IOException if the input cannot be opened for reading
  84.      */
  85.     protected abstract InputStream getStream(T input) throws IOException;

  86.     /** {@inheritDoc} */
  87.     @Override
  88.     public boolean feed(final Pattern supported,
  89.                         final DataLoader visitor,
  90.                         final DataProvidersManager manager) {

  91.         try {
  92.             OrekitException delayedException = null;
  93.             boolean loaded = false;
  94.             for (T input : inputs) {
  95.                 try {

  96.                     if (visitor.stillAcceptsData()) {
  97.                         final String name     = getCompleteName(input);
  98.                         final String fileName = getBaseName(input);
  99.                         if (ZIP_ARCHIVE_PATTERN.matcher(fileName).matches()) {

  100.                             // browse inside the zip/jar file
  101.                             getZipJarCrawler(input).feed(supported, visitor, manager);
  102.                             loaded = true;

  103.                         } else {

  104.                             // apply all registered filters
  105.                             DataSource data = new DataSource(fileName, () -> getStream(input));
  106.                             data = manager.getFiltersManager().applyRelevantFilters(data);

  107.                             if (supported.matcher(data.getName()).matches()) {
  108.                                 // visit the current file
  109.                                 try (InputStream is = data.getOpener().openStreamOnce()) {
  110.                                     visitor.loadData(is, name);
  111.                                     loaded = true;
  112.                                 }
  113.                             }

  114.                         }
  115.                     }

  116.                 } catch (OrekitException oe) {
  117.                     // maybe the next path component will be able to provide data
  118.                     // wait until all components have been tried
  119.                     delayedException = oe;
  120.                 }
  121.             }

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

  125.             return loaded;

  126.         } catch (IOException | ParseException e) {
  127.             throw new OrekitException(e, new DummyLocalizable(e.getMessage()));
  128.         }

  129.     }

  130. }