private void checkIfQuantifierApplied() { if (!quantifier.hasProperty(Quantifier.QuantifierProperty.SINGLE)) { throw new MalformedPatternException("Already applied quantifier to this Pattern. " + "Current quantifier is: " + quantifier); } }
/** * Appends a new pattern to the existing one. The new pattern enforces that there is no event matching this pattern * right after the preceding matched event. * * @param name Name of the new pattern * @return A new pattern which is appended to this one */ public Pattern<T, T> notNext(final String name) { if (quantifier.hasProperty(Quantifier.QuantifierProperty.OPTIONAL)) { throw new UnsupportedOperationException( "Specifying a pattern with an optional path to NOT condition is not supported yet. " + "You can simulate such pattern with two independent patterns, one with and the other without " + "the optional part."); } return new Pattern<>(name, this, ConsumingStrategy.NOT_NEXT, afterMatchSkipStrategy); }
/** * Appends a new pattern to the existing one. The new pattern enforces that there is no event matching this pattern * between the preceding pattern and succeeding this one. * * <p><b>NOTE:</b> There has to be other pattern after this one. * * @param name Name of the new pattern * @return A new pattern which is appended to this one */ public Pattern<T, T> notFollowedBy(final String name) { if (quantifier.hasProperty(Quantifier.QuantifierProperty.OPTIONAL)) { throw new UnsupportedOperationException( "Specifying a pattern with an optional path to NOT condition is not supported yet. " + "You can simulate such pattern with two independent patterns, one with and the other without " + "the optional part."); } return new Pattern<>(name, this, ConsumingStrategy.NOT_FOLLOW, afterMatchSkipStrategy); }
public void consecutive() { checkPattern(hasProperty(QuantifierProperty.LOOPING) || hasProperty(QuantifierProperty.TIMES), "Consecutive not applicable to " + this + "!"); checkPattern(innerConsumingStrategy != ConsumingStrategy.SKIP_TILL_ANY, "You can apply either combinations or consecutive, not both!"); checkPattern(innerConsumingStrategy != ConsumingStrategy.STRICT, "Consecutive already applied!"); innerConsumingStrategy = ConsumingStrategy.STRICT; }
public void optional() { checkPattern(!hasProperty(QuantifierProperty.OPTIONAL), "Optional already applied!"); checkPattern(!(consumingStrategy == ConsumingStrategy.NOT_NEXT || consumingStrategy == ConsumingStrategy.NOT_FOLLOW), "NOT pattern cannot be optional"); properties.add(Quantifier.QuantifierProperty.OPTIONAL); }
public void greedy() { checkPattern(!(innerConsumingStrategy == ConsumingStrategy.SKIP_TILL_ANY), "Option not applicable to FollowedByAny pattern"); checkPattern(!hasProperty(Quantifier.QuantifierProperty.SINGLE), "Option not applicable to singleton quantifier"); properties.add(QuantifierProperty.GREEDY); }
private void checkIfPreviousPatternGreedy() { if (previous != null && previous.getQuantifier().hasProperty(Quantifier.QuantifierProperty.GREEDY)) { throw new MalformedPatternException("Optional pattern cannot be preceded by greedy pattern"); } }
/** * Checks if the given pattern is optional. If the given pattern is the head of a group pattern, * the optional status depends on the group pattern. */ private boolean isPatternOptional(Pattern<T, ?> pattern) { if (headOfGroup(pattern)) { return isCurrentGroupPatternFirstOfLoop() && currentGroupPattern.getQuantifier().hasProperty(Quantifier.QuantifierProperty.OPTIONAL); } else { return pattern.getQuantifier().hasProperty(Quantifier.QuantifierProperty.OPTIONAL); } }
public void combinations() { checkPattern(!hasProperty(QuantifierProperty.SINGLE), "Combinations not applicable to " + this + "!"); checkPattern(innerConsumingStrategy != ConsumingStrategy.STRICT, "You can apply either combinations or consecutive, not both!"); checkPattern(innerConsumingStrategy != ConsumingStrategy.SKIP_TILL_ANY, "Combinations already applied!"); innerConsumingStrategy = ConsumingStrategy.SKIP_TILL_ANY; }
/** * Applies a stop condition for a looping state. It allows cleaning the underlying state. * * @param untilCondition a condition an event has to satisfy to stop collecting events into looping state * @return The same pattern with applied untilCondition */ public Pattern<T, F> until(IterativeCondition<F> untilCondition) { Preconditions.checkNotNull(untilCondition, "The condition cannot be null"); if (this.untilCondition != null) { throw new MalformedPatternException("Only one until condition can be applied."); } if (!quantifier.hasProperty(Quantifier.QuantifierProperty.LOOPING)) { throw new MalformedPatternException("The until condition is only applicable to looping states."); } ClosureCleaner.clean(untilCondition, true); this.untilCondition = untilCondition; return this; }
private State<T> convertPattern(final State<T> sinkState) { final State<T> lastSink; final Quantifier quantifier = currentPattern.getQuantifier(); if (quantifier.hasProperty(Quantifier.QuantifierProperty.LOOPING)) { // if loop has started then all notPatterns previous to the optional states are no longer valid setCurrentGroupPatternFirstOfLoop(false); final State<T> sink = copyWithoutTransitiveNots(sinkState); final State<T> looping = createLooping(sink); setCurrentGroupPatternFirstOfLoop(true); lastSink = createTimesState(looping, sinkState, currentPattern.getTimes()); } else if (quantifier.hasProperty(Quantifier.QuantifierProperty.TIMES)) { lastSink = createTimesState(sinkState, sinkState, currentPattern.getTimes()); } else { lastSink = createSingletonState(sinkState); } addStopStates(lastSink); return lastSink; }
/** * Retrieves list of conditions resulting in Stop state and names of the corresponding NOT patterns. * * <p>A current not condition can be produced in two cases: * <ol> * <li>the previous pattern is a {@link Quantifier.ConsumingStrategy#NOT_FOLLOW}</li> * <li>exists a backward path of {@link Quantifier.QuantifierProperty#OPTIONAL} patterns to * {@link Quantifier.ConsumingStrategy#NOT_FOLLOW}</li> * </ol> * * <p><b>WARNING:</b> for more info on the second case see: {@link NFAFactoryCompiler#copyWithoutTransitiveNots(State)} * * @return list of not conditions with corresponding names */ private List<Tuple2<IterativeCondition<T>, String>> getCurrentNotCondition() { List<Tuple2<IterativeCondition<T>, String>> notConditions = new ArrayList<>(); Pattern<T, ? extends T> previousPattern = currentPattern; while (previousPattern.getPrevious() != null && ( previousPattern.getPrevious().getQuantifier().hasProperty(Quantifier.QuantifierProperty.OPTIONAL) || previousPattern.getPrevious().getQuantifier().getConsumingStrategy() == Quantifier.ConsumingStrategy.NOT_FOLLOW)) { previousPattern = previousPattern.getPrevious(); if (previousPattern.getQuantifier().getConsumingStrategy() == Quantifier.ConsumingStrategy.NOT_FOLLOW) { final IterativeCondition<T> notCondition = getTakeCondition(previousPattern); notConditions.add(Tuple2.of(notCondition, previousPattern.getName())); } } return notConditions; }
true); if (currentPattern.getQuantifier().hasProperty(Quantifier.QuantifierProperty.GREEDY) && times.getFrom() != times.getTo()) { if (untilCondition != null) { takeCondition, getIgnoreCondition(currentPattern), currentPattern.getQuantifier().hasProperty(Quantifier.QuantifierProperty.OPTIONAL));
!currentPattern.getQuantifier().hasProperty(Quantifier.QuantifierProperty.OPTIONAL)) {
if (currentPattern.getQuantifier().hasProperty(Quantifier.QuantifierProperty.GREEDY)) { final IterativeCondition<T> untilCondition = (IterativeCondition<T>) currentPattern.getUntilCondition();
final State<T> loopingState = createState(currentPattern.getName(), State.StateType.Normal); if (currentPattern.getQuantifier().hasProperty(Quantifier.QuantifierProperty.GREEDY)) { if (untilCondition != null) { State<T> sinkStateCopy = copy(sinkState);
public void consecutive() { checkPattern(hasProperty(QuantifierProperty.LOOPING) || hasProperty(QuantifierProperty.TIMES), "Combinations not applicable to " + this + "!"); checkPattern(innerConsumingStrategy != ConsumingStrategy.SKIP_TILL_ANY, "You can apply apply either combinations or consecutive, not both!"); checkPattern(innerConsumingStrategy != ConsumingStrategy.STRICT, "Combinations already applied!"); innerConsumingStrategy = ConsumingStrategy.STRICT; }
public void optional() { checkPattern(!hasProperty(QuantifierProperty.OPTIONAL), "Optional already applied!"); checkPattern(!(consumingStrategy == ConsumingStrategy.NOT_NEXT || consumingStrategy == ConsumingStrategy.NOT_FOLLOW), "NOT pattern cannot be optional"); properties.add(Quantifier.QuantifierProperty.OPTIONAL); }
public void optional() { checkPattern(!hasProperty(QuantifierProperty.OPTIONAL), "Optional already applied!"); checkPattern(!(consumingStrategy == ConsumingStrategy.NOT_NEXT || consumingStrategy == ConsumingStrategy.NOT_FOLLOW), "NOT pattern cannot be optional"); properties.add(Quantifier.QuantifierProperty.OPTIONAL); }
public void combinations() { checkPattern(!hasProperty(QuantifierProperty.SINGLE), "Combinations not applicable to " + this + "!"); checkPattern(innerConsumingStrategy != ConsumingStrategy.STRICT, "You can apply apply either combinations or consecutive, not both!"); checkPattern(innerConsumingStrategy != ConsumingStrategy.SKIP_TILL_ANY, "Combinations already applied!"); innerConsumingStrategy = ConsumingStrategy.SKIP_TILL_ANY; }