@Test public void mindiff() { AnyObjectTO oldOne = new AnyObjectTO(); oldOne.setName("name"); oldOne.getPlainAttrs().add(new Attr.Builder("plain").value("oldValue").build()); oldOne.getPlainAttrs().add(new Attr.Builder("encrypted").value("oldValue").build()); AnyObjectTO newOne = new AnyObjectTO(); newOne.setName("name"); newOne.getPlainAttrs().add(new Attr.Builder("plain").value("newValue").build()); newOne.getPlainAttrs().add(new Attr.Builder("encrypted").value("oldValue").build()); AnyObjectUR diff = AnyOperations.diff(newOne, oldOne, true); assertEquals(1, diff.getPlainAttrs().size()); AttrPatch patch = diff.getPlainAttrs().iterator().next(); assertEquals(PatchOperation.ADD_REPLACE, patch.getOperation()); assertEquals("plain", patch.getAttr().getSchema()); }
private static void diff( final AnyTO updated, final AnyTO original, final AnyUR result, final boolean incremental) { if (updated.getKey() == null && original.getKey() != null || (updated.getKey() != null && !updated.getKey().equals(original.getKey()))) { throw new IllegalArgumentException("AnyTO's key must be the same"); } result.setKey(updated.getKey()); result.setRealm(replacePatchItem(updated.getRealm(), original.getRealm(), new StringReplacePatchItem())); result.getAuxClasses().clear(); if (!incremental) { original.getAuxClasses().stream().filter(auxClass -> !updated.getAuxClasses().contains(auxClass)). forEach(auxClass -> result.getAuxClasses().add(new StringPatchItem.Builder(). operation(PatchOperation.DELETE).value(auxClass).build())); } updated.getAuxClasses().stream().filter(auxClass -> !original.getAuxClasses().contains(auxClass)). forEach(auxClass -> result.getAuxClasses().add(new StringPatchItem.Builder(). operation(PatchOperation.ADD_REPLACE).value(auxClass).build())); Map<String, Attr> updatedAttrs = EntityTOUtils.buildAttrMap(updated.getPlainAttrs()); Map<String, Attr> originalAttrs = EntityTOUtils.buildAttrMap(original.getPlainAttrs()); result.getPlainAttrs().clear(); if (!incremental) { originalAttrs.keySet().stream(). filter(attr -> !updatedAttrs.containsKey(attr)).forEach( schema -> result.getPlainAttrs().add( new AttrPatch.Builder(new Attr.Builder(schema).build()). operation(PatchOperation.DELETE). build())); } updatedAttrs.values().forEach(attr -> { if (isEmpty(attr)) { if (!incremental) { result.getPlainAttrs().add( new AttrPatch.Builder(new Attr.Builder(attr.getSchema()).build()). operation(PatchOperation.DELETE). build()); } } else if (!originalAttrs.containsKey(attr.getSchema()) || !originalAttrs.get(attr.getSchema()).getValues().equals(attr.getValues())) { AttrPatch patch = new AttrPatch.Builder(attr).operation(PatchOperation.ADD_REPLACE).build(); if (!patch.isEmpty()) { result.getPlainAttrs().add(patch); } } }); result.getVirAttrs().clear(); result.getVirAttrs().addAll(updated.getVirAttrs()); result.getResources().clear(); if (!incremental) { original.getResources().stream().filter(resource -> !updated.getResources().contains(resource)). forEach(resource -> result.getResources().add(new StringPatchItem.Builder(). operation(PatchOperation.DELETE).value(resource).build())); } updated.getResources().stream().filter(resource -> !original.getResources().contains(resource)). forEach(resource -> result.getResources().add(new StringPatchItem.Builder(). operation(PatchOperation.ADD_REPLACE).value(resource).build())); }
AnyOperations { private static void diff( final AnyTO updated, final AnyTO original, final AnyUR result, final boolean incremental) { if (updated.getKey() == null && original.getKey() != null || (updated.getKey() != null && !updated.getKey().equals(original.getKey()))) { throw new IllegalArgumentException("AnyTO's key must be the same"); } result.setKey(updated.getKey()); result.setRealm(replacePatchItem(updated.getRealm(), original.getRealm(), new StringReplacePatchItem())); result.getAuxClasses().clear(); if (!incremental) { original.getAuxClasses().stream().filter(auxClass -> !updated.getAuxClasses().contains(auxClass)). forEach(auxClass -> result.getAuxClasses().add(new StringPatchItem.Builder(). operation(PatchOperation.DELETE).value(auxClass).build())); } updated.getAuxClasses().stream().filter(auxClass -> !original.getAuxClasses().contains(auxClass)). forEach(auxClass -> result.getAuxClasses().add(new StringPatchItem.Builder(). operation(PatchOperation.ADD_REPLACE).value(auxClass).build())); Map<String, Attr> updatedAttrs = EntityTOUtils.buildAttrMap(updated.getPlainAttrs()); Map<String, Attr> originalAttrs = EntityTOUtils.buildAttrMap(original.getPlainAttrs()); result.getPlainAttrs().clear(); if (!incremental) { originalAttrs.keySet().stream(). filter(attr -> !updatedAttrs.containsKey(attr)).forEach( schema -> result.getPlainAttrs().add( new AttrPatch.Builder(new Attr.Builder(schema).build()). operation(PatchOperation.DELETE). build())); } updatedAttrs.values().forEach(attr -> { if (isEmpty(attr)) { if (!incremental) { result.getPlainAttrs().add( new AttrPatch.Builder(new Attr.Builder(attr.getSchema()).build()). operation(PatchOperation.DELETE). build()); } } else if (!originalAttrs.containsKey(attr.getSchema()) || !originalAttrs.get(attr.getSchema()).getValues().equals(attr.getValues())) { AttrPatch patch = new AttrPatch.Builder(attr).operation(PatchOperation.ADD_REPLACE).build(); if (!patch.isEmpty()) { result.getPlainAttrs().add(patch); } } }); result.getVirAttrs().clear(); result.getVirAttrs().addAll(updated.getVirAttrs()); result.getResources().clear(); if (!incremental) { original.getResources().stream().filter(resource -> !updated.getResources().contains(resource)). forEach(resource -> result.getResources().add(new StringPatchItem.Builder(). operation(PatchOperation.DELETE).value(resource).build())); } updated.getResources().stream().filter(resource -> !original.getResources().contains(resource)). forEach(resource -> result.getResources().add(new StringPatchItem.Builder(). operation(PatchOperation.ADD_REPLACE).value(resource).build())); } }
AnyOperations { private static void diff( final AnyTO updated, final AnyTO original, final AnyUR result, final boolean incremental) { if (updated.getKey() == null && original.getKey() != null || (updated.getKey() != null && !updated.getKey().equals(original.getKey()))) { throw new IllegalArgumentException("AnyTO's key must be the same"); } result.setKey(updated.getKey()); result.setRealm(replacePatchItem(updated.getRealm(), original.getRealm(), new StringReplacePatchItem())); result.getAuxClasses().clear(); if (!incremental) { original.getAuxClasses().stream().filter(auxClass -> !updated.getAuxClasses().contains(auxClass)). forEach(auxClass -> result.getAuxClasses().add(new StringPatchItem.Builder(). operation(PatchOperation.DELETE).value(auxClass).build())); } updated.getAuxClasses().stream().filter(auxClass -> !original.getAuxClasses().contains(auxClass)). forEach(auxClass -> result.getAuxClasses().add(new StringPatchItem.Builder(). operation(PatchOperation.ADD_REPLACE).value(auxClass).build())); Map<String, Attr> updatedAttrs = EntityTOUtils.buildAttrMap(updated.getPlainAttrs()); Map<String, Attr> originalAttrs = EntityTOUtils.buildAttrMap(original.getPlainAttrs()); result.getPlainAttrs().clear(); if (!incremental) { originalAttrs.keySet().stream(). filter(attr -> !updatedAttrs.containsKey(attr)).forEach( schema -> result.getPlainAttrs().add( new AttrPatch.Builder(new Attr.Builder(schema).build()). operation(PatchOperation.DELETE). build())); } updatedAttrs.values().forEach(attr -> { if (isEmpty(attr)) { if (!incremental) { result.getPlainAttrs().add( new AttrPatch.Builder(new Attr.Builder(attr.getSchema()).build()). operation(PatchOperation.DELETE). build()); } } else if (!originalAttrs.containsKey(attr.getSchema()) || !originalAttrs.get(attr.getSchema()).getValues().equals(attr.getValues())) { AttrPatch patch = new AttrPatch.Builder(attr).operation(PatchOperation.ADD_REPLACE).build(); if (!patch.isEmpty()) { result.getPlainAttrs().add(patch); } } }); result.getVirAttrs().clear(); result.getVirAttrs().addAll(updated.getVirAttrs()); result.getResources().clear(); if (!incremental) { original.getResources().stream().filter(resource -> !updated.getResources().contains(resource)). forEach(resource -> result.getResources().add(new StringPatchItem.Builder(). operation(PatchOperation.DELETE).value(resource).build())); } updated.getResources().stream().filter(resource -> !original.getResources().contains(resource)). forEach(resource -> result.getResources().add(new StringPatchItem.Builder(). operation(PatchOperation.ADD_REPLACE).value(resource).build())); } private  AnyOperations(); }
AnyOperations { private static void diff( final AnyTO updated, final AnyTO original, final AnyUR result, final boolean incremental) { if (updated.getKey() == null && original.getKey() != null || (updated.getKey() != null && !updated.getKey().equals(original.getKey()))) { throw new IllegalArgumentException("AnyTO's key must be the same"); } result.setKey(updated.getKey()); result.setRealm(replacePatchItem(updated.getRealm(), original.getRealm(), new StringReplacePatchItem())); result.getAuxClasses().clear(); if (!incremental) { original.getAuxClasses().stream().filter(auxClass -> !updated.getAuxClasses().contains(auxClass)). forEach(auxClass -> result.getAuxClasses().add(new StringPatchItem.Builder(). operation(PatchOperation.DELETE).value(auxClass).build())); } updated.getAuxClasses().stream().filter(auxClass -> !original.getAuxClasses().contains(auxClass)). forEach(auxClass -> result.getAuxClasses().add(new StringPatchItem.Builder(). operation(PatchOperation.ADD_REPLACE).value(auxClass).build())); Map<String, Attr> updatedAttrs = EntityTOUtils.buildAttrMap(updated.getPlainAttrs()); Map<String, Attr> originalAttrs = EntityTOUtils.buildAttrMap(original.getPlainAttrs()); result.getPlainAttrs().clear(); if (!incremental) { originalAttrs.keySet().stream(). filter(attr -> !updatedAttrs.containsKey(attr)).forEach( schema -> result.getPlainAttrs().add( new AttrPatch.Builder(new Attr.Builder(schema).build()). operation(PatchOperation.DELETE). build())); } updatedAttrs.values().forEach(attr -> { if (isEmpty(attr)) { if (!incremental) { result.getPlainAttrs().add( new AttrPatch.Builder(new Attr.Builder(attr.getSchema()).build()). operation(PatchOperation.DELETE). build()); } } else if (!originalAttrs.containsKey(attr.getSchema()) || !originalAttrs.get(attr.getSchema()).getValues().equals(attr.getValues())) { AttrPatch patch = new AttrPatch.Builder(attr).operation(PatchOperation.ADD_REPLACE).build(); if (!patch.isEmpty()) { result.getPlainAttrs().add(patch); } } }); result.getVirAttrs().clear(); result.getVirAttrs().addAll(updated.getVirAttrs()); result.getResources().clear(); if (!incremental) { original.getResources().stream().filter(resource -> !updated.getResources().contains(resource)). forEach(resource -> result.getResources().add(new StringPatchItem.Builder(). operation(PatchOperation.DELETE).value(resource).build())); } updated.getResources().stream().filter(resource -> !original.getResources().contains(resource)). forEach(resource -> result.getResources().add(new StringPatchItem.Builder(). operation(PatchOperation.ADD_REPLACE).value(resource).build())); } private  AnyOperations(); static AnyObjectUR diff(
            final AnyObjectTO updated, final AnyObjectTO original, final boolean incremental); static UserUR diff(final UserTO updated, final UserTO original, final boolean incremental); static GroupUR diff(final GroupTO updated, final GroupTO original, final boolean incremental); @SuppressWarnings("unchecked") static P diff(
            final TO updated, final TO original, final boolean incremental); static AnyTO patch(final AnyTO anyTO, final AnyUR anyUR); static GroupTO patch(final GroupTO groupTO, final GroupUR groupUR); static AnyObjectTO patch(final AnyObjectTO anyObjectTO, final AnyObjectUR anyObjectUR); static UserTO patch(final UserTO userTO, final UserUR userUR); static void cleanEmptyAttrs(final AnyTO anyTO, final AnyUR anyUR); }
