Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into feature/secrets-pro…
Browse files Browse the repository at this point in the history
…vider
  • Loading branch information
1azyman committed Jan 8, 2024
2 parents f9be8ea + b35ce7a commit b0709bc
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
import com.evolveum.axiom.lang.antlr.AxiomQueryError;

import java.util.List;
import java.util.Map;

public interface AxiomQueryLangService {

List<AxiomQueryError> validate(String query);

List<String> queryCompletion(String query);
Map<String, String> queryCompletion(String query);

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
import org.jetbrains.annotations.NotNull;

import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;

/**
Expand Down Expand Up @@ -59,43 +58,46 @@ public Object visitItemComponent(ItemComponentContext ctx) {
return super.visitItemComponent(ctx);
}

public List<String> generateSuggestion() {
List<String> suggestions = new ArrayList<>();
ParseTree lastNode = getLastNode();
public Map<String, String> generateSuggestion() {
// structure of suggestion: filterName -> alias
Map<String, String> suggestions = new HashMap<>();
final ParseTree lastNode = getLastNode();

// generate suggestion
if (lastNode instanceof AxiomQueryParser.ItemPathComponentContext ctx) {
suggestions = getFilters(lastNode.getText());
suggestions.add(FilterNames.NOT.getLocalPart());
suggestions.put(FilterNames.NOT.getLocalPart(), null);
} else if (lastNode instanceof AxiomQueryParser.FilterNameContext ctx) {
// TODO maybe to add suggestion for value
// value for @type || . type
if (findNode(ctx).getChild(0).getText().equals(FilterNames.META_TYPE) || ctx.getText().equals(FilterNames.TYPE.getLocalPart())) {
TypeDefinition typeDefinition = schemaRegistry.findTypeDefinitionByType(new QName(lastType.getText()));
suggestions = schemaRegistry.getAllSubTypesByTypeDefinition(List.of(typeDefinition)).stream().map(item -> item.getTypeName().getLocalPart()).toList();
TypeDefinition typeDefinition = schemaRegistry.findTypeDefinitionByType(defineObjectType());
suggestions = schemaRegistry.getAllSubTypesByTypeDefinition(List.of(typeDefinition)).stream()
.collect(Collectors.toMap(item -> item.getTypeName().getLocalPart(), item -> item.getTypeName().getLocalPart(), (existing, replacement) -> existing))
.values().stream().collect(Collectors.toMap(filterName -> filterName, alias -> alias));
}
// value for @path
if (findNode(ctx).getChild(0).getText().equals(FilterNames.META_PATH)) {
suggestions = getAllPath();
suggestions = getAllPath().stream().collect(Collectors.toMap(x -> x, x -> x));
}
// value for @relation
if (ctx.getText().equals(FilterNames.META_RELATION)) {
// TODO add value for @relation to suggestions list
}

if (ctx.getText().equals(FilterNames.MATCHES.getLocalPart()) || ctx.getText().equals(FilterNames.REFERENCED_BY.getLocalPart())) {
suggestions.add("(");
suggestions.put("(", null);
}
} else if (lastNode instanceof AxiomQueryParser.GenFilterContext || lastNode instanceof AxiomQueryParser.DescendantPathContext) {
suggestions = getFilters(lastNode.getText());
suggestions.add(FilterNames.NOT.getLocalPart());
suggestions.put(FilterNames.NOT.getLocalPart(), null);
} else if (lastNode instanceof AxiomQueryParser.SubfilterOrValueContext ctx) {
suggestions.add(FilterNames.AND.getLocalPart());
suggestions.add(FilterNames.OR.getLocalPart());
suggestions.put(FilterNames.AND.getLocalPart(), null);
suggestions.put(FilterNames.OR.getLocalPart(), null);
} else if (lastNode instanceof TerminalNode ctx) {
if (ctx.getSymbol().getType() == AxiomQueryParser.SEP || ctx.getSymbol().getType() == AxiomQueryParser.AND_KEYWORD || ctx.getSymbol().getType() == AxiomQueryParser.OR_KEYWORD) {
suggestions = getAllPath();
suggestions.add(".");
suggestions = getAllPath().stream().collect(Collectors.toMap(x -> x, x -> x));
suggestions.put(".", null);
}
} else if (lastNode instanceof ErrorNode ctx) {
// TODO solve Error token
Expand Down Expand Up @@ -153,16 +155,25 @@ private ParseTree getPreviousToken(@NotNull ParserRuleContext ctx) {
}

private List<String> getAllPath() {
TypeDefinition typeDefinition = schemaRegistry.findTypeDefinitionByType(new QName(lastType.getText()));
TypeDefinition typeDefinition = schemaRegistry.findTypeDefinitionByType(defineObjectType());
PrismObjectDefinition<?> objectDefinition = schemaRegistry.findObjectDefinitionByCompileTimeClass((Class) typeDefinition.getCompileTimeClass());
return objectDefinition.getItemNames().stream().map(QName::getLocalPart).collect(Collectors.toList());
}

private List<String> getFilters(@NotNull String stringItemPath) {
private Map<String, String> getFilters(@NotNull String stringItemPath) {
ItemPath itemPath = ItemPathHolder.parseFromString(stringItemPath);
TypeDefinition typeDefinition = schemaRegistry.findTypeDefinitionByType(new QName(lastType.getText()));
TypeDefinition typeDefinition = schemaRegistry.findTypeDefinitionByType(defineObjectType());
PrismObjectDefinition<?> objectDefinition = schemaRegistry.findObjectDefinitionByCompileTimeClass((Class) typeDefinition.getCompileTimeClass());
ItemDefinition<?> itemDefinition = objectDefinition.findItemDefinition(itemPath, ItemDefinition.class);
return FilterNamesProvider.findFilterNamesByItemDefinition(itemDefinition, new FilterContext());
}

// remove after implementing schemaContext annotation
private QName defineObjectType() {
if (lastType == null) {
return new QName("UserType");
} else {
return new QName(lastType.getText());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.evolveum.midpoint.prism.query.AxiomQueryLangService;

import java.util.List;
import java.util.Map;

/**
* Created by Dominik.
Expand All @@ -25,7 +26,7 @@ public List<AxiomQueryError> validate(String query) {
return axiomQueryValidationVisitor.errorList;
}

public List<String> queryCompletion(String query) {
public Map<String, String> queryCompletion(String query) {
AxiomQuerySource axiomQuerySource = AxiomQuerySource.from(query);
AxiomQueryCompletionVisitor axiomQueryCompletionVisitor = new AxiomQueryCompletionVisitor(this.prismContext);
axiomQueryCompletionVisitor.visit(axiomQuerySource.root());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
* Created by Dominik.
Expand All @@ -34,7 +35,6 @@ public Object visitItemFilter(ItemFilterContext ctx) {
if (ctx.filterName().getText().equals(FilterNames.TYPE.getLocalPart())) {
// checking . type ObjectType
typeDefinition = checkType(ctx.subfilterOrValue());

}
} else if (ctx.path().getText().equals(FilterNames.META_TYPE) || ctx.path().getText().equals(PrismQueryLanguageParserImpl.REF_TYPE)) {
// checking path context META @type
Expand Down Expand Up @@ -125,15 +125,15 @@ private ItemDefinition<?> checkItemPath(ParserRuleContext ctx) {
if (i != (itemPathCount - 1)) {
itemDefinition = objectDefinition.findItemDefinition(itemPath);
} else {
return itemDefinition.findItemDefinition(itemPath, ItemDefinition.class);
return objectDefinition.findItemDefinition(itemPath);
}
}
}
} else {
errorList.add(new AxiomQueryError(null,
null,
ctx.getStart().getLine(), ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(),
"Missing item definition",
"Missing object definition",
null)
);
}
Expand All @@ -143,7 +143,10 @@ private ItemDefinition<?> checkItemPath(ParserRuleContext ctx) {

private void checkFilterName(ItemDefinition<?> itemDefinition, ParserRuleContext ctx) {
if (itemDefinition != null) {
if (!FilterNamesProvider.findFilterNamesByItemDefinition(itemDefinition, ctx).contains(ctx.getText())) {

Map<String, String> filters = FilterNamesProvider.findFilterNamesByItemDefinition(itemDefinition, ctx);

if (!filters.containsKey(ctx.getText()) && !filters.containsValue(ctx.getText())) {
errorList.add(new AxiomQueryError(null,
null,
ctx.getStart().getLine(), ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import com.evolveum.midpoint.util.DOMUtil;
import org.antlr.v4.runtime.ParserRuleContext;

import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Map;

import static com.evolveum.axiom.lang.antlr.query.AxiomQueryParser.*;
import static com.evolveum.midpoint.prism.impl.query.lang.FilterNames.*;
Expand All @@ -14,65 +14,59 @@
* Created by Dominik.
*/
public class FilterNamesProvider {
public static List<String> findFilterNamesByItemDefinition(ItemDefinition<?> itemDefinition, ParserRuleContext ruleContext) {
public static Map<String, String> findFilterNamesByItemDefinition(ItemDefinition<?> itemDefinition, ParserRuleContext ruleContext) {

List<String> suggestions = new ArrayList<>();
Map<String, String> suggestions = new HashMap<>();

if (ruleContext instanceof FilterNameContext || ruleContext instanceof FilterNameAliasContext || ruleContext instanceof FilterContext) {
if (itemDefinition instanceof PrismPropertyDefinition) {
suggestions.add(EQUAL.getLocalPart());
suggestions.add(LESS.getLocalPart());
suggestions.add(GREATER.getLocalPart());
suggestions.add(LESS_OR_EQUAL.getLocalPart());
suggestions.add(GREATER_OR_EQUAL.getLocalPart());
suggestions.add(NOT_EQUAL.getLocalPart());
suggestions.add(NAME_TO_ALIAS.get(EQUAL));
suggestions.add(NAME_TO_ALIAS.get(LESS));
suggestions.add(NAME_TO_ALIAS.get(GREATER));
suggestions.add(NAME_TO_ALIAS.get(LESS_OR_EQUAL));
suggestions.add(NAME_TO_ALIAS.get(GREATER_OR_EQUAL));
suggestions.add(NAME_TO_ALIAS.get(NOT_EQUAL));
suggestions.put(EQUAL.getLocalPart(), NAME_TO_ALIAS.get(EQUAL));
suggestions.put(LESS.getLocalPart(), NAME_TO_ALIAS.get(LESS));
suggestions.put(GREATER.getLocalPart(), NAME_TO_ALIAS.get(GREATER));
suggestions.put(LESS_OR_EQUAL.getLocalPart(), NAME_TO_ALIAS.get(LESS_OR_EQUAL));
suggestions.put(GREATER_OR_EQUAL.getLocalPart(), NAME_TO_ALIAS.get(GREATER_OR_EQUAL));
suggestions.put(NOT_EQUAL.getLocalPart(), NAME_TO_ALIAS.get(NOT_EQUAL));

suggestions.add(EXISTS.getLocalPart());
suggestions.add(LEVENSHTEIN.getLocalPart());
suggestions.add(SIMILARITY.getLocalPart());
suggestions.add(IN_OID.getLocalPart());
suggestions.add(OWNED_BY_OID.getLocalPart());
suggestions.add(IN_ORG.getLocalPart());
suggestions.add(IS_ROOT.getLocalPart());
suggestions.add(OWNED_BY.getLocalPart());
suggestions.add(ANY_IN.getLocalPart());
suggestions.add(TYPE.getLocalPart());
suggestions.put(EXISTS.getLocalPart(), NAME_TO_ALIAS.get(EXISTS));
suggestions.put(LEVENSHTEIN.getLocalPart(), NAME_TO_ALIAS.get(LEVENSHTEIN));
suggestions.put(SIMILARITY.getLocalPart(), NAME_TO_ALIAS.get(SIMILARITY));
suggestions.put(IN_OID.getLocalPart(), NAME_TO_ALIAS.get(IN_OID));
suggestions.put(OWNED_BY_OID.getLocalPart(), NAME_TO_ALIAS.get(OWNED_BY_OID));
suggestions.put(IN_ORG.getLocalPart(), NAME_TO_ALIAS.get(IN_ORG));
suggestions.put(IS_ROOT.getLocalPart(), NAME_TO_ALIAS.get(IS_ROOT));
suggestions.put(OWNED_BY.getLocalPart(), NAME_TO_ALIAS.get(OWNED_BY));
suggestions.put(ANY_IN.getLocalPart(), NAME_TO_ALIAS.get(ANY_IN));
suggestions.put(TYPE.getLocalPart(), NAME_TO_ALIAS.get(TYPE));

if (itemDefinition.getTypeName().equals(DOMUtil.XSD_STRING) || itemDefinition.getTypeName().equals(PrismConstants.POLYSTRING_TYPE_QNAME)) {
suggestions.add(STARTS_WITH.getLocalPart());
suggestions.add(ENDS_WITH.getLocalPart());
suggestions.add(CONTAINS.getLocalPart());
suggestions.add(FULL_TEXT.getLocalPart());
suggestions.put(STARTS_WITH.getLocalPart(), NAME_TO_ALIAS.get(STARTS_WITH));
suggestions.put(ENDS_WITH.getLocalPart(), NAME_TO_ALIAS.get(ENDS_WITH));
suggestions.put(CONTAINS.getLocalPart(), NAME_TO_ALIAS.get(CONTAINS));
suggestions.put(FULL_TEXT.getLocalPart(), NAME_TO_ALIAS.get(FULL_TEXT));
}

if (itemDefinition.getTypeName().equals(PrismConstants.POLYSTRING_TYPE_QNAME)) {
suggestions.add(MATCHES.getLocalPart());
suggestions.put(MATCHES.getLocalPart(), NAME_TO_ALIAS.get(MATCHES));
}
}
if (itemDefinition instanceof PrismReferenceDefinition) {
suggestions.add(REFERENCED_BY.getLocalPart());
suggestions.put(REFERENCED_BY.getLocalPart(), NAME_TO_ALIAS.get(REFERENCED_BY));
}
if (itemDefinition instanceof PrismContainerDefinition<?>) {
suggestions.add(MATCHES.getLocalPart());
suggestions.put(MATCHES.getLocalPart(), NAME_TO_ALIAS.get(MATCHES));
}
}

if (ruleContext instanceof SubfilterOrValueContext) {
suggestions.add(AND.getLocalPart());
suggestions.add(OR.getLocalPart());
suggestions.add(NOT.getLocalPart());
suggestions.put(AND.getLocalPart(), NAME_TO_ALIAS.get(AND));
suggestions.put(OR.getLocalPart(), NAME_TO_ALIAS.get(OR));
suggestions.put(NOT.getLocalPart(), NAME_TO_ALIAS.get(NOT));
}

if (ruleContext instanceof ItemPathComponentContext) {
suggestions.add(META_TYPE);
suggestions.add(META_PATH);
suggestions.add(META_RELATION);
suggestions.put(META_TYPE, null);
suggestions.put(META_PATH, null);
suggestions.put(META_RELATION, null);
}

return suggestions;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ public void invalidateObjectType() {
new AxiomQueryError(null,
null,
1, 21, 30,
"Missing type definition",
"Missing object definition",
null)
);

Expand Down

0 comments on commit b0709bc

Please sign in to comment.