use of com.linkedin.data.element.DataElement in project incubator-gobblin by apache.
the class CronValidator method validate.
@Override
public void validate(ValidatorContext ctx) {
DataElement element = ctx.dataElement();
Object value = element.getValue();
String str = String.valueOf(value);
if (!CronExpression.isValidExpression(str)) {
ctx.addResult(new Message(element.path(), "\"%1$s\" is not in Cron format", str));
}
}
use of com.linkedin.data.element.DataElement in project incubator-gobblin by apache.
the class TemplateUriValidator method validate.
@Override
public void validate(ValidatorContext ctx) {
DataElement element = ctx.dataElement();
Object value = element.getValue();
String str = String.valueOf(value);
boolean valid = true;
try {
Iterable<String> uriStrings = Splitter.on(",").omitEmptyStrings().trimResults().split(str);
for (String uriString : uriStrings) {
URI uri = new URI(uriString);
if (!uri.getScheme().equalsIgnoreCase(FS_SCHEME)) {
throw new URISyntaxException(uriString, "Scheme is not FS");
}
}
} catch (URISyntaxException e) {
valid = false;
}
if (!valid) {
ctx.addResult(new Message(element.path(), "\"%1$s\" is not a well-formed comma-separated list of URIs", str));
}
}
use of com.linkedin.data.element.DataElement in project rest.li by linkedin.
the class TestPatchFilterValidator method testPatchFilterValidator.
@Test
public void testPatchFilterValidator() throws IOException {
String schemaText = "{\n" + " \"type\" : \"record\",\n" + " \"name\" : \"Foo\",\n" + " \"fields\" : [\n" + " { \"name\" : \"fooInt\", \"type\" : \"int\", \"optional\" : true },\n" + " { \"name\" : \"fooString\", \"type\" : \"string\", \"optional\" : true },\n" + " {\n" + " \"name\" : \"bar\",\n" + " \"type\" : {\n" + " \"type\" : \"record\",\n" + " \"name\" : \"Bar\",\n" + " \"fields\" : [\n" + " { \"name\" : \"barInt\", \"type\" : \"int\", \"optional\" : true },\n" + " { \"name\" : \"barString\", \"type\" : \"string\", \"optional\" : true },\n" + " {\n" + " \"name\" : \"baz\",\n" + " \"type\" : {\n" + " \"type\" : \"record\",\n" + " \"name\" : \"Baz\",\n" + " \"fields\" : [\n" + " { \"name\" : \"bazInt\", \"type\" : \"int\", \"optional\" : true },\n" + " { \"name\" : \"bazString\", \"type\" : \"string\", \"optional\" : true }\n" + " ]\n" + " },\n" + " \"optional\" : true\n" + " }\n" + " ]\n" + " },\n" + " \"optional\" : true\n" + " }\n" + " ]\n" + "}\n";
Object[][] inputs = { // }
{ // deleted /fooInt
"{ }", "{ \"$delete\" : [ \"fooInt\" ] }", "", asList(Mode.SET_ONLY), asList(Mode.PARENT_AND_SET, ""), asList(Mode.ANCESTOR_AND_SET, "") }, { // must not call validator for parents and ancestors not modified
"{ \"fooString\" : \"excluded\", \"bar\" : { \"barInt\" : -1 } }", "{ \"$delete\" : [ \"fooInt\" ] }", "", asList(Mode.SET_ONLY), asList(Mode.PARENT_AND_SET, ""), asList(Mode.ANCESTOR_AND_SET, "") }, { // deleted /bar/barInt
"{ \"bar\" : { } }", "{ \"bar\" : { \"$delete\" : [ \"barInt\" ] } }", "", asList(Mode.SET_ONLY), asList(Mode.PARENT_AND_SET, "/bar"), asList(Mode.ANCESTOR_AND_SET, "", "/bar") }, { // must not call validator for parents and ancestors not modified
"{ \"fooInt\" : -1, \"fooString\" : \"excluded\", \"bar\" : { } }", "{ \"bar\" : { \"$delete\" : [ \"barInt\" ] } }", "", asList(Mode.SET_ONLY), asList(Mode.PARENT_AND_SET, "/bar"), asList(Mode.ANCESTOR_AND_SET, "", "/bar") }, { // deleted /bar/baz/bazInt
"{ \"bar\" : { \"baz\" : { } } }", "{ \"bar\" : { \"baz\" : { \"$delete\" : [ \"bazInt\" ] } } }", "", asList(Mode.SET_ONLY), asList(Mode.PARENT_AND_SET, "/bar/baz"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz") }, { // must not call validator for parents and ancestors not modified
"{ \"fooInt\" : -1, \"fooString\" : \"excluded\", \"bar\" : { \"barInt\" : -1, \"baz\" : { } } }", "{ \"bar\" : { \"baz\" : { \"$delete\" : [ \"bazInt\" ] } } }", "", asList(Mode.SET_ONLY), asList(Mode.PARENT_AND_SET, "/bar/baz"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz") }, { // deleted /bar/baz
"{ \"bar\" : { } }", "{ \"bar\" : { \"$delete\" : [ \"baz\" ] } }", "", asList(Mode.SET_ONLY), asList(Mode.PARENT_AND_SET, "/bar"), asList(Mode.ANCESTOR_AND_SET, "", "/bar") }, { // must not call validator for parents and ancestors not modified
"{ \"fooInt\" : -1, \"fooString\" : \"excluded\", \"bar\" : { \"barInt\" : -1 } }", "{ \"bar\" : { \"$delete\" : [ \"baz\" ] } }", "", asList(Mode.SET_ONLY), asList(Mode.PARENT_AND_SET, "/bar"), asList(Mode.ANCESTOR_AND_SET, "", "/bar") }, { // set /fooInt (set field in root record)
"{ \"fooInt\" : 2 }", "{ \"$set\" : { \"fooInt\" : 2 } }", "", asList(Mode.SET_ONLY, "/fooInt"), asList(Mode.PARENT_AND_SET, "", "/fooInt"), asList(Mode.ANCESTOR_AND_SET, "", "/fooInt") }, { // must not call validator for parents and ancestors not modified
"{ \"fooInt\" : 2, \"fooString\" : \"excluded\", \"bar\" : { \"baz\" : { } } }", "{ \"$set\" : { \"fooInt\" : 2 } }", "", asList(Mode.SET_ONLY, "/fooInt"), asList(Mode.PARENT_AND_SET, "", "/fooInt"), asList(Mode.ANCESTOR_AND_SET, "", "/fooInt") }, { // must not call validator for parents and ancestors not modified
"{\n" + " \"fooInt\" : 2,\n" + " \"fooString\" : \"excluded\",\n" + " \"bar\" : {\n" + " \"barInt\" : 2,\n" + " \"barString\" : \"excluded\",\n" + " \"baz\" : {}\n" + " }\n" + "}", "{ \"bar\" : { \"$set\" : { \"barInt\" : 2 } } }", "", asList(Mode.SET_ONLY, "/bar/barInt"), asList(Mode.PARENT_AND_SET, "/bar", "/bar/barInt"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/barInt") }, { // must not call validator for parents and ancestors not modified
"{\n" + " \"fooInt\" : -1,\n" + " \"fooString\" : \"excludes\",\n" + " \"bar\" : {\n" + " \"barInt\" : -1,\n" + " \"barString\" : \"x\",\n" + " \"baz\" : {\n" + " \"bazInt\" : 2,\n" + " \"bazString\" : \"excludes\"\n" + " }\n" + " }\n" + "}", "{ \"bar\" : { \"$set\" : { \"barString\" : \"x\" } } }", "", asList(Mode.SET_ONLY, "/bar/barString"), asList(Mode.PARENT_AND_SET, "/bar", "/bar/barString"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/barString") }, { // set /bar/baz/bazInt (set field in nested grandchild record)
"{ \"bar\" : { \"baz\" : { \"bazInt\" : 2 } } }", "{ \"bar\" : { \"baz\" : { \"$set\" : { \"bazInt\" : 2 } } } }", "", asList(Mode.SET_ONLY, "/bar/baz/bazInt"), asList(Mode.PARENT_AND_SET, "/bar/baz", "/bar/baz/bazInt"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt") }, { // must not call validator for parents and ancestors not modified
"{\n" + " \"fooInt\" : 2,\n" + " \"fooString\" : \"excluded\",\n" + " \"bar\" : {\n" + " \"barInt\" : 2,\n" + " \"barString\" : \"excluded\",\n" + " \"baz\" : {\n" + " \"bazInt\" : 2,\n" + " \"bazString\" : \"excluded\"\n" + " }\n" + " }\n" + "}", "{ \"bar\" : { \"baz\" : { \"$set\" : { \"bazInt\" : 2 } } } }", "", asList(Mode.SET_ONLY, "/bar/baz/bazInt"), asList(Mode.PARENT_AND_SET, "/bar/baz", "/bar/baz/bazInt"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt") }, { // must not call validator for parents and ancestors not modified
"{\n" + " \"fooInt\" : -1,\n" + " \"fooString\" : \"excludes\",\n" + " \"bar\" : {\n" + " \"barInt\" : -1,\n" + " \"baz\" : {\n" + " \"bazInt\" : 2,\n" + " \"bazString\" : \"excludes\"\n" + " }\n" + " }\n" + "}", "{ \"bar\" : { \"baz\" : { \"$set\" : { \"bazInt\" : 2 } } } }", "", asList(Mode.SET_ONLY, "/bar/baz/bazInt"), asList(Mode.PARENT_AND_SET, "/bar/baz", "/bar/baz/bazInt"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt") }, { // set /bar (set record in root record)
"{ \"bar\" : { \"baz\" : { \"bazInt\" : 2 } } }", "{ \"$set\" : { \"bar\" : { \"baz\" : { \"bazInt\" : 2 } } } }", "", asList(Mode.SET_ONLY, "/bar", "/bar/baz", "/bar/baz/bazInt"), asList(Mode.PARENT_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt") }, { // must not call validator for parents and ancestors not modified
"{\n" + " \"fooInt\" : 2,\n" + " \"fooString\" : \"excluded\",\n" + " \"bar\" : {\n" + " \"baz\" : {\n" + " \"bazInt\" : 2\n" + " }\n" + " }\n" + "}", "{ \"bar\" : { \"baz\" : { \"$set\" : { \"bazInt\" : 2 } } } }", "", asList(Mode.SET_ONLY, "/bar/baz/bazInt"), asList(Mode.PARENT_AND_SET, "/bar/baz", "/bar/baz/bazInt"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt") }, { // set /bar/baz (set record in nested child record)
"{ \"bar\" : { \"baz\" : { \"bazInt\" : 2 } } }", "{ \"bar\" : { \"$set\" : { \"baz\" : { \"bazInt\" : 2 } } } }", "", asList(Mode.SET_ONLY, "/bar/baz", "/bar/baz/bazInt"), asList(Mode.PARENT_AND_SET, "/bar", "/bar/baz", "/bar/baz/bazInt"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt") }, { // must not call validator for parents and ancestors not modified
"{\n" + " \"fooInt\" : 2,\n" + " \"fooString\" : \"excluded\",\n" + " \"bar\" : {\n" + " \"barInt\" : 2,\n" + " \"barString\" : \"excluded\",\n" + " \"baz\" : {\n" + " \"bazInt\" : 2\n" + " }\n" + " }\n" + "}", "{ \"bar\" : { \"$set\" : { \"baz\" : { \"bazInt\" : 2 } } } }", "", asList(Mode.SET_ONLY, "/bar/baz", "/bar/baz/bazInt"), asList(Mode.PARENT_AND_SET, "/bar", "/bar/baz", "/bar/baz/bazInt"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt") }, { // must not call validator for parents and ancestors not modified
"{\n" + " \"fooInt\" : -1,\n" + " \"fooString\" : \"excludes\",\n" + " \"bar\" : {\n" + " \"barInt\" : -1,\n" + " \"barString\" : \"excludes\",\n" + " \"baz\" : {\n" + " \"bazInt\" : 2,\n" + " \"bazString\" : \"x\"\n" + " }\n" + " }\n" + "}", "{ \"bar\" : { \"$set\" : { \"baz\" : { \"bazInt\" : 2, \"bazString\" : \"x\" } } } }", "", asList(Mode.SET_ONLY, "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString"), asList(Mode.PARENT_AND_SET, "/bar", "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString") }, { // set /fooInt, /fooString (set multiple fields in root record)
"{ \"fooInt\" : 2, \"fooString\" : \"x\" }", "{ \"$set\" : { \"fooInt\" : 2, \"fooString\" : \"x\" } }", "", asList(Mode.SET_ONLY, "/fooInt", "/fooString"), asList(Mode.PARENT_AND_SET, "", "/fooInt", "/fooString"), asList(Mode.ANCESTOR_AND_SET, "", "/fooInt", "/fooString") }, { // set /bar/barInt, /bar/barString (set multiple fields in nested child record)
"{ \"bar\" : { \"barInt\" : 2, \"barString\" : \"x\" } }", "{ \"bar\" : { \"$set\" : { \"barInt\" : 2, \"barString\" : \"x\" } } }", "", asList(Mode.SET_ONLY, "/bar/barInt", "/bar/barString"), asList(Mode.PARENT_AND_SET, "/bar", "/bar/barInt", "/bar/barString"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/barInt", "/bar/barString") }, { // set /bar/baz/bazInt, /bar/baz/bazString (set multiple fields in nested grandchild record)
"{ \"bar\" : { \"baz\" : { \"bazInt\" : 2, \"bazString\" : \"x\" } } }", "{ \"bar\" : { \"baz\" : { \"$set\" : { \"bazInt\" : 2, \"bazString\" : \"x\" } } } }", "", asList(Mode.SET_ONLY, "/bar/baz/bazInt", "/bar/baz/bazString"), asList(Mode.PARENT_AND_SET, "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString") }, { // set /fooInt, /bar/barInt, /bar/baz/bazInt
"{\n" + " \"fooInt\" : 2,\n" + " \"bar\" : {\n" + " \"barInt\" : 2,\n" + " \"baz\" : {\n" + " \"bazInt\" : 2\n" + " }\n" + " }\n" + "}", "{\n" + " \"$set\" : { \"fooInt\" : 2 },\n" + " \"bar\" : {\n" + " \"$set\" : { \"barInt\" : 2 },\n" + " \"baz\" : {\n" + " \"$set\" : { \"bazInt\" : 2 }\n" + " }\n" + " }\n" + "}", "", asList(Mode.SET_ONLY, "/fooInt", "/bar/barInt", "/bar/baz/bazInt"), asList(Mode.PARENT_AND_SET, "", "/fooInt", "/bar", "/bar/barInt", "/bar/baz", "/bar/baz/bazInt"), asList(Mode.ANCESTOR_AND_SET, "", "/fooInt", "/bar", "/bar/barInt", "/bar/baz", "/bar/baz/bazInt") }, { // nothing set
"{\n" + " \"fooInt\" : -1,\n" + " \"fooString\" : \"excludes\",\n" + " \"bar\" : {\n" + " \"barInt\" : -1,\n" + " \"baz\" : {\n" + " \"bazInt\" : -1,\n" + " \"bazString\" : \"excludes\"\n" + " }\n" + " }\n" + "}", "{}", "", asList(Mode.SET_ONLY), asList(Mode.PARENT_AND_SET), asList(Mode.ANCESTOR_AND_SET) }, { // must not call next validator for /fooString, /bar/barInt
"{\n" + " \"fooInt\" : 2,\n" + " \"fooString\" : \"excludes\",\n" + " \"bar\" : {\n" + " \"barInt\" : -1,\n" + " \"baz\" : {\n" + " \"bazInt\" : 2,\n" + " \"bazString\" : \"x\"\n" + " }\n" + " }\n" + "}", "{\n" + " \"$set\" : { \"fooInt\" : 2 },\n" + " \"bar\" : {\n" + " \"$set\" : {\n" + " \"baz\" : { \"bazInt\" : 2, \"bazString\" : \"x\" }\n" + " }\n" + " }\n" + "}", "", asList(Mode.SET_ONLY, "/fooInt", "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString"), asList(Mode.PARENT_AND_SET, "", "/fooInt", "/bar", "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString"), asList(Mode.ANCESTOR_AND_SET, "", "/fooInt", "/bar", "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString") }, { // must not call next validator for /fooInt, /fooString, /bar/barInt
"{\n" + " \"fooInt\" : 2,\n" + " \"fooString\" : \"excludes\",\n" + " \"bar\" : {\n" + " \"barInt\" : -1,\n" + " \"baz\" : {\n" + " \"bazInt\" : 2,\n" + " \"bazString\" : \"x\"\n" + " }\n" + " }\n" + "}", "{\n" + " \"$set\" : {\n" + " \"baz\" : {\n" + " \"bazInt\" : 2,\n" + " \"bazString\" : \"x\"\n" + " }\n" + " }\n" + "}", "/bar", asList(Mode.SET_ONLY, "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString"), asList(Mode.PARENT_AND_SET, "/bar", "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString") }, { // must not call next validator for /fooInt, /fooString, /bar/barInt
"{\n" + " \"fooInt\" : 2,\n" + " \"fooString\" : \"excludes\",\n" + " \"bar\" : {\n" + " \"barInt\" : -1,\n" + " \"baz\" : {\n" + " \"bazInt\" : 2,\n" + " \"bazString\" : \"x\"\n" + " }\n" + " }\n" + "}", "{\n" + " \"baz\" : {\n" + " \"$set\" : {\n" + " \"bazInt\" : 2\n" + " }\n" + " }\n" + "}", "/bar", asList(Mode.SET_ONLY, "/bar/baz/bazInt"), asList(Mode.PARENT_AND_SET, "/bar/baz", "/bar/baz/bazInt"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt") }, { // must not call next validator for /fooInt, /fooString, /bar/barInt
"{\n" + " \"fooInt\" : 2,\n" + " \"fooString\" : \"excludes\",\n" + " \"bar\" : {\n" + " \"barInt\" : -1,\n" + " \"baz\" : {\n" + " \"bazInt\" : 2,\n" + " \"bazString\" : \"x\"\n" + " }\n" + " }\n" + "}", "{\n" + " \"$set\" : { \"bazInt\" : 2 }\n" + "}", "/bar/baz", asList(Mode.SET_ONLY, "/bar/baz/bazInt"), asList(Mode.PARENT_AND_SET, "/bar/baz", "/bar/baz/bazInt"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt") } };
DataSchema schema = dataSchemaFromString(schemaText);
ValidationOptions options = new ValidationOptions(RequiredMode.CAN_BE_ABSENT_IF_HAS_DEFAULT, CoercionMode.NORMAL);
for (Object[] row : inputs) {
String value = (String) row[0];
String patch = (String) row[1];
String patchPath = (String) row[2];
DataMap valueMap = dataMapFromString(value);
DataMap opMap = dataMapFromString(patch);
if (debug) {
out.println("Value: " + value);
out.println("Patch: " + patch);
if (patchPath.isEmpty() == false)
out.println("PatchPath: " + patchPath);
}
for (int i = 3; i < row.length; i++) {
VisitedValidator visitedValidator = new VisitedValidator();
@SuppressWarnings("unchecked") List<Object> check = (List<Object>) row[i];
Mode mode = (Mode) check.get(0);
Validator validator;
if (patchPath.isEmpty()) {
validator = new PatchFilterValidator(visitedValidator, opMap, mode);
} else {
DataElement patchElement = DataElementUtil.element(valueMap, schema, patchPath);
assertNotSame(patchElement, null);
validator = new PatchFilterValidator(visitedValidator, opMap, mode, patchElement);
}
ValidationResult result = ValidateDataAgainstSchema.validate(valueMap, schema, options, validator);
if (debug) {
out.println("Mode: " + mode);
out.print("Result: " + result);
out.println("VisitedPaths: " + visitedValidator._visitedPaths);
}
assertTrue(result.isValid());
for (int j = 1; j < check.size(); j++) {
assertTrue(visitedValidator._visitedPaths.contains(check.get(j)));
}
assertEquals(visitedValidator._visitedPaths.size(), check.size() - 1);
}
}
}
use of com.linkedin.data.element.DataElement in project rest.li by linkedin.
the class Transformer method transform.
/**
* Transforms the Data objects returned by the {@link DataIterator}.
* This method mutates the Data object and it's descendants.
*
* @param root provides the root of the Data objects that will be transformed.
* @param it provides the iterator of Data objects to be transformed.
* @param transform used to provide a replacement value.
* @return the transformed of root Data object if it was transformed, otherwise the input root with the transformations applied.
*/
public static Object transform(Object root, DataIterator it, Transform<Object, Object> transform) {
DataElement element;
// don't transform in place because iterator behavior with replacements (which behave like a remove and an add) while iterating is undefined
ArrayList<ToTransform> transformList = new ArrayList<>();
while ((element = it.next()) != null) {
transformList.add(new ToTransform(element));
}
for (ToTransform toTransform : transformList) {
if (toTransform.isRoot()) {
root = transform.apply(toTransform._value);
} else {
toTransform.transform(transform);
}
}
return root;
}
use of com.linkedin.data.element.DataElement in project rest.li by linkedin.
the class PathMatchesPatternPredicate method pass.
private boolean pass(DataElement element, int i) {
boolean pass = true;
DataElement currentElement = element;
for (; i < _matches.size(); ++i) {
Match match = _matches.get(i);
if (match.name == null) {
int d = 0;
while (d < match.minDistance) {
if (currentElement.getParent() == null) {
pass = false;
break;
}
currentElement = currentElement.getParent();
++d;
}
if (pass == false) {
break;
}
if (i == (_matches.size() - 1)) {
while (d < match.maxDistance && currentElement.getParent() != null) {
currentElement = currentElement.getParent();
++d;
}
} else {
Match nextMatch = _matches.get(i + 1);
int searchDistance = (match.maxDistance == Integer.MAX_VALUE ? Integer.MAX_VALUE : match.maxDistance - match.minDistance + 1);
boolean matched = false;
while (searchDistance > 0 && currentElement.getParent() != null) {
if (matchName(nextMatch, currentElement.getName())) {
boolean subPass = pass(currentElement.getParent(), i + 2);
if (subPass) {
matched = true;
i = _matches.size();
while (currentElement.getParent() != null) {
currentElement = currentElement.getParent();
}
break;
}
}
searchDistance--;
currentElement = currentElement.getParent();
}
if (matched == false) {
pass = false;
break;
}
break;
}
} else {
if (currentElement.getParent() == null || matchName(match, currentElement.getName()) == false) {
pass = false;
break;
}
currentElement = currentElement.getParent();
}
}
if (pass) {
assert (i == _matches.size());
pass = (currentElement.getParent() == null);
}
return pass;
}
Aggregations