public Slot<TableFilter> filter(FormulaNode filter) { if(filter == null) { return new PendingSlot<>(TableFilter.ALL_SELECTED); } else { return new MemoizedSlot<>(evaluateExpression(filter), new Function<ColumnView, TableFilter>() { @Override public TableFilter apply(ColumnView columnView) { return new TableFilter(columnView); } }); } }
private Slot<ColumnView> expandCalculatedField(NodeMatch node) { try { Slot<ColumnView> calculation = evaluateExpression(node.getCalculation()); FormulaNode relevanceFormula = tryParseRelevance(node); if(relevanceFormula == null) { return calculation; } else { return new MemoizedSlot2<>(calculation, evaluateExpression(relevanceFormula), new BiFunction<ColumnView, ColumnView, ColumnView>() { @Override public ColumnView apply(ColumnView calculation, ColumnView relevance) { return new RelevanceViewMask(calculation, relevance); } }); } } catch (FormulaException e) { LOGGER.log(Level.WARNING, "Exception in calculated field " + node.getFormClass().getId() + "." + node.getFieldComponent() + " = " + node.getCalculation() + ": " + e.getMessage(), e); return batch.addEmptyColumn(filterLevel, node.getFormClass()); } }
private Slot<TableFilter> computePermissionFilter(ResourceId formId) { FormPermissions permissions = supervisor.getFormPermissions(formId); if(!permissions.isVisible()) { return new PendingSlot<>(TableFilter.NONE_SELECTED); } if(!permissions.hasVisibilityFilter()) { return new PendingSlot<>(TableFilter.ALL_SELECTED); } // Otherwise apply per-record permissions try { FormTreeBuilder formTreeBuilder = new FormTreeBuilder(formClassProvider); FormTree formTree = formTreeBuilder.queryTree(formId); FormulaNode formula = FormulaParser.parse(permissions.getViewFilter()); QueryEvaluator evaluator = new QueryEvaluator(FilterLevel.NONE, formTree, this); Slot<ColumnView> filterView = evaluator.evaluateExpression(formula); return new MemoizedSlot<>(filterView, new Function<ColumnView, TableFilter>() { @Override public TableFilter apply(ColumnView columnView) { return new TableFilter(columnView); } }); } catch (Exception e) { LOGGER.log(Level.SEVERE, "Failed to parse visibility filter", e); LOGGER.severe("Error parsing visibility filter '" + permissions.getViewFilter() + " in form " + formId + ": " + e.getMessage() + ". " + "For security reasons, no results will be shown"); return new PendingSlot<>(TableFilter.NONE_SELECTED); } }
Slot<ColumnView> view; try { view = evaluateExpression(column.getFormula()); } catch (FormulaException e) { throw new QuerySyntaxException("Syntax error in column " + column.getId() +
@Test public void circularReference() throws Exception { final FormClass formClass = new FormClass(ResourceId.valueOf("XYZ")); formClass.addField(ResourceId.valueOf("FA")) .setCode("A") .setLabel("Field A") .setType(new CalculatedFieldType("B")); formClass.addField(ResourceId.valueOf("FB")) .setCode("B") .setLabel("Field B") .setType(new CalculatedFieldType("A")); FormStorageProviderStub catalog = new FormStorageProviderStub(); catalog.addForm(formClass).withRowCount(10); ColumnSetBuilder builder = new ColumnSetBuilder(catalog, new NullFormScanCache(), new NullFormSupervisor()); FormScanBatch batch = builder.createNewBatch(); QueryEvaluator evaluator = new QueryEvaluator(FilterLevel.BASE, catalog.getTree(formClass.getId()), batch); Slot<ColumnView> a = evaluator.evaluateExpression(new SymbolNode("A")); Slot<ColumnView> aPlusOne = evaluator.evaluateExpression(FormulaParser.parse("A+1")); builder.execute(batch); assertThat(a.get().numRows(), equalTo(10)); assertThat(a.get().getString(0), nullValue()); assertThat(aPlusOne.get().getString(0), equalTo(Double.toString(1d))); assertThat(aPlusOne.get().getDouble(0), equalTo(1d)); }