/** * * @return a new {@code QueryPath} with the next element as the new head. */ public QueryPath next() { return new QueryPath(path.subList(1, path.size())); }
/** * @return true if the current head of this query path matches the given {@code fieldNode} */ public boolean matches(FormTree.Node fieldNode) { String symbolName = path.get(0); return match(fieldNode, symbolName); }
private java.util.Optional<NodeMatch> matchCoordinate(QueryPath queryPath, FormTree.Node field) { String symbol = queryPath.peek().toLowerCase(); if(symbol.equals("latitude") || symbol.equals("longitude")) { return java.util.Optional.of(NodeMatch.forFieldComponent(field, symbol)); } else { return java.util.Optional.empty(); } }
private Optional<NodeMatch> matchEnum(QueryPath queryPath, FormTree.Node field) { if(queryPath.matches(field)) { QueryPath next = queryPath.next(); if(next.isLeaf()) { EnumType type = (EnumType) field.getType(); List<EnumItem> matchingItems = Lists.newArrayList(); for (EnumItem enumItem : type.getValues()) { if(next.head().equals(enumItem.getId().asString()) || next.head().equalsIgnoreCase(enumItem.getLabel()) || next.head().equalsIgnoreCase(enumItem.getCode())) { matchingItems.add(enumItem); } } if(matchingItems.size() == 1) { return Optional.of(NodeMatch.forFieldComponent(field, matchingItems.get(0).getId().asString())); } } } return Optional.absent(); }
/** * Resolves a compound expression like "province.name" to one or more {@code FormTree.Nodes} * * @return a binding to the corresponding {@code FormTree.Node} * * @throws AmbiguousSymbolException if the expression could match multiple nodes in the tree */ public Collection<NodeMatch> resolveCompoundExpr(CompoundExpr expr) { QueryPath queryPath = new QueryPath(expr); // Given an expression like Province.Name, see if we can match the // the first symbol against the root form's id or label if(queryPath.matches(tree.getRootFormClass())) { return matchNodes(queryPath.next(), tree.getRootFields()); } return matchNodes(queryPath, tree.getRootFields()); }
private Collection<NodeMatch> unionMatches(QueryPath path, FormTree.Node parentField) { List<NodeMatch> results = Lists.newArrayList(); for (ResourceId childFormId : parentField.getRange()) { Optional<FormClass> childForm = tree.getFormClassIfPresent(childFormId); if(childForm.isPresent()) { Iterable<FormTree.Node> childFields = parentField.getChildren(childFormId); if (path.matches(childForm.get()) && path.peek().equals(ColumnModel.RECORD_ID_SYMBOL)) { results.add(NodeMatch.forId(parentField, childForm.get())); } else if (path.matches(childForm.get()) || path.matches(parentField)) { results.addAll(matchNodes(path.next(), childFields)); } else { // Descend the next level results.addAll(matchNodes(path, childFields)); } } } return results; }
if(path.isLeaf() && path.head().equals(ColumnModel.FORM_NAME_SYMBOL)) { matches.add(NodeMatch.forLabel(path.head(), tree.getRootFormClass())); if (path.isLeaf() && path.head().equals(ColumnModel.RECORD_ID_SYMBOL) || path.head().equals(ColumnModel.FORM_ID_SYMBOL)) { matches.add(NodeMatch.forId(path.head(), tree.getRootFormClass())); if (path.isLeaf() && path.head().equals(tree.getRootFormId().asString())) { matches.add(NodeMatch.forId(ColumnModel.RECORD_ID_SYMBOL, tree.getRootFormClass())); if(path.matches(field)) { matches.add(NodeMatch.forField(field, currentAggregation())); } else if (field.getType() instanceof ReferenceType) { String symbol = path.head().toLowerCase(); if(symbol.equals("latitude") || symbol.equals("longitude")) { matches.add(NodeMatch.forFieldComponent(field, symbol)); throw new AmbiguousSymbolException(path.head(), "Could refer to " + Joiner.on(", ").join(matches));
private void referencedFormIdMatches(List<NodeMatch> matches, QueryPath path, FormTree.Node field) { for (ResourceId referencedFormId : ((ReferenceType) field.getType()).getRange()) { Optional<FormClass> refFormClass = tree.getFormClassIfPresent(referencedFormId); if (!refFormClass.isPresent()) { continue; } if (path.matches(refFormClass.get())) { matches.add(NodeMatch.forId(field, refFormClass.get())); } } }
private Collection<NodeMatch> matchNodes(QueryPath queryPath, Iterable<FormTree.Node> fields) { if(queryPath.isLeaf()) { return matchTerminal(queryPath, fields); } else { return matchReferenceField(queryPath, fields); } }
public Collection<NodeMatch> resolveSymbol(SymbolNode symbol) { return matchNodes(new QueryPath(symbol), tree.getRootFields()); }
private QueryPath newQueryPath(String expression) { FormulaNode expr = FormulaParser.parse(expression); return new QueryPath((CompoundExpr) expr); }