/* * Copyright (C) 2016 Francis Galiegue <fgaliegue@gmail.com> * * Licensed 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 com.github.fge.grappa.parsers; import com.github.fge.grappa.annotations.SkipActionsInPredicates; import com.github.fge.grappa.rules.Action; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; import javax.annotation.Nonnull; import java.util.Objects; /** * A {@link BaseParser} with an attached {@link EventBus} * * <p>This parser allows you to register instances of classes with methods which * have subscribed to a bus using Guava's {@link Subscribe} annotation. For the * recall, such methods must obey the following criteria:</p> * * <ul> * <li>they must be public,</li> * <li>they must return {@code void},</li> * <li>they must accept one, and only one, argument.</li> * </ul> * * <p>A sample usage is shown below, where an event is posted on the bus, with * the text matched as an argument:</p> * * <pre> * public Rule someRule() * { * // will trigger on any subscribed method having a String as an * // argument, since match() returns a String * return sequence("foobar", post(match())); * } * </pre> * * <p>This method ({@link #post(Object)} ultimately becomes an {@link Action}, * which means it obeys all the rules of an action. This includes, for instance, * the presence (or absence thereof) of annotations such as {@link * SkipActionsInPredicates}.</p> * * <h2>Usage notes</h2> * * <p>Listeners to such a parser can only be registered once the parser has been * created. For instance:</p> * * <pre> * // MyParser extends EventBusParser * final MyParser parser = Grappa.createParser(MyParser.class); * * // Create the listener * final MyListener listener = new MyListener(); * * // Register it to the parser * parser.register(listener); * * // Crete a runner, run on an input * </pre> * * <p>Please note that such a listener's state, if any, will be retained across * reuses of the same parser on different inputs. According to the use case, * this may, or may not, be a desirable property.</p> * * @see Subscribe * @see EventBus#register(Object) * @see EventBus#post(Object) */ public abstract class EventBusParser<V> extends BaseParser<V> { protected final EventBus bus = new EventBus(); /** * Register a listener to the event bus * * @param listener the listener * @return always true * * @see EventBus#register(Object) */ public final boolean register(@Nonnull final Object listener) { bus.register(Objects.requireNonNull(listener)); return true; } /** * Post an arbitrary, non null, object on the bus * * @param object the object (must not be null) * @return always true */ public final boolean post(@Nonnull final Object object) { Objects.requireNonNull(object); bus.post(object); return true; } }