1   /* Copyright 2002-2025 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  
19  import java.io.IOException;
20  import java.util.ArrayList;
21  import java.util.List;
22  
23  /** Manager for {@link DataFilter data filters}.
24   * <p>
25   * This manager holds a set of filters and applies all the relevant
26   * ones by building a stack that transforms a raw {@link DataSource}
27   * into a processed {@link DataSource}.
28   * </p>
29   * @see DataSource
30   * @see DataFilter
31   * @author Luc Maisonobe
32   * @since 11.0
33   */
34  public class FiltersManager {
35  
36      /** Supported filters. */
37      private final List<DataFilter> filters;
38  
39      /** Build an empty manager.
40       */
41      public FiltersManager() {
42          this.filters = new ArrayList<>();
43      }
44  
45      /** Add a data filter.
46       * @param filter filter to add
47       * @see #applyRelevantFilters(DataSource)
48       * @see #clearFilters()
49       */
50      public void addFilter(final DataFilter filter) {
51          filters.add(filter);
52      }
53  
54      /** Remove all data filters.
55       * @see #addFilter(DataFilter)
56       */
57      public void clearFilters() {
58          filters.clear();
59      }
60  
61      /** Apply all the relevant data filters, taking care of layers.
62       * <p>
63       * If several filters can be applied, they will all be applied
64       * as a stack, even recursively if required. This means that if
65       * filter A applies to files with names of the form base.ext.a
66       * and filter B applies to files with names of the form base.ext.b,
67       * then providing base.ext.a.b.a will result in filter A being
68       * applied on top of filter B which itself is applied on top of
69       * another instance of filter A.
70       * </p>
71       * @param original original data source
72       * @return fully filtered data source
73       * @exception IOException if some data stream cannot be filtered
74       * @see #addFilter(DataFilter)
75       * @see #clearFilters()
76       * @since 9.2
77       */
78      public DataSource applyRelevantFilters(final DataSource original)
79          throws IOException {
80          DataSource top = original;
81          for (boolean filtering = true; filtering;) {
82              filtering = false;
83              for (final DataFilter filter : filters) {
84                  final DataSource filtered = filter.filter(top);
85                  if (filtered != top) {
86                      // the filter has been applied, we need to restart the loop
87                      top       = filtered;
88                      filtering = true;
89                      break;
90                  }
91              }
92          }
93          return top;
94      }
95  
96  }