Skip to content

Commit

Permalink
Added extended literals
Browse files Browse the repository at this point in the history
  • Loading branch information
tonydamage committed Jan 12, 2021
1 parent 52ce4ff commit caabad5
Show file tree
Hide file tree
Showing 5 changed files with 377 additions and 91 deletions.
@@ -1,29 +1,27 @@
grammar AxiomQuery;

SEMICOLON : ';';
LEFT_BRACE : '{';
RIGHT_BRACE : '}';
COLON : ':';
PLUS : '+';
LINE_COMMENT : [ \n\r\t]* ('//' (~[\r\n]*)) [ \n\r\t]* -> skip;
SEP: [ \n\r\t]+;

AND_KEYWORD: 'and';
OR_KEYWORD: 'or';
NOT_KEYWORD: 'not';
IDENTIFIER : [a-zA-Z_][a-zA-Z0-9_\-]*;
nullLiteral: 'null';
booleanLiteral: 'true' | 'false';

fragment SQOUTE : '\'';
fragment DQOUTE : '"';
intLiteral: INT;
floatLiteral: FLOAT;
stringLiteral : STRING_SINGLEQUOTE #singleQuoteString
| STRING_DOUBLEQUOTE #doubleQuoteString
| STRING_MULTILINE_START (~('"""'))*'"""' # multilineString;

fragment ESC : '\\';

