/**************************************************************************************
* 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.epl.parse;
import com.espertech.esper.collection.Pair;
import com.espertech.esper.epl.generated.EsperEPL2GrammarParser;
import com.espertech.esper.type.*;
import org.antlr.runtime.tree.Tree;
/**
* Builds a filter specification from filter AST nodes.
*/
public class ASTFilterSpecHelper
{
/**
* Return the generated property name that is defined by the AST child node and it's siblings.
* @param parentNode the AST node to consider as the parent for the child nodes to look at
* @param startIndex the index of the child node to start looking at
* @return property name, ie. indexed[1] or mapped('key') or nested.nested or a combination or just 'simple'.
*/
protected static String getPropertyName(Tree parentNode, int startIndex)
{
StringBuilder buffer = new StringBuilder();
String delimiter = "";
int childIndex = startIndex;
while (childIndex < parentNode.getChildCount())
{
Tree child = parentNode.getChild(childIndex);
buffer.append(delimiter);
switch (child.getType()) {
case EsperEPL2GrammarParser.EVENT_PROP_SIMPLE:
buffer.append(escapeDot(child.getChild(0).getText()));
break;
case EsperEPL2GrammarParser.EVENT_PROP_MAPPED:
buffer.append(escapeDot(child.getChild(0).getText()));
buffer.append('(');
buffer.append(child.getChild(1).getText());
buffer.append(')');
break;
case EsperEPL2GrammarParser.EVENT_PROP_INDEXED:
buffer.append(escapeDot(child.getChild(0).getText()));
buffer.append('[');
buffer.append(child.getChild(1).getText());
buffer.append(']');
break;
case EsperEPL2GrammarParser.EVENT_PROP_DYNAMIC_SIMPLE:
buffer.append(escapeDot(child.getChild(0).getText()));
buffer.append('?');
break;
case EsperEPL2GrammarParser.EVENT_PROP_DYNAMIC_MAPPED:
buffer.append(escapeDot(child.getChild(0).getText()));
buffer.append('(');
buffer.append(child.getChild(1).getText());
buffer.append(')');
buffer.append('?');
break;
case EsperEPL2GrammarParser.EVENT_PROP_DYNAMIC_INDEXED:
buffer.append(escapeDot(child.getChild(0).getText()));
buffer.append('[');
buffer.append(child.getChild(1).getText());
buffer.append(']');
buffer.append('?');
break;
default:
throw new IllegalStateException("Event property AST node not recognized, type=" + child.getType());
}
delimiter = ".";
childIndex++;
}
return buffer.toString();
}
public static Pair<String, String> getMappedPropertyPair(Tree node) {
if (node.getChild(0).getType() != EsperEPL2GrammarParser.EVENT_PROP_MAPPED) {
return null;
}
return new Pair<String, String>(escapeDot(node.getChild(0).getChild(0).getText()),
StringValue.parseString(node.getChild(0).getChild(1).getText()));
}
/**
* Escape all unescape dot characters in the text (identifier only) passed in.
* @param identifierToEscape text to escape
* @return text where dots are escaped
*/
protected static String escapeDot(String identifierToEscape)
{
int indexof = identifierToEscape.indexOf(".");
if (indexof == -1)
{
return identifierToEscape;
}
StringBuilder builder = new StringBuilder();
for (int i = 0; i < identifierToEscape.length(); i++)
{
char c = identifierToEscape.charAt(i);
if (c != '.')
{
builder.append(c);
continue;
}
if (i > 0)
{
if (identifierToEscape.charAt(i - 1) == '\\')
{
builder.append('.');
continue;
}
}
builder.append('\\');
builder.append('.');
}
return builder.toString();
}
/**
* Find the index of an unescaped dot (.) character, or return -1 if none found.
* @param identifier text to find an un-escaped dot character
* @return index of first unescaped dot
*/
public static int unescapedIndexOfDot(String identifier)
{
int indexof = identifier.indexOf(".");
if (indexof == -1)
{
return -1;
}
for (int i = 0; i < identifier.length(); i++)
{
char c = identifier.charAt(i);
if (c != '.')
{
continue;
}
if (i > 0)
{
if (identifier.charAt(i - 1) == '\\')
{
continue;
}
}
return i;
}
return -1;
}
/**
* Un-Escape all escaped dot characters in the text (identifier only) passed in.
* @param identifierToUnescape text to un-escape
* @return string
*/
public static String unescapeDot(String identifierToUnescape)
{
int indexof = identifierToUnescape.indexOf(".");
if (indexof == -1)
{
return identifierToUnescape;
}
indexof = identifierToUnescape.indexOf("\\");
if (indexof == -1)
{
return identifierToUnescape;
}
StringBuilder builder = new StringBuilder();
int index = -1;
int max = identifierToUnescape.length() - 1;
do
{
index++;
char c = identifierToUnescape.charAt(index);
if (c != '\\') {
builder.append(c);
continue;
}
if (index < identifierToUnescape.length() - 1)
{
if (identifierToUnescape.charAt(index + 1) == '.')
{
builder.append('.');
index++;
}
}
}
while (index < max);
return builder.toString();
}
}