/* * ************************************************************************************* * Copyright (C) 2008 EsperTech, Inc. All rights reserved. * * http://esper.codehaus.org * * http://www.espertech.com * * ---------------------------------------------------------------------------------- * * The software in this package is published under the terms of the GPL license * * a copy of which has been included with this distribution in the license.txt file. * * ************************************************************************************* */ package com.espertech.esper.core.context.mgr; import com.espertech.esper.client.EventBean; import com.espertech.esper.core.context.util.AgentInstanceContext; import com.espertech.esper.core.service.EPServicesContext; import com.espertech.esper.core.service.StatementContext; import com.espertech.esper.epl.spec.ContextDetailConditionPattern; import com.espertech.esper.epl.spec.PatternStreamSpecCompiled; import com.espertech.esper.pattern.*; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; public class ContextControllerConditionPattern implements ContextControllerCondition, PatternMatchCallback { private final EPServicesContext servicesContext; private final AgentInstanceContext agentInstanceContext; private final ContextDetailConditionPattern endpointPatternSpec; private final ContextControllerConditionCallback callback; private final ContextInternalFilterAddendum filterAddendum; private final boolean isStartEndpoint; private final ContextStatePathKey contextStatePathKey; protected EvalRootState patternStopCallback; public ContextControllerConditionPattern(EPServicesContext servicesContext, AgentInstanceContext agentInstanceContext, ContextDetailConditionPattern endpointPatternSpec, ContextControllerConditionCallback callback, ContextInternalFilterAddendum filterAddendum, boolean startEndpoint, ContextStatePathKey contextStatePathKey) { this.servicesContext = servicesContext; this.agentInstanceContext = agentInstanceContext; this.endpointPatternSpec = endpointPatternSpec; this.callback = callback; this.filterAddendum = filterAddendum; this.isStartEndpoint = startEndpoint; this.contextStatePathKey = contextStatePathKey; } public void activate(EventBean optionalTriggeringEvent, MatchedEventMap priorMatches, long timeOffset, boolean isRecoveringReslient) { if (patternStopCallback != null) { patternStopCallback.stop(); } PatternStreamSpecCompiled patternStreamSpec = endpointPatternSpec.getPatternCompiled(); StatementContext stmtContext = agentInstanceContext.getStatementContext(); EvalRootFactoryNode rootFactoryNode = servicesContext.getPatternNodeFactory().makeRootNode(); int streamNum = isStartEndpoint ? contextStatePathKey.getSubPath() : -1 * contextStatePathKey.getSubPath(); boolean allowResilient = contextStatePathKey.getLevel() == 1; rootFactoryNode.addChildNode(patternStreamSpec.getEvalFactoryNode()); PatternContext patternContext = stmtContext.getPatternContextFactory().createContext(stmtContext, streamNum, rootFactoryNode, new MatchedEventMapMeta(patternStreamSpec.getAllTags(), !patternStreamSpec.getArrayEventTypes().isEmpty()), allowResilient); PatternAgentInstanceContext patternAgentInstanceContext = stmtContext.getPatternContextFactory().createPatternAgentContext(patternContext, agentInstanceContext, false); EvalRootNode rootNode = EvalNodeUtil.makeRootNodeFromFactory(rootFactoryNode, patternAgentInstanceContext); if (priorMatches == null) { priorMatches = new MatchedEventMapImpl(patternContext.getMatchedEventMapMeta()); } // capture any callbacks that may occur right after start ConditionPatternMatchCallback callback = new ConditionPatternMatchCallback(this); patternStopCallback = rootNode.start(callback, patternContext, priorMatches, isRecoveringReslient); callback.forwardCalls = true; if (agentInstanceContext.getStatementContext().getExtensionServicesContext() != null) { agentInstanceContext.getStatementContext().getExtensionServicesContext().startContextPattern(patternStopCallback, isStartEndpoint, contextStatePathKey); } if (callback.isInvoked) { matchFound(Collections.<String, Object>emptyMap()); } } public void matchFound(Map<String, Object> matchEvent) { Map<String, Object> matchEventInclusive = null; if (endpointPatternSpec.isInclusive()) { if (matchEvent.size() < 2) { matchEventInclusive = matchEvent; } else { // need to reorder according to tag order LinkedHashMap<String, Object> ordered = new LinkedHashMap<String, Object>(); for (String key : endpointPatternSpec.getPatternCompiled().getTaggedEventTypes().keySet()) { ordered.put(key, matchEvent.get(key)); } for (String key : endpointPatternSpec.getPatternCompiled().getArrayEventTypes().keySet()) { ordered.put(key, matchEvent.get(key)); } matchEventInclusive = ordered; } } callback.rangeNotification(matchEvent, this, null, matchEventInclusive, filterAddendum); } public void deactivate() { if (patternStopCallback != null) { patternStopCallback.stop(); patternStopCallback = null; if (agentInstanceContext.getStatementContext().getExtensionServicesContext() != null) { agentInstanceContext.getStatementContext().getExtensionServicesContext().stopContextPattern(patternStopCallback, isStartEndpoint, contextStatePathKey); } } } public boolean isRunning() { return patternStopCallback != null; } public Long getExpectedEndTime() { return null; } public static class ConditionPatternMatchCallback implements PatternMatchCallback { private final ContextControllerConditionPattern condition; private boolean isInvoked; private boolean forwardCalls; public ConditionPatternMatchCallback(ContextControllerConditionPattern condition) { this.condition = condition; } public void matchFound(Map<String, Object> matchEvent) { isInvoked = true; if (forwardCalls) { condition.matchFound(matchEvent); } } public boolean isInvoked() { return isInvoked; } } }