/************************************************************************************** * 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.antlr.ASTUtil; import com.espertech.esper.client.ConfigurationInformation; import com.espertech.esper.client.EPStatementException; import com.espertech.esper.client.EPStatementSyntaxException; import com.espertech.esper.core.context.mgr.ContextManagementService; import com.espertech.esper.epl.core.EngineImportService; import com.espertech.esper.epl.declexpr.ExprDeclaredService; import com.espertech.esper.epl.generated.EsperEPL2GrammarParser; import com.espertech.esper.epl.parse.*; import com.espertech.esper.epl.spec.PatternStreamSpecRaw; import com.espertech.esper.epl.spec.SelectClauseElementWildcard; import com.espertech.esper.epl.spec.SelectClauseStreamSelectorEnum; import com.espertech.esper.epl.spec.StatementSpecRaw; import com.espertech.esper.epl.variable.VariableService; import com.espertech.esper.pattern.PatternNodeFactory; import com.espertech.esper.schedule.SchedulingService; import org.antlr.runtime.RecognitionException; import org.antlr.runtime.tree.CommonTreeNodeStream; import org.antlr.runtime.tree.Tree; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Helper class for administrative interface. */ public class EPAdministratorHelper { private static ParseRuleSelector patternParseRule; private static ParseRuleSelector eplParseRule; private static WalkRuleSelector patternWalkRule; private static WalkRuleSelector eplWalkRule; static { patternParseRule = new ParseRuleSelector() { public Tree invokeParseRule(EsperEPL2GrammarParser parser) throws RecognitionException { EsperEPL2GrammarParser.startPatternExpressionRule_return r = parser.startPatternExpressionRule(); return (Tree) r.getTree(); } }; patternWalkRule = new WalkRuleSelector() { public void invokeWalkRule(EPLTreeWalker walker) throws RecognitionException { walker.startPatternExpressionRule(); } }; eplParseRule = new ParseRuleSelector() { public Tree invokeParseRule(EsperEPL2GrammarParser parser) throws RecognitionException { EsperEPL2GrammarParser.startEPLExpressionRule_return r = parser.startEPLExpressionRule(); return (Tree) r.getTree(); } }; eplWalkRule = new WalkRuleSelector() { public void invokeWalkRule(EPLTreeWalker walker) throws RecognitionException { walker.startEPLExpressionRule(); } }; } /** * Compile an EPL statement. * @param eplStatement to compile * @param eplStatementForErrorMsg the statement to use for indicating error messages * @param addPleaseCheck true to add please-check message text * @param statementName the name of statement * @param services engine services * @param defaultStreamSelector stream selector * @return compiled statement */ public static StatementSpecRaw compileEPL(String eplStatement, String eplStatementForErrorMsg, boolean addPleaseCheck, String statementName, EPServicesContext services, SelectClauseStreamSelectorEnum defaultStreamSelector) { return compileEPL(eplStatement, eplStatementForErrorMsg, addPleaseCheck, statementName, defaultStreamSelector, services.getEngineImportService(), services.getVariableService(), services.getSchedulingService(), services.getEngineURI(), services.getConfigSnapshot(), services.getPatternNodeFactory(), services.getContextManagementService(), services.getExprDeclaredService()); } /** * Compile the EPL. * @param eplStatement expression to compile * @param statementName is the name of the statement * @param defaultStreamSelector - the configuration for which insert or remove streams (or both) to produce * @param eplStatementForErrorMsg - use this text for the error message * @param addPleaseCheck - indicator to add a "please check" wording for stack paraphrases * @return statement specification */ public static StatementSpecRaw compileEPL(String eplStatement, String eplStatementForErrorMsg, boolean addPleaseCheck, String statementName, SelectClauseStreamSelectorEnum defaultStreamSelector, EngineImportService engineImportService, VariableService variableService, SchedulingService schedulingService, String engineURI, ConfigurationInformation configSnapshot, PatternNodeFactory patternNodeFactory, ContextManagementService contextManagementService, ExprDeclaredService exprDeclaredService) { if (log.isDebugEnabled()) { log.debug(".createEPLStmt statementName=" + statementName + " eplStatement=" + eplStatement); } ParseResult parseResult = ParseHelper.parse(eplStatement, eplStatementForErrorMsg, addPleaseCheck, eplParseRule, true); Tree ast = parseResult.getTree(); CommonTreeNodeStream nodes = new CommonTreeNodeStream(ast); EPLTreeWalker walker = new EPLTreeWalker(nodes, parseResult.getTokenStream(), engineImportService, variableService, schedulingService, defaultStreamSelector, engineURI, configSnapshot, patternNodeFactory, contextManagementService, parseResult.getScripts(), exprDeclaredService); try { ParseHelper.walk(ast, walker, eplWalkRule, eplStatement, eplStatementForErrorMsg); } catch (ASTWalkException ex) { log.error(".createEPL Error validating expression", ex); throw new EPStatementException(ex.getMessage(), ex, eplStatementForErrorMsg); } catch (EPStatementSyntaxException ex) { throw ex; } catch (RuntimeException ex) { String message = "Error in expression"; log.debug(message, ex); throw new EPStatementException(getNullableErrortext(message, ex.getMessage()), ex, eplStatementForErrorMsg); } if (log.isDebugEnabled()) { ASTUtil.dumpAST(ast); } StatementSpecRaw raw = walker.getStatementSpec(); raw.setExpressionNoAnnotations(parseResult.getExpressionWithoutAnnotations()); return raw; } public static StatementSpecRaw compilePattern(String expression, String expressionForErrorMessage, boolean addPleaseCheck, EPServicesContext services, SelectClauseStreamSelectorEnum defaultStreamSelector) { // Parse and walk ParseResult parseResult = ParseHelper.parse(expression, expressionForErrorMessage, addPleaseCheck, patternParseRule, true); Tree ast = parseResult.getTree(); CommonTreeNodeStream nodes = new CommonTreeNodeStream(ast); EPLTreeWalker walker = new EPLTreeWalker(nodes, parseResult.getTokenStream(), services.getEngineImportService(), services.getVariableService(), services.getSchedulingService(), defaultStreamSelector, services.getEngineURI(), services.getConfigSnapshot(), services.getPatternNodeFactory(), services.getContextManagementService(), parseResult.getScripts(), services.getExprDeclaredService()); try { ParseHelper.walk(ast, walker, patternWalkRule, expression, expressionForErrorMessage); } catch (ASTWalkException ex) { log.debug(".createPattern Error validating expression", ex); throw new EPStatementException(ex.getMessage(), expression); } catch (EPStatementSyntaxException ex) { throw ex; } catch (RuntimeException ex) { String message = "Error in expression"; log.debug(message, ex); throw new EPStatementException(getNullableErrortext(message, ex.getMessage()), expression); } if (log.isDebugEnabled()) { ASTUtil.dumpAST(ast); } if (walker.getStatementSpec().getStreamSpecs().size() > 1) { throw new IllegalStateException("Unexpected multiple stream specifications encountered"); } // Get pattern specification PatternStreamSpecRaw patternStreamSpec = (PatternStreamSpecRaw) walker.getStatementSpec().getStreamSpecs().get(0); // Create statement spec, set pattern stream, set wildcard select StatementSpecRaw statementSpec = new StatementSpecRaw(SelectClauseStreamSelectorEnum.ISTREAM_ONLY); statementSpec.getStreamSpecs().add(patternStreamSpec); statementSpec.getSelectClauseSpec().getSelectExprList().clear(); statementSpec.getSelectClauseSpec().getSelectExprList().add(new SelectClauseElementWildcard()); statementSpec.setAnnotations(walker.getStatementSpec().getAnnotations()); statementSpec.setExpressionNoAnnotations(parseResult.getExpressionWithoutAnnotations()); return statementSpec; } private static String getNullableErrortext(String msg, String cause) { if (cause == null) { return msg; } else { return msg + ": " + cause; } } private static Log log = LogFactory.getLog(EPAdministratorHelper.class); }