BlockParser.java
/* Copyright 2002-2024 Luc Maisonobe
* Licensed to CS GROUP (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.files.sinex;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** Parser for SINEX block.
* @param <T> type of the sinex files parse info
* @author Luc Maisonobe
* @since 13.0
*/
class BlockParser<T extends ParseInfo<?>> implements LineParser<T> {
/** Start block pattern. */
private final Pattern startPattern;
/** End block pattern. */
private Pattern endPattern;
/** Allowed parsers when dealing within this block (content + end marker). */
private final List<LineParser<T>> inBlockParsers;
/** Allowed parsers when leaving this block. */
private List<LineParser<T>> siblingParsers;
/** Simple constructor.
* @param blockId regular expression for block name
* @param predicates predicates for parsing block content lines
*/
protected BlockParser(final String blockId, final List<Predicate<T>> predicates) {
this.startPattern = Pattern.compile("^\\+(" + blockId + ") *$");
this.endPattern = null;
this.inBlockParsers = new ArrayList<>(1 + predicates.size());
for (final Predicate<T> predicate : predicates) {
inBlockParsers.add(new LineParser<T>() {
/** {@inheritDoc} */
@Override
public boolean parseIfRecognized(final T parseInfo) {
return predicate.test(parseInfo);
}
/** {@inheritDoc} */
@Override
public Iterable<LineParser<T>> allowedNextParsers(final T parseInfo) {
return inBlockParsers;
}
});
}
this.inBlockParsers.add(this);
}
/** Set allowed parsers when leaving this block.
* @param siblingParsers allowed parsers when leaving this block
*/
public void setSiblingParsers(final List<LineParser<T>> siblingParsers) {
this.siblingParsers = siblingParsers;
}
/** {@inheritDoc} */
@Override
public boolean parseIfRecognized(final T parseInfo) {
return outsideBlock() ? checkEntering(parseInfo) : checkLeaving(parseInfo);
}
/** {@inheritDoc} */
@Override
public Iterable<LineParser<T>> allowedNextParsers(final T parseInfo) {
return outsideBlock() ? siblingParsers : inBlockParsers;
}
/** Check if we are outside block.
* @return true if we are at block end
*/
protected boolean outsideBlock() {
return endPattern == null;
}
/** Check if we are at the start marker.
* @param parseInfo holder for transient data
* @return true if we are at block start
*/
protected boolean checkEntering(final T parseInfo) {
final Matcher matcher = startPattern.matcher(parseInfo.getLine());
if (matcher.matches()) {
// we are entering the block
endPattern = Pattern.compile("^-" + matcher.group(1) + " *$");
return true;
} else {
return false;
}
}
/** Check if we are at the end marker.
* @param parseInfo holder for transient data
* @return true if we are at block end
*/
protected boolean checkLeaving(final T parseInfo) {
if (endPattern != null && endPattern.matcher(parseInfo.getLine()).matches()) {
endPattern = null;
return true;
} else {
return false;
}
}
}