/* * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.evolveum.midpoint.schema; import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.Item; import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismProperty; import com.evolveum.midpoint.prism.PrismPropertyDefinition; import com.evolveum.midpoint.prism.PrismPropertyDefinitionImpl; import com.evolveum.midpoint.prism.delta.ChangeType; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.schema.constants.MidPointConstants; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.PrettyPrinter; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; import com.evolveum.midpoint.xml.ns._public.common.common_3.FailedOperationTypeType; import com.evolveum.midpoint.xml.ns._public.common.common_3.MetadataType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; import org.testng.annotations.BeforeSuite; import org.testng.annotations.Test; import org.xml.sax.SAXException; import java.io.IOException; import java.util.Date; import javax.xml.namespace.QName; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.assertNull; import static org.testng.AssertJUnit.assertTrue; /** * @author lazyman */ public class TestDiffEquals { private static final String NS_TEST_RI = "http://midpoint.evolveum.com/xml/ns/test/ri-1"; @BeforeSuite public void setup() throws SchemaException, SAXException, IOException { PrettyPrinter.setDefaultNamespacePrefix(MidPointConstants.NS_MIDPOINT_PUBLIC_PREFIX); PrismTestUtil.resetPrismContext(MidPointPrismContextFactory.FACTORY); } @Test public void testUserSimplePropertyDiff() throws SchemaException { System.out.println("\n\n===[ testUserSimplePropertyDiff ]===\n"); UserType userType1 = new UserType(); userType1.setName(PrismTestUtil.createPolyStringType("test name")); UserType userType2 = new UserType(); userType2.setName(PrismTestUtil.createPolyStringType("test name")); PrismTestUtil.getPrismContext().adopt(userType1); PrismTestUtil.getPrismContext().adopt(userType2); ObjectDelta delta = userType1.asPrismObject().diff(userType2.asPrismObject()); assertNotNull(delta); assertEquals(0, delta.getModifications().size()); userType2.setDescription(null); delta = userType1.asPrismObject().diff(userType2.asPrismObject()); assertNotNull(delta); assertEquals("Delta should be empty, nothing changed.", 0, delta.getModifications().size()); } @Test public void testUserListSimpleDiff() throws SchemaException { System.out.println("\n\n===[ testUserListSimpleDiff ]===\n"); UserType u1 = new UserType(); u1.setName(PrismTestUtil.createPolyStringType("test name")); UserType u2 = new UserType(); u2.setName(PrismTestUtil.createPolyStringType("test name")); PrismTestUtil.getPrismContext().adopt(u1); PrismTestUtil.getPrismContext().adopt(u2); ObjectDelta delta = u1.asPrismObject().diff(u2.asPrismObject()); assertNotNull(delta); assertEquals(0, delta.getModifications().size()); u2.getAdditionalName(); delta = u1.asPrismObject().diff(u2.asPrismObject()); assertNotNull(delta); assertEquals("Delta should be empty, nothing changed.", 0, delta.getModifications().size()); } @Test public void testAssignmentEquals() throws Exception { System.out.println("\n\n===[ testAssignmentEquals ]===\n"); PrismContext prismContext = PrismTestUtil.getPrismContext(); AssignmentType a1a = new AssignmentType(); prismContext.adopt(a1a); a1a.setDescription("descr1"); AssignmentType a2 = new AssignmentType(); prismContext.adopt(a2); a2.setDescription("descr2"); AssignmentType a1b = new AssignmentType(); prismContext.adopt(a1b); a1b.setDescription("descr1"); AssignmentType a1m = new AssignmentType(); prismContext.adopt(a1m); a1m.setDescription("descr1"); MetadataType metadata1m = new MetadataType(); metadata1m.setCreateTimestamp(XmlTypeConverter.createXMLGregorianCalendar(System.currentTimeMillis())); a1m.setMetadata(metadata1m); AssignmentType a1e = new AssignmentType(); prismContext.adopt(a1e); a1e.setDescription("descr1"); ActivationType activation1e = new ActivationType(); activation1e.setEffectiveStatus(ActivationStatusType.ENABLED); a1e.setActivation(activation1e); // WHEN assertFalse(a1a.equals(a2)); assertFalse(a1b.equals(a2)); assertFalse(a1m.equals(a2)); assertFalse(a1e.equals(a2)); assertFalse(a2.equals(a1a)); assertFalse(a2.equals(a1b)); assertFalse(a2.equals(a1m)); assertFalse(a2.equals(a1e)); assertTrue(a1a.equals(a1a)); assertTrue(a1b.equals(a1b)); assertTrue(a1m.equals(a1m)); assertTrue(a1e.equals(a1e)); assertTrue(a2.equals(a2)); assertTrue(a1a.equals(a1b)); assertTrue(a1b.equals(a1a)); assertTrue(a1a.equals(a1m)); assertTrue(a1b.equals(a1m)); assertTrue(a1m.equals(a1a)); assertTrue(a1m.equals(a1b)); assertTrue(a1m.equals(a1e)); assertTrue(a1a.equals(a1e)); assertTrue(a1b.equals(a1e)); assertTrue(a1e.equals(a1a)); assertTrue(a1e.equals(a1b)); assertTrue(a1e.equals(a1m)); } @Test public void testAssignmentEquivalent() throws Exception { System.out.println("\n\n===[ testAssignmentEquivalent ]===\n"); PrismContext prismContext = PrismTestUtil.getPrismContext(); AssignmentType a1 = new AssignmentType(prismContext); ActivationType a1a = new ActivationType(prismContext); a1a.setValidFrom(XmlTypeConverter.createXMLGregorianCalendar(new Date())); a1a.setEffectiveStatus(ActivationStatusType.ENABLED); a1.setActivation(a1a); AssignmentType a2 = new AssignmentType(prismContext); ActivationType a2a = new ActivationType(prismContext); a2a.setEffectiveStatus(ActivationStatusType.ENABLED); a2.setActivation(a2a); // WHEN assertFalse(a1.equals(a2)); assertFalse(a1.asPrismContainerValue().equivalent(a2.asPrismContainerValue())); // a bit redundant assertFalse(a2.equals(a1)); assertFalse(a2.asPrismContainerValue().equivalent(a1.asPrismContainerValue())); // a bit redundant } @Test public void testContextlessAssignmentEquals() throws Exception { System.out.println("\n\n===[ testContextlessAssignmentEquals ]===\n"); AssignmentType a1 = new AssignmentType(); // no prismContext here a1.setDescription("descr1"); AssignmentType a2 = new AssignmentType(); // no prismContext here a2.setDescription("descr2"); AssignmentType a3 = new AssignmentType(); // no prismContext here a3.setDescription("descr1"); assertFalse(a1.equals(a2)); // this should work even without prismContext assertTrue(a1.equals(a3)); // this should work even without prismContext PrismContext prismContext = PrismTestUtil.getPrismContext(); prismContext.adopt(a1); prismContext.adopt(a2); prismContext.adopt(a3); assertFalse(a1.equals(a2)); // this should work as well assertTrue(a1.equals(a3)); } @Test public void testContextlessAssignmentEquals2() throws Exception { System.out.println("\n\n===[ testContextlessAssignmentEquals2 ]===\n"); // (1) user without prismContext - the functionality is reduced UserType user = new UserType(); AssignmentType a1 = new AssignmentType(); // no prismContext here a1.setDescription("descr1"); user.getAssignment().add(a1); AssignmentType a2 = new AssignmentType(); // no prismContext here a2.setDescription("descr2"); user.getAssignment().add(a2); AssignmentType a2identical = new AssignmentType(); a2identical.setDescription("descr2"); assertTrue(user.getAssignment().contains(a2identical)); ObjectDelta delta1 = user.asPrismObject().createDelta(ChangeType.DELETE); // delta1 is without prismContext assertNull(delta1.getPrismContext()); // (2) user with prismContext UserType userWithContext = new UserType(PrismTestUtil.getPrismContext()); AssignmentType b1 = new AssignmentType(); // no prismContext here b1.setDescription("descr1"); userWithContext.getAssignment().add(b1); AssignmentType b2 = new AssignmentType(); // no prismContext here b2.setDescription("descr2"); userWithContext.getAssignment().add(b2); AssignmentType b2identical = new AssignmentType(); b2identical.setDescription("descr2"); assertTrue(user.getAssignment().contains(b2identical)); // b1 and b2 obtain context when they are added to the container assertNotNull(b1.asPrismContainerValue().getPrismContext()); assertNotNull(b2.asPrismContainerValue().getPrismContext()); assertFalse(b1.equals(b2)); ObjectDelta delta2 = userWithContext.asPrismObject().createDelta(ChangeType.DELETE); assertNotNull(delta2.getPrismContext()); } @Test public void testDiffShadow() throws Exception { System.out.println("\n\n===[ testDiffShadow ]===\n"); PrismContext prismContext = PrismTestUtil.getPrismContext(); PrismObject<ShadowType> shadow1 = prismContext.getSchemaRegistry() .findObjectDefinitionByCompileTimeClass(ShadowType.class).instantiate(); ShadowType shadow1Type = shadow1.asObjectable(); shadow1Type.setName(new PolyStringType("Whatever")); shadow1Type.setFailedOperationType(FailedOperationTypeType.ADD); shadow1Type.getAuxiliaryObjectClass().add(new QName(NS_TEST_RI, "foo")); PrismContainer<Containerable> shadow1Attrs = shadow1.findOrCreateContainer(ShadowType.F_ATTRIBUTES); ShadowType shadow2Type = new ShadowType(); PrismObject<ShadowType> shadow2 = shadow2Type.asPrismObject(); prismContext.adopt(shadow2Type); shadow2Type.setName(new PolyStringType("Whatever")); shadow2Type.getAuxiliaryObjectClass().add(new QName(NS_TEST_RI, "foo")); shadow2Type.getAuxiliaryObjectClass().add(new QName(NS_TEST_RI, "bar")); PrismContainer<Containerable> shadow2Attrs = shadow2.findOrCreateContainer(ShadowType.F_ATTRIBUTES); PrismProperty<String> attrEntryUuid = new PrismProperty<>(new QName(NS_TEST_RI, "entryUuid"), prismContext); PrismPropertyDefinition<String> attrEntryUuidDef = new PrismPropertyDefinitionImpl<>(new QName(NS_TEST_RI, "entryUuid"), DOMUtil.XSD_STRING, prismContext); attrEntryUuid.setDefinition(attrEntryUuidDef); shadow2Attrs.add(attrEntryUuid); attrEntryUuid.addRealValue("1234-5678-8765-4321"); PrismProperty<String> attrDn = new PrismProperty<>(new QName(NS_TEST_RI, "dn"), prismContext); PrismPropertyDefinition<String> attrDnDef = new PrismPropertyDefinitionImpl<>(new QName(NS_TEST_RI, "dn"), DOMUtil.XSD_STRING, prismContext); attrDn.setDefinition(attrDnDef); shadow2Attrs.add(attrDn); attrDn.addRealValue("uid=foo,o=bar"); System.out.println("Shadow 1"); System.out.println(shadow1.debugDump(1)); System.out.println("Shadow 2"); System.out.println(shadow2.debugDump(1)); // WHEN ObjectDelta<ShadowType> delta = shadow1.diff(shadow2); // THEN assertNotNull("No delta", delta); System.out.println("Delta"); System.out.println(delta.debugDump(1)); PrismAsserts.assertIsModify(delta); PrismAsserts.assertPropertyDelete(delta, ShadowType.F_FAILED_OPERATION_TYPE, FailedOperationTypeType.ADD); PrismAsserts.assertPropertyAdd(delta, ShadowType.F_AUXILIARY_OBJECT_CLASS, new QName(NS_TEST_RI, "bar")); PrismAsserts.assertContainerAdd(delta, ShadowType.F_ATTRIBUTES, shadow2Attrs.getValue().clone()); PrismAsserts.assertModifications(delta, 3); } }