STRING_SINGLEQUOTE: SQOUTE ((ESC SQOUTE) | ~[\n'])* SQOUTE;
STRING_DOUBLEQUOTE: DQOUTE ((ESC DQOUTE) | ~[\n"])* DQOUTE;
STRING_MULTILINE_START: '"""' ('\r')? '\n';
literalValue:
value=('true' | 'false') #booleanValue
| value=INT #intValue
| value=FLOAT #floatValue
| stringLiteral #stringValue
| 'null' #nullValue;

// endgrammar axiom literals

//statement : SEP* identifier SEP* (argument)? SEP* (SEMICOLON | LEFT_BRACE SEP* (statement)* SEP* RIGHT_BRACE SEP*) SEP*;

itemName: prefixedName #dataName
| '@' prefixedName #infraName;

Expand All @@ -32,10 +30,7 @@ prefixedName: (prefix=IDENTIFIER COLON)? localName=IDENTIFIER
| (prefix=IDENTIFIER)? COLON localName=(AND_KEYWORD | NOT_KEYWORD | OR_KEYWORD);


argument : prefixedName | string;
string : STRING_SINGLEQUOTE #singleQuoteString
| STRING_DOUBLEQUOTE #doubleQuoteString
| STRING_MULTILINE_START (~('"""'))*'"""' # multilineString;
argument : prefixedName | literalValue;

variable: '$' itemName;
parent: '..';
Expand All @@ -58,7 +53,11 @@ matchingRule: '[' prefixedName ']';


// Currently value could be string or path
valueSpecification: string | path;
valueSpecification: literalValue | path;




negation: NOT_KEYWORD;
// Filter could be Value filter or Logic Filter

Expand All @@ -73,3 +72,57 @@ itemFilter: path (SEP+ negation)? SEP+ filterName (matchingRule)? (SEP+ (subfilt
subfilterOrValue : subfilterSpec | valueSpecification;






// grammar AxiomLiterals;

SEMICOLON : ';';
LEFT_BRACE : '{';
RIGHT_BRACE : '}';
COLON : ':';
PLUS : '+';
LINE_COMMENT : [ \n\r\t]* ('//' (~[\r\n]*)) [ \n\r\t]* -> skip;
SEP: [ \n\r\t]+;

AND_KEYWORD: 'and';
OR_KEYWORD: 'or';
NOT_KEYWORD: 'not';
IDENTIFIER : [a-zA-Z_][a-zA-Z0-9_\-]*;

fragment SQOUTE : '\'';
fragment DQOUTE : '"';

fragment ESC : '\\';
//fragment ESC: '\\' ( ["\\/bfnrt] | UNICODE);



STRING_SINGLEQUOTE: SQOUTE ((ESC SQOUTE) | ~[\n'])* SQOUTE;
STRING_DOUBLEQUOTE: DQOUTE ((ESC DQOUTE) | ~[\n"])* DQOUTE;
STRING_MULTILINE_START: '"""' ('\r')? '\n';
fragment UNICODE: 'u' HEX HEX HEX HEX;
fragment HEX: [0-9a-fA-F];
fragment NONZERO_DIGIT: [1-9];
fragment DIGIT: [0-9];
fragment FRACTIONAL_PART: '.' DIGIT+;
fragment EXPONENTIAL_PART: EXPONENT_INDICATOR SIGN? DIGIT+;
fragment EXPONENT_INDICATOR: [eE];
fragment SIGN: [+-];
fragment NEGATIVE_SIGN: '-';
FLOAT: INT FRACTIONAL_PART
| INT EXPONENTIAL_PART
| INT FRACTIONAL_PART EXPONENTIAL_PART
;
INT: NEGATIVE_SIGN? '0'
| NEGATIVE_SIGN? NONZERO_DIGIT DIGIT*
;
@@ -1,5 +1,16 @@
package com.evolveum.axiom.lang.antlr;

import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.BooleanValueContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.DoubleQuoteStringContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.FloatValueContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.IntValueContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.LiteralValueContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.MultilineStringContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.NullValueContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.SingleQuoteStringContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.StringLiteralContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.StringValueContext;

public class AxiomAntlrLiterals {

public static String convertSingleQuote(String text) {
Expand All @@ -15,4 +26,55 @@ public static String convertDoubleQuote(String text) {
public static String convertMultiline(String text) {
return text.replace("\"\"\"", "");
}

public static Object convert(LiteralValueContext value) {
if (value instanceof StringValueContext) {
return convertString((StringValueContext) value);
} else if(value instanceof IntValueContext) {
return convertInteger((IntValueContext) value);
} else if (value instanceof BooleanValueContext) {
return convertBoolean((BooleanValueContext) value);
} else if (value instanceof NullValueContext) {
return convertNull((NullValueContext) value);
} else if (value instanceof FloatValueContext) {
return convertFloat((FloatValueContext) value);
}


// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unknown type of literal" + value.getClass());
}


private static Number convertFloat(FloatValueContext value) {
return Double.parseDouble(value.getText());
}

private static String convertString(StringValueContext value) {
return convertString(value.stringLiteral());
}

private static String convertString(StringLiteralContext string) {
if(string instanceof SingleQuoteStringContext) {
return convertSingleQuote(string.getText());
} else if (string instanceof MultilineStringContext) {
return convertMultiline(string.getText());
} else if (string instanceof DoubleQuoteStringContext) {
return convertDoubleQuote(string.getText());
}
throw new UnsupportedOperationException("Unknown String type" + string.getClass());
}

private static Void convertNull(NullValueContext value) {
return null;
}

private static Boolean convertBoolean(BooleanValueContext value) {
return Boolean.parseBoolean(value.getText());
}

private static Number convertInteger(IntValueContext value) {
return Integer.parseInt(value.getText());
}

}
Expand Up @@ -8,17 +8,14 @@
import com.evolveum.axiom.lang.antlr.AxiomAntlrLiterals;
import com.evolveum.axiom.lang.antlr.AxiomQuerySource;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.AndFilterContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.DoubleQuoteStringContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.FilterContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.FilterNameContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.GenFilterContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.ItemFilterContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.MultilineStringContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.LiteralValueContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.OrFilterContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.PathContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.PrefixedNameContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.SingleQuoteStringContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.StringContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.SubFilterContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.SubfilterOrValueContext;
import com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.ValueSpecificationContext;
Expand All @@ -27,9 +24,12 @@
import com.evolveum.midpoint.prism.PrismContainerDefinition;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismPropertyDefinition;
import com.evolveum.midpoint.prism.PrismReferenceDefinition;
import com.evolveum.midpoint.prism.impl.marshaller.ItemPathHolder;
import com.evolveum.midpoint.prism.impl.query.EqualFilterImpl;
import com.evolveum.midpoint.prism.impl.query.ExistsFilterImpl;
import com.evolveum.midpoint.prism.impl.query.GreaterFilterImpl;
import com.evolveum.midpoint.prism.impl.query.LessFilterImpl;
import com.evolveum.midpoint.prism.impl.query.NotFilterImpl;
import com.evolveum.midpoint.prism.impl.query.SubstringFilterImpl;
import com.evolveum.midpoint.prism.path.ItemPath;
Expand Down Expand Up @@ -70,8 +70,8 @@ public ObjectFilter create(PrismContainerDefinition<?> parentDef, ItemPath path,
ValueSpecificationContext valueSpec = subfilterOrValue.valueSpecification();
if(valueSpec.path() != null) {
throw new UnsupportedOperationException("FIXME: Implement right side lookup");
} else if (valueSpec.string() != null) {
Object parsedValue = parseLiteral(propDef, valueSpec.string());
} else if (valueSpec.literalValue() != null) {
Object parsedValue = parseLiteral(propDef, valueSpec.literalValue());
return valueFilter(propDef, path, matchingRule, parsedValue);
}
throw new IllegalStateException();
Expand Down Expand Up @@ -135,6 +135,34 @@ public ObjectFilter propertyFilter(PrismPropertyDefinition<?> definition, ItemPa
return EqualFilterImpl.createEqual(path, definition, matchingRule, rightPath, rightDef);
}
})
.put(queryName("greater"), new PropertyFilterFactory() {
@Override
ObjectFilter valueFilter(PrismPropertyDefinition<?> definition, ItemPath path, QName matchingRule,
Object value) {
return GreaterFilterImpl.createGreater(path, definition, matchingRule, value,false, context);
}

@Override
ObjectFilter propertyFilter(PrismPropertyDefinition<?> definition, ItemPath path, QName matchingRule,
ItemPath rightPath, PrismPropertyDefinition<?> rightDef) {
// TODO Auto-generated method stub
return null;
}
})
.put(queryName("less"), new PropertyFilterFactory() {
@Override
ObjectFilter valueFilter(PrismPropertyDefinition<?> definition, ItemPath path, QName matchingRule,
Object value) {
return LessFilterImpl.createLess(path, definition, matchingRule, value,false, context);
}

@Override
ObjectFilter propertyFilter(PrismPropertyDefinition<?> definition, ItemPath path, QName matchingRule,
ItemPath rightPath, PrismPropertyDefinition<?> rightDef) {
// TODO Auto-generated method stub
return null;
}
})
.put(queryName("contains"), new SubstringFilterFactory(false, false))
.put(queryName("startsWith"), new SubstringFilterFactory(true, false))
.put(queryName("endsWith"), new SubstringFilterFactory(false, true))
Expand Down Expand Up @@ -282,33 +310,38 @@ private QName toFilterName(String defaultNs, PrefixedNameContext itemName) {
ObjectFilter createEqual(PrismPropertyDefinition<?> definition, ItemPath path, QName matchingRule, ValueSpecificationContext value) {
if(value.path() != null) {
throw new UnsupportedOperationException("FIXME: Implement right side lookup");
} else if (value.string() != null) {
Object parsedValue = parseLiteral(definition, value.string());
} else if (value.literalValue() != null) {
Object parsedValue = parseLiteral(definition, value.literalValue());
return EqualFilterImpl.createEqual(path, definition, matchingRule, context, parsedValue);
}
throw new IllegalStateException();
}

private Object parseLiteral(PrismPropertyDefinition<?> definition, StringContext string) {
// FIXME: Use property definition for parsing (date, name, qname, etc)
if (string instanceof DoubleQuoteStringContext) {
return AxiomAntlrLiterals.convertDoubleQuote(string.getText());
} else if (string instanceof SingleQuoteStringContext) {
return AxiomAntlrLiterals.convertSingleQuote(string.getText());
} else if (string instanceof MultilineStringContext) {
return AxiomAntlrLiterals.convertMultiline(string.getText());
}
return null;
private Object parseLiteral(PrismPropertyDefinition<?> definition, LiteralValueContext string) {
return AxiomAntlrLiterals.convert(string);
}


private ObjectFilter matchesFilter(PrismContainerDefinition<?> parent, ItemPath path,ItemDefinition<?> definition, QName matchingRule, SubfilterOrValueContext subfilterOrValue) throws SchemaException {
Preconditions.checkArgument(definition instanceof PrismContainerDefinition<?>);
PrismContainerDefinition<?> containerDef = (PrismContainerDefinition<?>) definition;
FilterContext subfilterTree = subfilterOrValue.subfilterSpec().filter();
ObjectFilter subfilter = parseFilter(containerDef, subfilterTree);
return ExistsFilterImpl.createExists(path, (PrismContainerDefinition<?>) parent, subfilter);
schemaCheck(subfilterOrValue.subfilterSpec() != null, "matches filter requires subfilter");
if (definition instanceof PrismContainerDefinition<?>) {
PrismContainerDefinition<?> containerDef = (PrismContainerDefinition<?>) definition;
FilterContext subfilterTree = subfilterOrValue.subfilterSpec().filter();
ObjectFilter subfilter = parseFilter(containerDef, subfilterTree);
return ExistsFilterImpl.createExists(path, (PrismContainerDefinition<?>) parent, subfilter);
} else if(definition instanceof PrismReferenceDefinition) {
return matchesReferenceFilter(path, (PrismReferenceDefinition) definition, subfilterOrValue.subfilterSpec().filter());

}
throw new UnsupportedOperationException("Unknown schema type");
}

private ObjectFilter matchesReferenceFilter(ItemPath path, PrismReferenceDefinition definition,
FilterContext filter) {
// TODO Auto-generated method stub


throw new UnsupportedOperationException("Not Implemented");
}

public static PrismQueryLanguageParser create(PrismContext prismContext) {
Expand Down

0 comments on commit caabad5

Please sign in to comment.