@Test public void testAll_of() { String a = "a"; String b = "b"; String c = "c"; String d = "d"; String e = "e"; String f = "f"; String g = "g"; String h = "h"; String j = "j"; String w = "w"; Bag bagabcdefg = null; Bag bagbdfhj = null; Bag bagace = null; Bag bagb = null; Bag bagaaacccef = null; Bag bagInt = null; Bag bagStringInt = null; Bag bagEmpty = null; Bag bagStringBooleansFalse = null; Bag bagStringBooleansTrue = null; FunctionArgumentAttributeValue attra = null; FunctionArgumentAttributeValue attrh = null; FunctionArgumentAttributeValue attrw = null; FunctionArgumentAttributeValue attrPredicateStringEqual = null; FunctionArgumentAttributeValue attrPredicateStringIntersection = null; FunctionArgumentAttributeValue attrPredicateStringGreaterThan = null; FunctionArgumentAttributeValue attrPredicateBooleanFromString = null; try { bagabcdefg = new Bag(); bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(a)); bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(b)); bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(c)); bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(d)); bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(e)); bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(f)); bagabcdefg.add(DataTypes.DT_STRING.createAttributeValue(g)); bagbdfhj = new Bag(); bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(b)); bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(d)); bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(f)); bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(h)); bagbdfhj.add(DataTypes.DT_STRING.createAttributeValue(j)); bagace = new Bag(); bagace.add(DataTypes.DT_STRING.createAttributeValue(a)); bagace.add(DataTypes.DT_STRING.createAttributeValue(c)); bagace.add(DataTypes.DT_STRING.createAttributeValue(e)); bagb = new Bag(); bagb.add(DataTypes.DT_STRING.createAttributeValue(b)); bagaaacccef = new Bag(); bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(a)); bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(c)); bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(e)); bagaaacccef.add(DataTypes.DT_STRING.createAttributeValue(f)); bagInt = new Bag(); bagInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); bagStringInt = new Bag(); bagStringInt.add(DataTypes.DT_STRING.createAttributeValue(a)); bagStringInt.add(DataTypes.DT_INTEGER.createAttributeValue(123)); bagEmpty = new Bag(); bagStringBooleansTrue = new Bag(); bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); bagStringBooleansTrue.add(DataTypes.DT_STRING.createAttributeValue("true")); bagStringBooleansFalse = new Bag(); bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); bagStringBooleansFalse.add(DataTypes.DT_STRING.createAttributeValue("false")); attra = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(a)); attrh = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(h)); attrw = new FunctionArgumentAttributeValue(DataTypes.DT_STRING.createAttributeValue(w)); attrPredicateStringEqual = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_EQUAL)); attrPredicateStringIntersection = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_INTERSECTION)); attrPredicateStringGreaterThan = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_STRING_GREATER_THAN)); attrPredicateBooleanFromString = new FunctionArgumentAttributeValue(DataTypes.DT_ANYURI.createAttributeValue(XACML3.ID_FUNCTION_BOOLEAN_FROM_STRING)); } catch (Exception ex) { fail("creating attribute e="+ ex); } FunctionArgumentBag attrBagabcdefg = new FunctionArgumentBag(bagabcdefg); FunctionArgumentBag attrBagbdfhj = new FunctionArgumentBag(bagbdfhj); FunctionArgumentBag attrBagace = new FunctionArgumentBag(bagace); FunctionArgumentBag attrBagStringInt = new FunctionArgumentBag(bagStringInt); FunctionArgumentBag attrBagEmpty = new FunctionArgumentBag(bagEmpty); FunctionArgumentBag attrBagStringBooleansTrue = new FunctionArgumentBag(bagStringBooleansTrue); FunctionArgumentBag attrBagStringBooleansFalse = new FunctionArgumentBag(bagStringBooleansFalse); FunctionDefinitionHigherOrderBag<?,?> fd = (FunctionDefinitionHigherOrderBag<?,?>) StdFunctions.FD_ALL_OF; assertEquals(XACML3.ID_FUNCTION_ALL_OF, fd.getId()); assertEquals(DataTypes.DT_BOOLEAN.getId(), fd.getDataTypeId()); assertFalse(fd.returnsBag()); arguments.clear(); arguments.add(attrPredicateStringGreaterThan); arguments.add(attrw); arguments.add(attrBagace); ExpressionResult res = fd.evaluate(null, arguments); assertTrue(res.isOk()); Boolean resValue = (Boolean)res.getValue().getValue(); assertTrue(resValue); arguments.clear(); arguments.add(attrPredicateStringGreaterThan); arguments.add(attra); arguments.add(attrBagbdfhj); res = fd.evaluate(null, arguments); assertTrue(res.isOk()); resValue = (Boolean)res.getValue().getValue(); assertFalse(resValue); arguments.clear(); arguments.add(attrPredicateStringEqual); arguments.add(attrBagace); res = fd.evaluate(null, arguments); assertFalse(res.isOk()); assertEquals("function:all-of Predicate error: function:string-equal Expected 2 arguments, got 1", res.getStatus().getStatusMessage()); assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); arguments.clear(); arguments.add(attrPredicateBooleanFromString); arguments.add(attrBagStringBooleansTrue); res = fd.evaluate(null, arguments); assertTrue(res.isOk()); resValue = (Boolean)res.getValue().getValue(); assertTrue(resValue); arguments.clear(); arguments.add(attrPredicateBooleanFromString); arguments.add(attrBagStringBooleansFalse); res = fd.evaluate(null, arguments); assertTrue(res.isOk()); resValue = (Boolean)res.getValue().getValue(); assertFalse(resValue); arguments.clear(); arguments.add(attrPredicateStringGreaterThan); arguments.add(attrh); arguments.add(attrBagEmpty); res = fd.evaluate(null, arguments); assertTrue(res.isOk()); resValue = (Boolean)res.getValue().getValue(); assertTrue(resValue); arguments.clear(); arguments.add(attrPredicateStringGreaterThan); arguments.add(attrh); res = fd.evaluate(null, arguments); assertFalse(res.isOk()); assertEquals("function:all-of Did not get any Bag argument; must have at least 1", res.getStatus().getStatusMessage()); assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); arguments.clear(); arguments.add(attrPredicateStringEqual); arguments.add(attrh); arguments.add(attrBagStringBooleansTrue); arguments.add(attrh); arguments.add(attrBagStringBooleansTrue); res = fd.evaluate(null, arguments); assertFalse(res.isOk()); assertEquals("function:all-of must have only 1 bag; found one at index 2 and another at 4", res.getStatus().getStatusMessage()); assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); arguments.clear(); arguments.add(attrh); arguments.add(attrBagStringInt); res = fd.evaluate(null, arguments); assertFalse(res.isOk()); assertEquals("function:all-of First argument expected URI, got http: assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); arguments.clear(); arguments.add(attrPredicateStringIntersection); arguments.add(attrh); arguments.add(attrBagStringInt); res = fd.evaluate(null, arguments); assertFalse(res.isOk()); assertEquals("function:all-of Predicate Function must return boolean, but 'urn:oasis:names:tc:xacml:1.0:function:string-intersection' returns 'string", res.getStatus().getStatusMessage()); assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); arguments.clear(); arguments.add(attrPredicateStringGreaterThan); arguments.add(attrPredicateStringIntersection); arguments.add(attrBagStringInt); res = fd.evaluate(null, arguments); assertFalse(res.isOk()); assertEquals("function:all-of Predicate error: function:string-greater-than Expected data type 'string' saw 'anyURI' at arg index 0", res.getStatus().getStatusMessage()); assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); arguments.clear(); arguments.add(attrPredicateStringGreaterThan); arguments.add(attrh); arguments.add(attrBagStringInt); res = fd.evaluate(null, arguments); assertFalse(res.isOk()); arguments.clear(); arguments.add(null); arguments.add(attrBagabcdefg); res = fd.evaluate(null, arguments); assertFalse(res.isOk()); assertEquals("function:all-of Predicate Function (first argument) was null", res.getStatus().getStatusMessage()); assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); arguments.clear(); arguments.add(attrPredicateStringGreaterThan); arguments.add(attrBagabcdefg); arguments.add(null); res = fd.evaluate(null, arguments); assertFalse(res.isOk()); assertEquals("function:all-of Got null argument at index 2", res.getStatus().getStatusMessage()); assertEquals("urn:oasis:names:tc:xacml:1.0:status:processing-error", res.getStatus().getStatusCode().getStatusCodeValue().stringValue()); }
@Override public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { if (arguments == null || arguments.size() < 2) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected at least 2 arguments, got " + ((arguments == null) ? "null" : arguments.size()) )); } if (operation == OPERATION.ALL_OF_ANY || operation == OPERATION.ANY_OF_ALL || operation == OPERATION.ALL_OF_ALL) { if (arguments.size() != 3) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected 3 arguments, got " + arguments.size()) ); } if ( arguments.get(1) == null || ! arguments.get(1).isBag() ) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " 2nd argument must be bag, got '" + ((arguments.get(1) == null) ? "null" : this.getShortDataTypeId(arguments.get(1).getValue().getDataTypeId())) + "'" )); } if (arguments.get(2) == null || ! arguments.get(2).isBag() ) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " 3rd argument must be bag, got '" + ((arguments.get(2) == null) ? "null" : this.getShortDataTypeId(arguments.get(2).getValue().getDataTypeId())) + "'" )); } } FunctionArgument functionIdArgument = arguments.get(0); if (functionIdArgument == null || functionIdArgument.getValue() == null) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate Function (first argument) was null")); } if ( ! functionIdArgument.getValue().getDataTypeId().equals(DataTypes.DT_ANYURI.getId())) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " First argument expected URI, got " + functionIdArgument.getValue().getDataTypeId() ) ); } Identifier functionId = new IdentifierImpl((URI) functionIdArgument.getValue().getValue()); StdFunctionDefinitionFactory fdf = new StdFunctionDefinitionFactory(); FunctionDefinition predicate = fdf.getFunctionDefinition(functionId); if (predicate == null) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " First argument was not URI of a function, got '" + functionId + "'") ); } if (operation != OPERATION.MAP) { if ( ! predicate.getDataTypeId().equals(DataTypes.DT_BOOLEAN.getId())) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate Function must return boolean, but '" + predicate.getId() + "' returns '" + this.getShortDataTypeId(predicate.getDataTypeId()) )); } } boolean bagSeen = false; for (int i = 1; i < arguments.size(); i++) { FunctionArgument argument = arguments.get(i); if (argument == null) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Got null argument at index " + i) ); } if ( ! argument.getStatus().isOk()) { return ExpressionResult.newError(getFunctionStatus(argument.getStatus())); } if (argument.isBag()) { bagSeen = true; } else { if (argument.getValue() == null || argument.getValue().getValue() == null) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Got null attribute at index " + i) ); } } } if ( ! bagSeen && operation != OPERATION.ANY_OF_ANY) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Did not get any Bag argument; must have at least 1") ); } List<FunctionArgument> predicateArguments = new ArrayList<FunctionArgument>(); int indexOfBagInOriginalArgs = -1; Iterator<AttributeValue<?>> bagIterator1; Iterator<AttributeValue<?>> bagIterator2; switch (operation) { case ANY_OF: for (int i = 1; i < arguments.size(); i++) { predicateArguments.add(arguments.get(i)); if (arguments.get(i).isBag()) { if (indexOfBagInOriginalArgs == -1) { indexOfBagInOriginalArgs = i ; } else { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) ); } } } bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == true) { return ER_TRUE; } } return ER_FALSE; case ALL_OF: for (int i = 1; i < arguments.size(); i++) { predicateArguments.add(arguments.get(i)); if (arguments.get(i).isBag()) { if (indexOfBagInOriginalArgs == -1) { indexOfBagInOriginalArgs = i ; } else { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) ); } } } bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == false) { return ER_FALSE; } } return ER_TRUE; case ANY_OF_ANY: for (int i = 1; i < arguments.size(); i++) { if (arguments.get(i).isBag() && arguments.get(i).getBag().size() == 0) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Bag is empty at index " + i )); } } List<List<FunctionArgument>> listOfPredicateLists = new ArrayList<List<FunctionArgument>>(); appendCrossProduct(new ArrayList<FunctionArgument>(), arguments.subList(1, arguments.size()), 0, listOfPredicateLists); for (List<FunctionArgument> predicateArgumentList : listOfPredicateLists) { ExpressionResult res = predicate.evaluate(evaluationContext, predicateArgumentList); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == true) { return ER_TRUE; } } return ER_FALSE; case ALL_OF_ANY: bagIterator2 = arguments.get(2).getBag().getAttributeValues(); while (bagIterator2.hasNext()) { FunctionArgument predicateArgument2 = new FunctionArgumentAttributeValue(bagIterator2.next()); boolean allMatch = true; bagIterator1 = arguments.get(1).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { predicateArguments.clear(); predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator1.next())); predicateArguments.add(predicateArgument2); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == false) { allMatch = false; break; } } if (allMatch) { return ER_TRUE; } } return ER_FALSE; case ANY_OF_ALL: bagIterator1 = arguments.get(1).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { FunctionArgument predicateArgument1 = new FunctionArgumentAttributeValue(bagIterator1.next()); boolean allMatch = true; bagIterator2 = arguments.get(2).getBag().getAttributeValues(); while (bagIterator2.hasNext()) { predicateArguments.clear(); predicateArguments.add(predicateArgument1); predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator2.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == false) { allMatch = false; break; } } if (allMatch) { return ER_TRUE; } } return ER_FALSE; case ALL_OF_ALL: bagIterator1 = arguments.get(1).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { FunctionArgument predicateArgument1 = new FunctionArgumentAttributeValue(bagIterator1.next()); bagIterator2 = arguments.get(2).getBag().getAttributeValues(); while (bagIterator2.hasNext()) { predicateArguments.clear(); predicateArguments.add(predicateArgument1); predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator2.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == false) { return ER_FALSE; } } } return ER_TRUE; case MAP: for (int i = 1; i < arguments.size(); i++) { predicateArguments.add(arguments.get(i)); if (arguments.get(i).isBag()) { if (indexOfBagInOriginalArgs == -1) { indexOfBagInOriginalArgs = i ; } else { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) ); } } } Bag outputBag = new Bag(); bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if (res.isBag()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Cannot put bag inside bag; predicate was '" + predicate.getId() + "'")); } outputBag.add(res.getValue()); } return ExpressionResult.newBag(outputBag); } return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Could not evaluate Higher-Order Bag function " + operation)); }
FunctionDefinitionHigherOrderBag extends FunctionDefinitionBase<O, I> { @Override public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { if (arguments == null || arguments.size() < 2) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected at least 2 arguments, got " + ((arguments == null) ? "null" : arguments.size()) )); } if (operation == OPERATION.ALL_OF_ANY || operation == OPERATION.ANY_OF_ALL || operation == OPERATION.ALL_OF_ALL) { if (arguments.size() != 3) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected 3 arguments, got " + arguments.size()) ); } if ( arguments.get(1) == null || ! arguments.get(1).isBag() ) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " 2nd argument must be bag, got '" + ((arguments.get(1) == null) ? "null" : this.getShortDataTypeId(arguments.get(1).getValue().getDataTypeId())) + "'" )); } if (arguments.get(2) == null || ! arguments.get(2).isBag() ) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " 3rd argument must be bag, got '" + ((arguments.get(2) == null) ? "null" : this.getShortDataTypeId(arguments.get(2).getValue().getDataTypeId())) + "'" )); } } FunctionArgument functionIdArgument = arguments.get(0); if (functionIdArgument == null || functionIdArgument.getValue() == null) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate Function (first argument) was null")); } if ( ! functionIdArgument.getValue().getDataTypeId().equals(DataTypes.DT_ANYURI.getId())) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " First argument expected URI, got " + functionIdArgument.getValue().getDataTypeId() ) ); } Identifier functionId = new IdentifierImpl((URI) functionIdArgument.getValue().getValue()); StdFunctionDefinitionFactory fdf = new StdFunctionDefinitionFactory(); FunctionDefinition predicate = fdf.getFunctionDefinition(functionId); if (predicate == null) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " First argument was not URI of a function, got '" + functionId + "'") ); } if (operation != OPERATION.MAP) { if ( ! predicate.getDataTypeId().equals(DataTypes.DT_BOOLEAN.getId())) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate Function must return boolean, but '" + predicate.getId() + "' returns '" + this.getShortDataTypeId(predicate.getDataTypeId()) )); } } boolean bagSeen = false; for (int i = 1; i < arguments.size(); i++) { FunctionArgument argument = arguments.get(i); if (argument == null) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Got null argument at index " + i) ); } if ( ! argument.getStatus().isOk()) { return ExpressionResult.newError(getFunctionStatus(argument.getStatus())); } if (argument.isBag()) { bagSeen = true; } else { if (argument.getValue() == null || argument.getValue().getValue() == null) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Got null attribute at index " + i) ); } } } if ( ! bagSeen && operation != OPERATION.ANY_OF_ANY) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Did not get any Bag argument; must have at least 1") ); } List<FunctionArgument> predicateArguments = new ArrayList<FunctionArgument>(); int indexOfBagInOriginalArgs = -1; Iterator<AttributeValue<?>> bagIterator1; Iterator<AttributeValue<?>> bagIterator2; switch (operation) { case ANY_OF: for (int i = 1; i < arguments.size(); i++) { predicateArguments.add(arguments.get(i)); if (arguments.get(i).isBag()) { if (indexOfBagInOriginalArgs == -1) { indexOfBagInOriginalArgs = i ; } else { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) ); } } } bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == true) { return ER_TRUE; } } return ER_FALSE; case ALL_OF: for (int i = 1; i < arguments.size(); i++) { predicateArguments.add(arguments.get(i)); if (arguments.get(i).isBag()) { if (indexOfBagInOriginalArgs == -1) { indexOfBagInOriginalArgs = i ; } else { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) ); } } } bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == false) { return ER_FALSE; } } return ER_TRUE; case ANY_OF_ANY: for (int i = 1; i < arguments.size(); i++) { if (arguments.get(i).isBag() && arguments.get(i).getBag().size() == 0) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Bag is empty at index " + i )); } } List<List<FunctionArgument>> listOfPredicateLists = new ArrayList<List<FunctionArgument>>(); appendCrossProduct(new ArrayList<FunctionArgument>(), arguments.subList(1, arguments.size()), 0, listOfPredicateLists); for (List<FunctionArgument> predicateArgumentList : listOfPredicateLists) { ExpressionResult res = predicate.evaluate(evaluationContext, predicateArgumentList); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == true) { return ER_TRUE; } } return ER_FALSE; case ALL_OF_ANY: bagIterator2 = arguments.get(2).getBag().getAttributeValues(); while (bagIterator2.hasNext()) { FunctionArgument predicateArgument2 = new FunctionArgumentAttributeValue(bagIterator2.next()); boolean allMatch = true; bagIterator1 = arguments.get(1).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { predicateArguments.clear(); predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator1.next())); predicateArguments.add(predicateArgument2); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == false) { allMatch = false; break; } } if (allMatch) { return ER_TRUE; } } return ER_FALSE; case ANY_OF_ALL: bagIterator1 = arguments.get(1).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { FunctionArgument predicateArgument1 = new FunctionArgumentAttributeValue(bagIterator1.next()); boolean allMatch = true; bagIterator2 = arguments.get(2).getBag().getAttributeValues(); while (bagIterator2.hasNext()) { predicateArguments.clear(); predicateArguments.add(predicateArgument1); predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator2.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == false) { allMatch = false; break; } } if (allMatch) { return ER_TRUE; } } return ER_FALSE; case ALL_OF_ALL: bagIterator1 = arguments.get(1).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { FunctionArgument predicateArgument1 = new FunctionArgumentAttributeValue(bagIterator1.next()); bagIterator2 = arguments.get(2).getBag().getAttributeValues(); while (bagIterator2.hasNext()) { predicateArguments.clear(); predicateArguments.add(predicateArgument1); predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator2.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == false) { return ER_FALSE; } } } return ER_TRUE; case MAP: for (int i = 1; i < arguments.size(); i++) { predicateArguments.add(arguments.get(i)); if (arguments.get(i).isBag()) { if (indexOfBagInOriginalArgs == -1) { indexOfBagInOriginalArgs = i ; } else { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) ); } } } Bag outputBag = new Bag(); bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if (res.isBag()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Cannot put bag inside bag; predicate was '" + predicate.getId() + "'")); } outputBag.add(res.getValue()); } return ExpressionResult.newBag(outputBag); } return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Could not evaluate Higher-Order Bag function " + operation)); } }
FunctionDefinitionHigherOrderBag extends FunctionDefinitionBase<O, I> { @Override public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { if (arguments == null || arguments.size() < 2) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected at least 2 arguments, got " + ((arguments == null) ? "null" : arguments.size()) )); } if (operation == OPERATION.ALL_OF_ANY || operation == OPERATION.ANY_OF_ALL || operation == OPERATION.ALL_OF_ALL) { if (arguments.size() != 3) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected 3 arguments, got " + arguments.size()) ); } if ( arguments.get(1) == null || ! arguments.get(1).isBag() ) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " 2nd argument must be bag, got '" + ((arguments.get(1) == null) ? "null" : this.getShortDataTypeId(arguments.get(1).getValue().getDataTypeId())) + "'" )); } if (arguments.get(2) == null || ! arguments.get(2).isBag() ) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " 3rd argument must be bag, got '" + ((arguments.get(2) == null) ? "null" : this.getShortDataTypeId(arguments.get(2).getValue().getDataTypeId())) + "'" )); } } FunctionArgument functionIdArgument = arguments.get(0); if (functionIdArgument == null || functionIdArgument.getValue() == null) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate Function (first argument) was null")); } if ( ! functionIdArgument.getValue().getDataTypeId().equals(DataTypes.DT_ANYURI.getId())) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " First argument expected URI, got " + functionIdArgument.getValue().getDataTypeId() ) ); } Identifier functionId = new IdentifierImpl((URI) functionIdArgument.getValue().getValue()); StdFunctionDefinitionFactory fdf = new StdFunctionDefinitionFactory(); FunctionDefinition predicate = fdf.getFunctionDefinition(functionId); if (predicate == null) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " First argument was not URI of a function, got '" + functionId + "'") ); } if (operation != OPERATION.MAP) { if ( ! predicate.getDataTypeId().equals(DataTypes.DT_BOOLEAN.getId())) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate Function must return boolean, but '" + predicate.getId() + "' returns '" + this.getShortDataTypeId(predicate.getDataTypeId()) )); } } boolean bagSeen = false; for (int i = 1; i < arguments.size(); i++) { FunctionArgument argument = arguments.get(i); if (argument == null) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Got null argument at index " + i) ); } if ( ! argument.getStatus().isOk()) { return ExpressionResult.newError(getFunctionStatus(argument.getStatus())); } if (argument.isBag()) { bagSeen = true; } else { if (argument.getValue() == null || argument.getValue().getValue() == null) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Got null attribute at index " + i) ); } } } if ( ! bagSeen && operation != OPERATION.ANY_OF_ANY) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Did not get any Bag argument; must have at least 1") ); } List<FunctionArgument> predicateArguments = new ArrayList<FunctionArgument>(); int indexOfBagInOriginalArgs = -1; Iterator<AttributeValue<?>> bagIterator1; Iterator<AttributeValue<?>> bagIterator2; switch (operation) { case ANY_OF: for (int i = 1; i < arguments.size(); i++) { predicateArguments.add(arguments.get(i)); if (arguments.get(i).isBag()) { if (indexOfBagInOriginalArgs == -1) { indexOfBagInOriginalArgs = i ; } else { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) ); } } } bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == true) { return ER_TRUE; } } return ER_FALSE; case ALL_OF: for (int i = 1; i < arguments.size(); i++) { predicateArguments.add(arguments.get(i)); if (arguments.get(i).isBag()) { if (indexOfBagInOriginalArgs == -1) { indexOfBagInOriginalArgs = i ; } else { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) ); } } } bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == false) { return ER_FALSE; } } return ER_TRUE; case ANY_OF_ANY: for (int i = 1; i < arguments.size(); i++) { if (arguments.get(i).isBag() && arguments.get(i).getBag().size() == 0) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Bag is empty at index " + i )); } } List<List<FunctionArgument>> listOfPredicateLists = new ArrayList<List<FunctionArgument>>(); appendCrossProduct(new ArrayList<FunctionArgument>(), arguments.subList(1, arguments.size()), 0, listOfPredicateLists); for (List<FunctionArgument> predicateArgumentList : listOfPredicateLists) { ExpressionResult res = predicate.evaluate(evaluationContext, predicateArgumentList); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == true) { return ER_TRUE; } } return ER_FALSE; case ALL_OF_ANY: bagIterator2 = arguments.get(2).getBag().getAttributeValues(); while (bagIterator2.hasNext()) { FunctionArgument predicateArgument2 = new FunctionArgumentAttributeValue(bagIterator2.next()); boolean allMatch = true; bagIterator1 = arguments.get(1).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { predicateArguments.clear(); predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator1.next())); predicateArguments.add(predicateArgument2); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == false) { allMatch = false; break; } } if (allMatch) { return ER_TRUE; } } return ER_FALSE; case ANY_OF_ALL: bagIterator1 = arguments.get(1).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { FunctionArgument predicateArgument1 = new FunctionArgumentAttributeValue(bagIterator1.next()); boolean allMatch = true; bagIterator2 = arguments.get(2).getBag().getAttributeValues(); while (bagIterator2.hasNext()) { predicateArguments.clear(); predicateArguments.add(predicateArgument1); predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator2.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == false) { allMatch = false; break; } } if (allMatch) { return ER_TRUE; } } return ER_FALSE; case ALL_OF_ALL: bagIterator1 = arguments.get(1).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { FunctionArgument predicateArgument1 = new FunctionArgumentAttributeValue(bagIterator1.next()); bagIterator2 = arguments.get(2).getBag().getAttributeValues(); while (bagIterator2.hasNext()) { predicateArguments.clear(); predicateArguments.add(predicateArgument1); predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator2.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == false) { return ER_FALSE; } } } return ER_TRUE; case MAP: for (int i = 1; i < arguments.size(); i++) { predicateArguments.add(arguments.get(i)); if (arguments.get(i).isBag()) { if (indexOfBagInOriginalArgs == -1) { indexOfBagInOriginalArgs = i ; } else { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) ); } } } Bag outputBag = new Bag(); bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if (res.isBag()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Cannot put bag inside bag; predicate was '" + predicate.getId() + "'")); } outputBag.add(res.getValue()); } return ExpressionResult.newBag(outputBag); } return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Could not evaluate Higher-Order Bag function " + operation)); } FunctionDefinitionHigherOrderBag(Identifier idIn, DataType<O> dataTypeIn, DataType<I> dataTypeArgsIn, OPERATION opIn); }
FunctionDefinitionHigherOrderBag extends FunctionDefinitionBase<O, I> { @Override public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { if (arguments == null || arguments.size() < 2) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected at least 2 arguments, got " + ((arguments == null) ? "null" : arguments.size()) )); } if (operation == OPERATION.ALL_OF_ANY || operation == OPERATION.ANY_OF_ALL || operation == OPERATION.ALL_OF_ALL) { if (arguments.size() != 3) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected 3 arguments, got " + arguments.size()) ); } if ( arguments.get(1) == null || ! arguments.get(1).isBag() ) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " 2nd argument must be bag, got '" + ((arguments.get(1) == null) ? "null" : this.getShortDataTypeId(arguments.get(1).getValue().getDataTypeId())) + "'" )); } if (arguments.get(2) == null || ! arguments.get(2).isBag() ) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " 3rd argument must be bag, got '" + ((arguments.get(2) == null) ? "null" : this.getShortDataTypeId(arguments.get(2).getValue().getDataTypeId())) + "'" )); } } FunctionArgument functionIdArgument = arguments.get(0); if (functionIdArgument == null || functionIdArgument.getValue() == null) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate Function (first argument) was null")); } if ( ! functionIdArgument.getValue().getDataTypeId().equals(DataTypes.DT_ANYURI.getId())) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " First argument expected URI, got " + functionIdArgument.getValue().getDataTypeId() ) ); } Identifier functionId = new IdentifierImpl((URI) functionIdArgument.getValue().getValue()); StdFunctionDefinitionFactory fdf = new StdFunctionDefinitionFactory(); FunctionDefinition predicate = fdf.getFunctionDefinition(functionId); if (predicate == null) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " First argument was not URI of a function, got '" + functionId + "'") ); } if (operation != OPERATION.MAP) { if ( ! predicate.getDataTypeId().equals(DataTypes.DT_BOOLEAN.getId())) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate Function must return boolean, but '" + predicate.getId() + "' returns '" + this.getShortDataTypeId(predicate.getDataTypeId()) )); } } boolean bagSeen = false; for (int i = 1; i < arguments.size(); i++) { FunctionArgument argument = arguments.get(i); if (argument == null) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Got null argument at index " + i) ); } if ( ! argument.getStatus().isOk()) { return ExpressionResult.newError(getFunctionStatus(argument.getStatus())); } if (argument.isBag()) { bagSeen = true; } else { if (argument.getValue() == null || argument.getValue().getValue() == null) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Got null attribute at index " + i) ); } } } if ( ! bagSeen && operation != OPERATION.ANY_OF_ANY) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Did not get any Bag argument; must have at least 1") ); } List<FunctionArgument> predicateArguments = new ArrayList<FunctionArgument>(); int indexOfBagInOriginalArgs = -1; Iterator<AttributeValue<?>> bagIterator1; Iterator<AttributeValue<?>> bagIterator2; switch (operation) { case ANY_OF: for (int i = 1; i < arguments.size(); i++) { predicateArguments.add(arguments.get(i)); if (arguments.get(i).isBag()) { if (indexOfBagInOriginalArgs == -1) { indexOfBagInOriginalArgs = i ; } else { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) ); } } } bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == true) { return ER_TRUE; } } return ER_FALSE; case ALL_OF: for (int i = 1; i < arguments.size(); i++) { predicateArguments.add(arguments.get(i)); if (arguments.get(i).isBag()) { if (indexOfBagInOriginalArgs == -1) { indexOfBagInOriginalArgs = i ; } else { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) ); } } } bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == false) { return ER_FALSE; } } return ER_TRUE; case ANY_OF_ANY: for (int i = 1; i < arguments.size(); i++) { if (arguments.get(i).isBag() && arguments.get(i).getBag().size() == 0) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Bag is empty at index " + i )); } } List<List<FunctionArgument>> listOfPredicateLists = new ArrayList<List<FunctionArgument>>(); appendCrossProduct(new ArrayList<FunctionArgument>(), arguments.subList(1, arguments.size()), 0, listOfPredicateLists); for (List<FunctionArgument> predicateArgumentList : listOfPredicateLists) { ExpressionResult res = predicate.evaluate(evaluationContext, predicateArgumentList); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == true) { return ER_TRUE; } } return ER_FALSE; case ALL_OF_ANY: bagIterator2 = arguments.get(2).getBag().getAttributeValues(); while (bagIterator2.hasNext()) { FunctionArgument predicateArgument2 = new FunctionArgumentAttributeValue(bagIterator2.next()); boolean allMatch = true; bagIterator1 = arguments.get(1).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { predicateArguments.clear(); predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator1.next())); predicateArguments.add(predicateArgument2); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == false) { allMatch = false; break; } } if (allMatch) { return ER_TRUE; } } return ER_FALSE; case ANY_OF_ALL: bagIterator1 = arguments.get(1).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { FunctionArgument predicateArgument1 = new FunctionArgumentAttributeValue(bagIterator1.next()); boolean allMatch = true; bagIterator2 = arguments.get(2).getBag().getAttributeValues(); while (bagIterator2.hasNext()) { predicateArguments.clear(); predicateArguments.add(predicateArgument1); predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator2.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == false) { allMatch = false; break; } } if (allMatch) { return ER_TRUE; } } return ER_FALSE; case ALL_OF_ALL: bagIterator1 = arguments.get(1).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { FunctionArgument predicateArgument1 = new FunctionArgumentAttributeValue(bagIterator1.next()); bagIterator2 = arguments.get(2).getBag().getAttributeValues(); while (bagIterator2.hasNext()) { predicateArguments.clear(); predicateArguments.add(predicateArgument1); predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator2.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == false) { return ER_FALSE; } } } return ER_TRUE; case MAP: for (int i = 1; i < arguments.size(); i++) { predicateArguments.add(arguments.get(i)); if (arguments.get(i).isBag()) { if (indexOfBagInOriginalArgs == -1) { indexOfBagInOriginalArgs = i ; } else { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) ); } } } Bag outputBag = new Bag(); bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if (res.isBag()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Cannot put bag inside bag; predicate was '" + predicate.getId() + "'")); } outputBag.add(res.getValue()); } return ExpressionResult.newBag(outputBag); } return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Could not evaluate Higher-Order Bag function " + operation)); } FunctionDefinitionHigherOrderBag(Identifier idIn, DataType<O> dataTypeIn, DataType<I> dataTypeArgsIn, OPERATION opIn); @Override ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments); }
FunctionDefinitionHigherOrderBag extends FunctionDefinitionBase<O, I> { @Override public ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments) { if (arguments == null || arguments.size() < 2) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected at least 2 arguments, got " + ((arguments == null) ? "null" : arguments.size()) )); } if (operation == OPERATION.ALL_OF_ANY || operation == OPERATION.ANY_OF_ALL || operation == OPERATION.ALL_OF_ALL) { if (arguments.size() != 3) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Expected 3 arguments, got " + arguments.size()) ); } if ( arguments.get(1) == null || ! arguments.get(1).isBag() ) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " 2nd argument must be bag, got '" + ((arguments.get(1) == null) ? "null" : this.getShortDataTypeId(arguments.get(1).getValue().getDataTypeId())) + "'" )); } if (arguments.get(2) == null || ! arguments.get(2).isBag() ) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " 3rd argument must be bag, got '" + ((arguments.get(2) == null) ? "null" : this.getShortDataTypeId(arguments.get(2).getValue().getDataTypeId())) + "'" )); } } FunctionArgument functionIdArgument = arguments.get(0); if (functionIdArgument == null || functionIdArgument.getValue() == null) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate Function (first argument) was null")); } if ( ! functionIdArgument.getValue().getDataTypeId().equals(DataTypes.DT_ANYURI.getId())) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " First argument expected URI, got " + functionIdArgument.getValue().getDataTypeId() ) ); } Identifier functionId = new IdentifierImpl((URI) functionIdArgument.getValue().getValue()); StdFunctionDefinitionFactory fdf = new StdFunctionDefinitionFactory(); FunctionDefinition predicate = fdf.getFunctionDefinition(functionId); if (predicate == null) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " First argument was not URI of a function, got '" + functionId + "'") ); } if (operation != OPERATION.MAP) { if ( ! predicate.getDataTypeId().equals(DataTypes.DT_BOOLEAN.getId())) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate Function must return boolean, but '" + predicate.getId() + "' returns '" + this.getShortDataTypeId(predicate.getDataTypeId()) )); } } boolean bagSeen = false; for (int i = 1; i < arguments.size(); i++) { FunctionArgument argument = arguments.get(i); if (argument == null) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Got null argument at index " + i) ); } if ( ! argument.getStatus().isOk()) { return ExpressionResult.newError(getFunctionStatus(argument.getStatus())); } if (argument.isBag()) { bagSeen = true; } else { if (argument.getValue() == null || argument.getValue().getValue() == null) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Got null attribute at index " + i) ); } } } if ( ! bagSeen && operation != OPERATION.ANY_OF_ANY) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Did not get any Bag argument; must have at least 1") ); } List<FunctionArgument> predicateArguments = new ArrayList<FunctionArgument>(); int indexOfBagInOriginalArgs = -1; Iterator<AttributeValue<?>> bagIterator1; Iterator<AttributeValue<?>> bagIterator2; switch (operation) { case ANY_OF: for (int i = 1; i < arguments.size(); i++) { predicateArguments.add(arguments.get(i)); if (arguments.get(i).isBag()) { if (indexOfBagInOriginalArgs == -1) { indexOfBagInOriginalArgs = i ; } else { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) ); } } } bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == true) { return ER_TRUE; } } return ER_FALSE; case ALL_OF: for (int i = 1; i < arguments.size(); i++) { predicateArguments.add(arguments.get(i)); if (arguments.get(i).isBag()) { if (indexOfBagInOriginalArgs == -1) { indexOfBagInOriginalArgs = i ; } else { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) ); } } } bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == false) { return ER_FALSE; } } return ER_TRUE; case ANY_OF_ANY: for (int i = 1; i < arguments.size(); i++) { if (arguments.get(i).isBag() && arguments.get(i).getBag().size() == 0) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Bag is empty at index " + i )); } } List<List<FunctionArgument>> listOfPredicateLists = new ArrayList<List<FunctionArgument>>(); appendCrossProduct(new ArrayList<FunctionArgument>(), arguments.subList(1, arguments.size()), 0, listOfPredicateLists); for (List<FunctionArgument> predicateArgumentList : listOfPredicateLists) { ExpressionResult res = predicate.evaluate(evaluationContext, predicateArgumentList); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == true) { return ER_TRUE; } } return ER_FALSE; case ALL_OF_ANY: bagIterator2 = arguments.get(2).getBag().getAttributeValues(); while (bagIterator2.hasNext()) { FunctionArgument predicateArgument2 = new FunctionArgumentAttributeValue(bagIterator2.next()); boolean allMatch = true; bagIterator1 = arguments.get(1).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { predicateArguments.clear(); predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator1.next())); predicateArguments.add(predicateArgument2); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == false) { allMatch = false; break; } } if (allMatch) { return ER_TRUE; } } return ER_FALSE; case ANY_OF_ALL: bagIterator1 = arguments.get(1).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { FunctionArgument predicateArgument1 = new FunctionArgumentAttributeValue(bagIterator1.next()); boolean allMatch = true; bagIterator2 = arguments.get(2).getBag().getAttributeValues(); while (bagIterator2.hasNext()) { predicateArguments.clear(); predicateArguments.add(predicateArgument1); predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator2.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == false) { allMatch = false; break; } } if (allMatch) { return ER_TRUE; } } return ER_FALSE; case ALL_OF_ALL: bagIterator1 = arguments.get(1).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { FunctionArgument predicateArgument1 = new FunctionArgumentAttributeValue(bagIterator1.next()); bagIterator2 = arguments.get(2).getBag().getAttributeValues(); while (bagIterator2.hasNext()) { predicateArguments.clear(); predicateArguments.add(predicateArgument1); predicateArguments.add(new FunctionArgumentAttributeValue(bagIterator2.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if ( (Boolean)(res.getValue().getValue()) == false) { return ER_FALSE; } } } return ER_TRUE; case MAP: for (int i = 1; i < arguments.size(); i++) { predicateArguments.add(arguments.get(i)); if (arguments.get(i).isBag()) { if (indexOfBagInOriginalArgs == -1) { indexOfBagInOriginalArgs = i ; } else { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " must have only 1 bag; found one at index " + indexOfBagInOriginalArgs + " and another at " + i) ); } } } Bag outputBag = new Bag(); bagIterator1 = arguments.get(indexOfBagInOriginalArgs).getBag().getAttributeValues(); while (bagIterator1.hasNext()) { predicateArguments.set(indexOfBagInOriginalArgs - 1, new FunctionArgumentAttributeValue(bagIterator1.next())); ExpressionResult res = predicate.evaluate(evaluationContext, predicateArguments); if ( ! res.isOk()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Predicate error: " + res.getStatus().getStatusMessage()) ); } if (res.isBag()) { return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Cannot put bag inside bag; predicate was '" + predicate.getId() + "'")); } outputBag.add(res.getValue()); } return ExpressionResult.newBag(outputBag); } return ExpressionResult.newError(new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, this.getShortFunctionId() + " Could not evaluate Higher-Order Bag function " + operation)); } FunctionDefinitionHigherOrderBag(Identifier idIn, DataType<O> dataTypeIn, DataType<I> dataTypeArgsIn, OPERATION opIn); @Override ExpressionResult evaluate(EvaluationContext evaluationContext, List<FunctionArgument> arguments);  }