/* * Copyright 2012 Research Studios Austria Forschungsges.m.b.H. * * 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 won.bot.impl; import won.bot.framework.bot.base.EventBot; import won.bot.framework.eventbot.EventListenerContext; import won.bot.framework.eventbot.action.BaseEventBotAction; import won.bot.framework.eventbot.action.impl.lifecycle.SignalWorkDoneAction; import won.bot.framework.eventbot.action.impl.monitor.MessageLifecycleMonitoringAction; import won.bot.framework.eventbot.action.impl.needlifecycle.CreateNeedWithFacetsAction; import won.bot.framework.eventbot.action.impl.needlifecycle.DeactivateAllNeedsAction; import won.bot.framework.eventbot.action.impl.wonmessage.CloseConnectionAction; import won.bot.framework.eventbot.action.impl.wonmessage.ConnectFromListToListAction; import won.bot.framework.eventbot.action.impl.wonmessage.OpenConnectionAction; import won.bot.framework.eventbot.bus.EventBus; import won.bot.framework.eventbot.event.Event; import won.bot.framework.eventbot.event.impl.lifecycle.ActEvent; import won.bot.framework.eventbot.event.impl.monitor.CrawlDoneEvent; import won.bot.framework.eventbot.event.impl.monitor.CrawlReadyEvent; import won.bot.framework.eventbot.event.impl.monitor.MessageDispatchStartedEvent; import won.bot.framework.eventbot.event.impl.monitor.MessageDispatchedEvent; import won.bot.framework.eventbot.event.impl.needlifecycle.NeedCreatedEvent; import won.bot.framework.eventbot.event.impl.needlifecycle.NeedDeactivatedEvent; import won.bot.framework.eventbot.event.impl.wonmessage.*; import won.bot.framework.eventbot.listener.BaseEventListener; import won.bot.framework.eventbot.listener.EventListener; import won.bot.framework.eventbot.listener.impl.ActionOnEventListener; import won.bot.framework.eventbot.listener.impl.ActionOnceAfterNEventsListener; import won.bot.framework.eventbot.listener.impl.AutomaticMonitoredMessageResponderListener; import won.protocol.model.FacetType; /** * */ public class ConversationBotMonitored extends EventBot { private static final int NO_OF_NEEDS = 2; private static final int NO_OF_MESSAGES = 1; private static final long MILLIS_BETWEEN_MESSAGES = 100; //we use protected members so we can extend the class and //access the listeners for unit test assertions and stats // //we use BaseEventListener as their types so we can access the generic //functionality offered by that class protected BaseEventListener needCreator; protected BaseEventListener needConnector; protected BaseEventListener autoOpener; protected BaseEventListener autoResponder; protected BaseEventListener connectionCloser; protected BaseEventListener needDeactivator; protected BaseEventListener workDoneSignaller; protected BaseEventListener crawlReadySignaller; protected BaseEventListener monitor; @Override protected void initializeEventListeners() { EventListenerContext ctx = getEventListenerContext(); EventBus bus = getEventBus(); //create needs every trigger execution until 2 needs are created this.needCreator = new ActionOnEventListener( ctx, new CreateNeedWithFacetsAction(ctx, getBotContextWrapper().getNeedCreateListName()), NO_OF_NEEDS ); bus.subscribe(ActEvent.class, this.needCreator); //count until 2 needs were created, then // * connect the 2 needs this.needConnector = new ActionOnceAfterNEventsListener(ctx,"needConnector", NO_OF_NEEDS, new ConnectFromListToListAction(ctx, ctx.getBotContextWrapper().getNeedCreateListName(), ctx.getBotContextWrapper().getNeedCreateListName(), FacetType.OwnerFacet.getURI(), FacetType.OwnerFacet.getURI(), MILLIS_BETWEEN_MESSAGES, "Hello," + "I am the ConversationBot, a simple bot that will exchange " + "messages and deactivate its needs after some time.")); bus.subscribe(NeedCreatedEvent.class, this.needConnector); //add a listener that is informed of the connect/open events and that auto-opens //subscribe it to: // * connect events - so it responds with open // * open events - so it responds with open (if the open received was the first open, and we still need to accept the connection) this.autoOpener = new ActionOnEventListener(ctx, new OpenConnectionAction(ctx, "Hi, I am the ConverssationBot.")); bus.subscribe(ConnectFromOtherNeedEvent.class, this.autoOpener); //add a listener that auto-responds to messages by a message and at different stages of messages processing fires // different monitoring events. After specified number of messages, it unsubscribes from all events. //subscribe it to: // * message events - so it responds // * open events - so it initiates the chain reaction of responses this.autoResponder = new AutomaticMonitoredMessageResponderListener(ctx, NO_OF_MESSAGES, MILLIS_BETWEEN_MESSAGES); bus.subscribe(OpenFromOtherNeedEvent.class, this.autoResponder); bus.subscribe(MessageFromOtherNeedEvent.class, this.autoResponder); //add a listener that closes the connection after it has seen 10 messages this.connectionCloser = new ActionOnceAfterNEventsListener( ctx, NO_OF_MESSAGES, new CloseConnectionAction(ctx, "Farewell!") ); bus.subscribe( MessageFromOtherNeedEvent.class, this.connectionCloser); //add a listener that closes the connection when a failureEvent occurs EventListener onFailureConnectionCloser = new ActionOnEventListener(ctx, new CloseConnectionAction(ctx,"Farewell!")); bus.subscribe(FailureResponseEvent.class, onFailureConnectionCloser); //add a listener that auto-responds to a close message with a deactivation of both needs. //subscribe it to: // * close events this.needDeactivator = new ActionOnEventListener(ctx, new DeactivateAllNeedsAction(ctx), 1); bus.subscribe(CloseFromOtherNeedEvent.class, this.needDeactivator); //add a listener that counts two NeedDeactivatedEvents and then tells the //framework that the bot's messaging work is done and connection messages linked data can be crawled this.crawlReadySignaller = new ActionOnceAfterNEventsListener( ctx, NO_OF_NEEDS, new BaseEventBotAction(ctx){ @Override protected void doRun(Event event, EventListener executingListener) throws Exception { bus.publish(new CrawlReadyEvent()); } } ); bus.subscribe(NeedDeactivatedEvent.class, this.crawlReadySignaller); //add a listener that, when crawl is done, tells the //framework that the bot's work is done this.workDoneSignaller = new ActionOnEventListener(ctx,new SignalWorkDoneAction(ctx)); bus.subscribe(CrawlDoneEvent.class, this.workDoneSignaller); //add a listener that reacts to monitoring events this.monitor = new ActionOnEventListener(ctx, "msgMonitor", new MessageLifecycleMonitoringAction(ctx)); bus.subscribe(MessageDispatchStartedEvent.class, this.monitor); bus.subscribe(MessageDispatchedEvent.class, this.monitor); bus.subscribe(SuccessResponseEvent.class, this.monitor); bus.subscribe(MessageFromOtherNeedEvent.class, this.monitor); bus.subscribe(CrawlReadyEvent.class, this.monitor); } }