BlockParser.java

  1. /* Copyright 2022-2025 Luc Maisonobe
  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.files.sinex;

  18. import java.util.ArrayList;
  19. import java.util.List;
  20. import java.util.function.Predicate;
  21. import java.util.regex.Matcher;
  22. import java.util.regex.Pattern;

  23. /** Parser for SINEX block.
  24.  * @param <T> type of the sinex files parse info
  25.  * @author Luc Maisonobe
  26.  * @since 13.0
  27.  */
  28. class BlockParser<T extends ParseInfo<?>> implements LineParser<T> {

  29.     /** Start block pattern. */
  30.     private final Pattern startPattern;

  31.     /** End block pattern. */
  32.     private Pattern endPattern;

  33.     /** Allowed parsers when dealing within this block (content + end marker). */
  34.     private final List<LineParser<T>> inBlockParsers;

  35.     /** Allowed parsers when leaving this block. */
  36.     private List<LineParser<T>> siblingParsers;

  37.     /** Simple constructor.
  38.      * @param blockId    regular expression for block name
  39.      * @param predicates predicates for parsing block content lines
  40.      */
  41.     protected BlockParser(final String blockId, final List<Predicate<T>> predicates) {
  42.         this.startPattern   = Pattern.compile("^\\+(" + blockId + ") *$");
  43.         this.endPattern     = null;
  44.         this.inBlockParsers = new ArrayList<>(1 + predicates.size());
  45.         for (final Predicate<T> predicate : predicates) {
  46.             inBlockParsers.add(new LineParser<T>() {

  47.                 /** {@inheritDoc} */
  48.                 @Override
  49.                 public boolean parseIfRecognized(final T parseInfo) {
  50.                     return predicate.test(parseInfo);
  51.                 }

  52.                 /** {@inheritDoc} */
  53.                 @Override
  54.                 public Iterable<LineParser<T>> allowedNextParsers(final T parseInfo) {
  55.                     return inBlockParsers;
  56.                 }

  57.             });
  58.         }
  59.         this.inBlockParsers.add(this);
  60.     }

  61.     /** Set allowed parsers when leaving this block.
  62.      * @param siblingParsers allowed parsers when leaving this block
  63.      */
  64.     public void setSiblingParsers(final List<LineParser<T>> siblingParsers) {
  65.         this.siblingParsers = siblingParsers;
  66.     }

  67.     /** {@inheritDoc} */
  68.     @Override
  69.     public boolean parseIfRecognized(final T parseInfo) {
  70.         return outsideBlock() ? checkEntering(parseInfo) : checkLeaving(parseInfo);
  71.     }

  72.     /** {@inheritDoc} */
  73.     @Override
  74.     public Iterable<LineParser<T>> allowedNextParsers(final T parseInfo) {
  75.         return outsideBlock()  ? siblingParsers : inBlockParsers;
  76.     }

  77.     /** Check if we are outside block.
  78.      * @return true if we are at block end
  79.      */
  80.     protected boolean outsideBlock() {
  81.         return endPattern == null;
  82.     }

  83.     /** Check if we are at the start marker.
  84.      * @param parseInfo holder for transient data
  85.      * @return true if we are at block start
  86.      */
  87.     protected boolean checkEntering(final T parseInfo) {
  88.         final Matcher matcher = startPattern.matcher(parseInfo.getLine());
  89.         if (matcher.matches()) {
  90.             // we are entering the block
  91.             endPattern = Pattern.compile("^-" + matcher.group(1) + " *$");
  92.             return true;
  93.         } else {
  94.             return false;
  95.         }
  96.     }

  97.     /** Check if we are at the end marker.
  98.      * @param parseInfo holder for transient data
  99.      * @return true if we are at block end
  100.      */
  101.     protected boolean checkLeaving(final T parseInfo) {
  102.         if (endPattern != null && endPattern.matcher(parseInfo.getLine()).matches()) {
  103.             endPattern = null;
  104.             return true;
  105.         } else {
  106.             return false;
  107.         }
  108.     }

  109. }