AnyOperations { private static void diff( final AnyTO updated, final AnyTO original, final AnyUR result, final boolean incremental) { if (updated.getKey() == null && original.getKey() != null || (updated.getKey() != null && !updated.getKey().equals(original.getKey()))) { throw new IllegalArgumentException("AnyTO's key must be the same"); } result.setKey(updated.getKey()); result.setRealm(replacePatchItem(updated.getRealm(), original.getRealm(), new StringReplacePatchItem())); result.getAuxClasses().clear(); if (!incremental) { original.getAuxClasses().stream().filter(auxClass -> !updated.getAuxClasses().contains(auxClass)). forEach(auxClass -> result.getAuxClasses().add(new StringPatchItem.Builder(). operation(PatchOperation.DELETE).value(auxClass).build())); } updated.getAuxClasses().stream().filter(auxClass -> !original.getAuxClasses().contains(auxClass)). forEach(auxClass -> result.getAuxClasses().add(new StringPatchItem.Builder(). operation(PatchOperation.ADD_REPLACE).value(auxClass).build())); Map<String, Attr> updatedAttrs = EntityTOUtils.buildAttrMap(updated.getPlainAttrs()); Map<String, Attr> originalAttrs = EntityTOUtils.buildAttrMap(original.getPlainAttrs()); result.getPlainAttrs().clear(); if (!incremental) { originalAttrs.keySet().stream(). filter(attr -> !updatedAttrs.containsKey(attr)).forEach( schema -> result.getPlainAttrs().add( new AttrPatch.Builder(new Attr.Builder(schema).build()). operation(PatchOperation.DELETE). build())); } updatedAttrs.values().forEach(attr -> { if (isEmpty(attr)) { if (!incremental) { result.getPlainAttrs().add( new AttrPatch.Builder(new Attr.Builder(attr.getSchema()).build()). operation(PatchOperation.DELETE). build()); } } else if (!originalAttrs.containsKey(attr.getSchema()) || !originalAttrs.get(attr.getSchema()).getValues().equals(attr.getValues())) { AttrPatch patch = new AttrPatch.Builder(attr).operation(PatchOperation.ADD_REPLACE).build(); if (!patch.isEmpty()) { result.getPlainAttrs().add(patch); } } }); result.getVirAttrs().clear(); result.getVirAttrs().addAll(updated.getVirAttrs()); result.getResources().clear(); if (!incremental) { original.getResources().stream().filter(resource -> !updated.getResources().contains(resource)). forEach(resource -> result.getResources().add(new StringPatchItem.Builder(). operation(PatchOperation.DELETE).value(resource).build())); } updated.getResources().stream().filter(resource -> !original.getResources().contains(resource)). forEach(resource -> result.getResources().add(new StringPatchItem.Builder(). operation(PatchOperation.ADD_REPLACE).value(resource).build())); } private  AnyOperations(); static AnyObjectUR diff(
            final AnyObjectTO updated, final AnyObjectTO original, final boolean incremental); static UserUR diff(final UserTO updated, final UserTO original, final boolean incremental); static GroupUR diff(final GroupTO updated, final GroupTO original, final boolean incremental); @SuppressWarnings("unchecked") static P diff(
            final TO updated, final TO original, final boolean incremental); static AnyTO patch(final AnyTO anyTO, final AnyUR anyUR); static GroupTO patch(final GroupTO groupTO, final GroupUR groupUR); static AnyObjectTO patch(final AnyObjectTO anyObjectTO, final AnyObjectUR anyObjectUR); static UserTO patch(final UserTO userTO, final UserUR userUR); static void cleanEmptyAttrs(final AnyTO anyTO, final AnyUR anyUR);  }