/************************************************************************************** * 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.service; import com.espertech.esper.client.EPStatementException; import com.espertech.esper.client.annotation.Audit; import com.espertech.esper.client.annotation.AuditEnum; import com.espertech.esper.client.annotation.Drop; import com.espertech.esper.client.annotation.Priority; import com.espertech.esper.core.context.mgr.ContextControllerFactoryServiceImpl; import com.espertech.esper.core.context.stmt.StatementAIResourceRegistry; import com.espertech.esper.core.context.util.ContextDescriptor; import com.espertech.esper.epl.agg.service.AggregationServiceFactoryServiceImpl; import com.espertech.esper.epl.core.MethodResolutionService; import com.espertech.esper.epl.core.MethodResolutionServiceImpl; import com.espertech.esper.epl.metric.StatementMetricHandle; import com.espertech.esper.epl.script.AgentInstanceScriptContext; import com.espertech.esper.epl.spec.*; import com.espertech.esper.filter.FilterServiceSPI; import com.espertech.esper.pattern.*; import com.espertech.esper.pattern.pool.PatternSubexpressionPoolStmtHandler; import com.espertech.esper.pattern.pool.PatternSubexpressionPoolStmtSvc; import com.espertech.esper.schedule.ScheduleBucket; import com.espertech.esper.schedule.SchedulingServiceSPI; import com.espertech.esper.view.StatementStopServiceImpl; import com.espertech.esper.view.ViewEnumHelper; import com.espertech.esper.view.ViewResolutionService; import com.espertech.esper.view.ViewResolutionServiceImpl; import java.lang.annotation.Annotation; import java.util.Map; /** * Default implementation for making a statement-specific context class. */ public class StatementContextFactoryDefault implements StatementContextFactory { private final PluggableObjectRegistryImpl viewRegistry; private final PluggableObjectCollection patternObjectClasses; private final Class systemVirtualDWViewFactory; private StatementContextEngineServices stmtEngineServices; /** * Ctor. * @param viewPlugIns is the view plug-in object descriptions * @param plugInPatternObj is the pattern plug-in object descriptions */ public StatementContextFactoryDefault(PluggableObjectCollection viewPlugIns, PluggableObjectCollection plugInPatternObj, Class systemVirtualDWViewFactory) { viewRegistry = new PluggableObjectRegistryImpl(new PluggableObjectCollection[] {ViewEnumHelper.getBuiltinViews(), viewPlugIns}); this.systemVirtualDWViewFactory = systemVirtualDWViewFactory; patternObjectClasses = new PluggableObjectCollection(); patternObjectClasses.addObjects(plugInPatternObj); patternObjectClasses.addObjects(PatternObjectHelper.getBuiltinPatternObjects()); } public void setStmtEngineServices(EPServicesContext services) { stmtEngineServices = getStmtCtxEngineServices(services); } public static StatementContextEngineServices getStmtCtxEngineServices(EPServicesContext services) { return new StatementContextEngineServices( services.getEngineURI(), services.getEventAdapterService(), services.getNamedWindowService(), services.getVariableService(), services.getEngineSettingsService(), services.getValueAddEventService(), services.getConfigSnapshot(), services.getMetricsReportingService(), services.getViewService(), services.getExceptionHandlingService(), services.getExpressionResultCacheSharable() ); } public StatementContext makeContext(String statementId, String statementName, String expression, EPServicesContext engineServices, Map<String, Object> optAdditionalContext, boolean isFireAndForget, Annotation[] annotations, EPIsolationUnitServices isolationUnitServices, boolean stateless, StatementSpecRaw statementSpecRaw) { // Allocate the statement's schedule bucket which stays constant over it's lifetime. // The bucket allows callbacks for the same time to be ordered (within and across statements) and thus deterministic. ScheduleBucket scheduleBucket = engineServices.getSchedulingMgmtService().allocateBucket(); // Create a lock for the statement StatementAgentInstanceLock defaultStatementAgentInstanceLock; // For on-delete statements, use the create-named-window statement lock CreateWindowDesc optCreateWindowDesc = statementSpecRaw.getCreateWindowDesc(); OnTriggerDesc optOnTriggerDesc = statementSpecRaw.getOnTriggerDesc(); if ((optOnTriggerDesc != null) && (optOnTriggerDesc instanceof OnTriggerWindowDesc)) { String windowName = ((OnTriggerWindowDesc) optOnTriggerDesc).getWindowName(); defaultStatementAgentInstanceLock = engineServices.getNamedWindowService().getNamedWindowLock(windowName); if (defaultStatementAgentInstanceLock == null) { throw new EPStatementException("Named window '" + windowName + "' has not been declared", expression); } } // For creating a named window, save the lock for use with on-delete/on-merge/on-update etc. statements else if (optCreateWindowDesc != null) { defaultStatementAgentInstanceLock = engineServices.getNamedWindowService().getNamedWindowLock(optCreateWindowDesc.getWindowName()); if (defaultStatementAgentInstanceLock == null) { defaultStatementAgentInstanceLock = engineServices.getStatementLockFactory().getStatementLock(statementName, expression, annotations, false); engineServices.getNamedWindowService().addNamedWindowLock(optCreateWindowDesc.getWindowName(), defaultStatementAgentInstanceLock, statementName); } } else { defaultStatementAgentInstanceLock = engineServices.getStatementLockFactory().getStatementLock(statementName, expression, annotations, stateless); } StatementMetricHandle stmtMetric = null; if (!isFireAndForget) { stmtMetric = engineServices.getMetricsReportingService().getStatementHandle(statementId, statementName); } AnnotationAnalysisResult annotationData = AnnotationAnalysisResult.analyzeAnnotations(annotations); boolean hasVariables = statementSpecRaw.isHasVariables() || (statementSpecRaw.getCreateContextDesc() != null); EPStatementHandle epStatementHandle = new EPStatementHandle(statementId, statementName, expression, expression, hasVariables, stmtMetric, annotationData.getPriority(), annotationData.isPremptive()); MethodResolutionService methodResolutionService = new MethodResolutionServiceImpl(engineServices.getEngineImportService(), engineServices.getSchedulingService()); PatternContextFactory patternContextFactory = new PatternContextFactoryDefault(); String optionalCreateNamedWindowName = statementSpecRaw.getCreateWindowDesc() != null ? statementSpecRaw.getCreateWindowDesc().getWindowName() : null; ViewResolutionService viewResolutionService = new ViewResolutionServiceImpl(viewRegistry, optionalCreateNamedWindowName, systemVirtualDWViewFactory); PatternObjectResolutionService patternResolutionService = new PatternObjectResolutionServiceImpl(patternObjectClasses); SchedulingServiceSPI schedulingService = engineServices.getSchedulingService(); FilterServiceSPI filterService = engineServices.getFilterService(); if (isolationUnitServices != null) { filterService = isolationUnitServices.getFilterService(); schedulingService = isolationUnitServices.getSchedulingService(); } Audit scheduleAudit = AuditEnum.SCHEDULE.getAudit(annotations); if (scheduleAudit != null) { schedulingService = new SchedulingServiceAudit(engineServices.getEngineURI(), statementName, schedulingService); } StatementAIResourceRegistry statementAgentInstanceRegistry = null; ContextDescriptor contextDescriptor = null; String optionalContextName = statementSpecRaw.getOptionalContextName(); if (optionalContextName != null) { contextDescriptor = engineServices.getContextManagementService().getContextDescriptor(optionalContextName); // allocate a per-instance registry of aggregations and prev/prior/subselect if (contextDescriptor != null) { statementAgentInstanceRegistry = contextDescriptor.getAiResourceRegistryFactory().make(); } } boolean countSubexpressions = engineServices.getConfigSnapshot().getEngineDefaults().getPatterns().getMaxSubexpressions() != null; PatternSubexpressionPoolStmtSvc patternSubexpressionPoolStmtSvc = null; if (countSubexpressions) { PatternSubexpressionPoolStmtHandler stmtCounter = new PatternSubexpressionPoolStmtHandler(); patternSubexpressionPoolStmtSvc = new PatternSubexpressionPoolStmtSvc(engineServices.getPatternSubexpressionPoolSvc(), stmtCounter); engineServices.getPatternSubexpressionPoolSvc().addPatternContext(statementName, stmtCounter); } AgentInstanceScriptContext defaultAgentInstanceScriptContext = null; if (statementSpecRaw.getScriptExpressions() != null && !statementSpecRaw.getScriptExpressions().isEmpty()) { defaultAgentInstanceScriptContext = new AgentInstanceScriptContext(); } // Create statement context return new StatementContext(stmtEngineServices, statementId, null, statementName, expression, schedulingService, scheduleBucket, epStatementHandle, viewResolutionService, patternResolutionService, null, // no statement extension context new StatementStopServiceImpl(), methodResolutionService, patternContextFactory, filterService, new StatementResultServiceImpl(statementName, engineServices.getStatementLifecycleSvc(), engineServices.getMetricsReportingService(), engineServices.getThreadingService()), engineServices.getInternalEventEngineRouteDest(), annotations, statementAgentInstanceRegistry, defaultStatementAgentInstanceLock, contextDescriptor, patternSubexpressionPoolStmtSvc, stateless, ContextControllerFactoryServiceImpl.DEFAULT_FACTORY, defaultAgentInstanceScriptContext, AggregationServiceFactoryServiceImpl.DEFAULT_FACTORY); } /** * Analysis result of analysing annotations for a statement. */ public static class AnnotationAnalysisResult { private int priority; private boolean isPremptive; /** * Ctor. * @param priority priority * @param premptive preemptive indicator */ private AnnotationAnalysisResult(int priority, boolean premptive) { this.priority = priority; isPremptive = premptive; } /** * Returns execution priority. * @return priority. */ public int getPriority() { return priority; } /** * Returns preemptive indicator (drop or normal). * @return true for drop */ public boolean isPremptive() { return isPremptive; } /** * Analyze the annotations and return priority and drop settings. * @param annotations to analyze * @return analysis result */ public static AnnotationAnalysisResult analyzeAnnotations(Annotation[] annotations) { boolean preemptive = false; int priority = 0; boolean hasPrioritySetting = false; for (Annotation annotation : annotations) { if (annotation instanceof Priority) { priority = ((Priority) annotation).value(); hasPrioritySetting = true; } if (annotation instanceof Drop) { preemptive = true; } } if (!hasPrioritySetting && preemptive) { priority = 1; } return new AnnotationAnalysisResult(priority, preemptive); } } }